OpenCV 对图像进行掩码操作

掩码操作是根据核来重新计算每个像素点的值,也就是对该像素点根据周围的像素点做一个加权平均。
就以增强图片对比对来展示吧,使用的是下面的这个公式:
OpenCV 对图像进行掩码操作_第1张图片
利用指针,通过函数实现:

void Sharpen(const Mat& myImage, Mat& Result)
{
    CV_Assert(myImage.depth() == CV_8U);  // 仅接受uchar图像

    Result.create(myImage.size(), myImage.type());
    const int nChannels = myImage.channels();

    for (int j = 1; j < myImage.rows - 1; ++j)
    {
        const uchar* previous = myImage.ptr<uchar>(j - 1);
        const uchar* current = myImage.ptr<uchar>(j);
        const uchar* next = myImage.ptr<uchar>(j + 1);

        uchar* output = Result.ptr<uchar>(j);

        for (int i = nChannels; i < nChannels*(myImage.cols - 1); ++i)
        {
            *output++ = saturate_cast<uchar>(5 * current[i]
                - current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
        }
    }

    Result.row(0).setTo(Scalar(0));                    //由于图片的最上下左右的那一行没有进行计算所以值全设为0
    Result.row(Result.rows - 1).setTo(Scalar(0));
    Result.col(0).setTo(Scalar(0));
    Result.col(Result.cols - 1).setTo(Scalar(0));
}

效果图:
OpenCV 对图像进行掩码操作_第2张图片

除了自己写代码实现,在OpenCv中还可以使用filter2D函数来实现,通过自定义一个内核来对图像处理
函数的定义如下:

void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor = Point(-1,-1),
                            double delta = 0, int borderType = BORDER_DEFAULT );

前两个参数为输入和输出图
第三个参数为图像的类型
第四个为要输入的内核
第五个为模板的中心点
第五个为补充图像的值
第六个是边界类型
一般用不到修改后三个

先定义一个内核,和上面的一样

Mat kern = (Mat_<char>(3, 3) << 0, -1, 0,
        -1, 5, -1,         0, -1, 0);

然后传入函数使用就行了
附上代码:

int main()
{
    Mat a = imread("6391b38fa0ec08fabe2ea0b55fee3d6d55fbda0d.jpg");
    Mat b;
    Mat kern = (Mat_<char>(3, 3) << 0, -1, 0,
        -1, 5, -1,
        0, -1, 0);
    filter2D(a, b, CV_8U, kern);
    imshow("原图", a);
    imshow("计算得到的图", b);
    waitKey(100000);
}

你可能感兴趣的:(图片,opencv)