所谓的掩膜操作,是用来提高图像的对比度。掩膜操作有一个简单的公式:
在进行掩膜操作之前,必须需要了解下面几个opencv的函数:
(1)int Mat对象.channels();//获取图像的通道数,不同类型的图像通道数不一样,以BGR为例,一张图按行按列均匀分布着像素点,但是每个像素点由三种颜色组成(灰度图只有一种颜色),相当于三个按行排列的通道,所以在处理图片像素时,往往列数要乘以通道数。
(2)uchar* Mat对象.ptr<uchar>(int row);//获取图像的行指针,相当于把图片的行像素看成一行数组。
(3)Mat Mat对象.zeros(Mat对象.size(),Mat对象.type());//用来生成一个相同规格的图像对象,内容为0。
(4)int saturate_cast<uchar>(int num);//相当于一个判断,如果num大于255,返回255,如果num小于0,返回0,如果num在0到255范围内,返回num,从而保证像素值正常,没有这个判断,掩膜处理后图像很可能会出现不正常显示。
除了自己手写掩膜外,也可以用filter2D函数来实现掩膜操作。
代码如下:
#include<opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat scr, dst;
scr = imread("2.jpg", 1);
imshow("原图", scr);
if (!scr.data)
{
return -1;
}
dst = scr.zeros(scr.size(), scr.type());
int offset = scr.channels();//图像通道数
int rows = scr.rows, cols = scr.cols*offset;//列一定要乘以通道数
for (int r = 1; r < rows-1; r++)
{
uchar* last = scr.ptr<uchar>(r - 1);//获取行指针
uchar* now = scr.ptr<uchar>(r);
uchar* next = scr.ptr<uchar>(r + 1);
uchar* dst_now = dst.ptr<uchar>(r);
for (int c = offset; c < cols - offset; c++)
dst_now[c] = saturate_cast<uchar>(5 * now[c] - (now[c - offset] + now[c + offset] + last[c] + next[c]));
}
/*Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(scr, dst, scr.depth(), kernel);*/
imshow("处理后", dst);
waitKey();
return 0;
}
效果如下:
处理前
处理后