opencv图像处理02-图像矩阵掩模操作

1. 矩阵掩模原理:

矩阵掩模算法feic非常简单,例如将一个3X3的矩阵,一张图像,对图像的每个像素点进行如下操作:

1.分别从左到右,从上到下,每个通道,拿3X3矩阵和原图对应位置做内积,最后得到的值在赋值给zhon中心像素点

简单例子:

通过如下3X3矩阵来做掩模,可以提高图像的对比度

如上图所示,红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象。

2.代码实现:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;
int main()
{
    Mat src = imread("E:/4.png");
    Mat dst;
    if (!src.data) {
        cout << "can not load" << endl;
    }
    else {
        cout << "successful" << endl;
    }

    cout << src.cols << endl;
    cout << src.rows << endl;
    cout << src.channels() << endl;

    namedWindow("test1", CV_WINDOW_AUTOSIZE);
    imshow("test1",src);

    //每一列必须乘以通道数,因为有可能为彩色图像,列数为灰度的三倍
    //由于最外围的一圈像素点没办法进行图像掩模,所以减1
    int cols = (src.cols - 1) * src.channels();
    //行为图像的行
    int rows = src.rows;
    int offsetx = src.channels();

    dst = Mat::zeros(src.size(), src.type());
    //row从1开始,rows-1结束,表示不要对最外围的像素点掩模
    for (int row = 1; row < (rows - 1); row++) {
        //通过像素指针,拿到行指针
        const uchar* previous = src.ptr<uchar>(row - 1);
        const uchar* current = src.ptr<uchar>(row);
        const uchar* next = src.ptr<uchar>(row + 1);
        uchar* output = dst.ptr<uchar>(row);
        //col从3开始,因为彩色图像会有三个通道,最外围的像素点不掩模
        //每一个像素有BGR三个通道
        //分别对每个像素的BGR都要分别进行掩模操作
        for (int col = offsetx; col < cols; col++) {
            output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));
        }
    }

/*
    double t = getTickCount();
    Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    filter2D(src, dst, src.depth(), kernel);
    double time = (getTickCount() - t) / getTickFrequency();
    cout << "use time " << time << endl;
*/
    namedWindow("test2", CV_WINDOW_AUTOSIZE);
    imshow("test2", dst);


    waitKey(0);

}

3.使用filter2D来实现只需要几行代码就可以搞定上面所有操作

    double t = getTickCount();
    Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    filter2D(src, dst, src.depth(), kernel);
    double time = (getTickCount() - t) / getTickFrequency();
    cout << "use time " << time << endl;

猜你喜欢

转载自blog.csdn.net/qinchao315/article/details/81262241