1. 掩模
矩阵掩模,根据掩模重新计算每个像素的像素值,掩模(mask),也称作Kernel,通过掩模可以实现图像对比度提高;
上图代表的是3*3矩阵,三通道;
以下程序解读,用到C++指针操作,在这方面还是薄弱,需要学习指针方面知识;
Mat.ptr<uchar>(i,j)//代表第i行,第j个点的值(j的大小包含通道数),这是一个地址 i = Mat.rols(); j = Mat.cols()*Mat.channels(); ucahr//代表这个容器存储的类型,和C++的Vector<int> test;一样的 Mat.ptr<uchar>(i) //获取像素矩阵的指针,索引i表示第几行,从0开始计行数。这是一个指针 const uchar* current= myImage.ptr<uchar>(row);//获得当前行指针 p(row,col) =current[col]//获取当前像素点P(row, col)的像素值 这是一个值
下面程序包括自己根据上述公式写的掩模算法以及Opencv API 并进行测试;
using namespace std; using namespace cv; void Mask(const Mat& src, Mat& dst); void main() { const Mat sourse = imread("E:\欣奕华\项目\OPENCV\Kernel\1.jpg", 1); namedWindow("原图", 1); imshow("原图", sourse); Mat dst; Mask(sourse, dst); namedWindow("掩模", 1); imshow("掩模", dst); Mat kernel = (Mat_<double>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); Mat output_image; double tick = static_cast<double>(getTickCount()); filter2D(sourse, output_image, sourse.depth(), kernel); tick = (static_cast<double>(getTickCount()) - tick) / getTickFrequency(); cout << tick; namedWindow("Mask image"); imshow("Mask image", output_image); waitKey(); } void Mask(const Mat& src, Mat& dst) { double tick = static_cast<double>(getTickCount()); dst.create(src.size(), src.type()); const int nChannels = src.channels(); for (int i = 1; i < src.rows - 1; i++) { const uchar* previous = src.ptr<uchar>(i-1); const uchar* currents = src.ptr<uchar>(i); const uchar* nexts = src.ptr<uchar>(i + 1); uchar* output = dst.ptr<uchar>(i); //目标操作图像 for (int j = nChannels; j < src.cols*nChannels-1; j++) //这个不是很好理解哈 { *output++ = saturate_cast<uchar>(5 * currents[j] - currents[j - nChannels] - currents[j + nChannels] - previous[j] - nexts[j]); } } tick = (static_cast<double>(getTickCount()) - tick)/getTickFrequency(); cout << tick; }
通过对比自定义掩模算法,相比于API较快:
对比度对比: