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;