1.掩膜概念
掩膜是一种图像滤镜的模板,实用掩膜经常处理的是遥感图像。当提取道路或者河流,或者房屋时,通过一个n*n的矩阵来对图像进行像素过滤,然后将我们需要的地物或者标志突出显示出来。这个矩阵就是一种掩膜。即掩膜用来提升图像的对比度。
2.矩阵实质概念
掩膜操作实现图像对比度调整:红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象。I(i,j)为一点像素值。具体如下:
3.获取图像像素指针
-
Mat.ptr<uchar>(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
-
获得当前行指针const uchar* current= myImage.ptr<uchar>(row );
-
获取当前像素点P(row, col)的像素值 p(row, col) =current[col]
-
像素范围处理saturate_cast<uchar>,saturate_cast<uchar>(-100),返回 0;saturate_cast<uchar>(288),返回255;saturate_cast<uchar>(100),返回100。这个函数的功能是确保RGB值得范围在0~255之间。
4.代码实现
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
//矩阵掩膜操作原理样例
int main() {
Mat src, dest;
src = imread("D:/demo.jpg");
if (!src.data) {
cout << "文件打开失败" << endl;
return -1;
}
namedWindow("掩膜操作前", WINDOW_AUTOSIZE);
imshow("掩膜操作前", src);
dest = Mat::zeros(src.size(), src.type());//生成一个和源图像大小相等类型相同的全0矩阵
int cols = (src.cols - 1)*src.channels();//获取图像的列数,一定不要忘记图像的通道数
int rows = src.rows;//获取图像的行数
int offsetx = src.channels();
cout << offsetx << endl;
for (int row = 1; row < rows - 1; row++) {
uchar* previous = src.ptr<uchar>(row - 1);//获取前一行指针
uchar* current = src.ptr<uchar>(row);//获取当行前指针
uchar* next = src.ptr<uchar>(row + 1);//获取后一行指针
uchar* output = dest.ptr<uchar>(row);//获取输出图像当前行指针
for (int col = offsetx; col < cols; col++) {
output[col] = saturate_cast<uchar>(5 * current[col] - (previous[col] + next[col] + current[col - 1] + current[col + 1]));
}
}
namedWindow("掩膜操作后", WINDOW_AUTOSIZE);
imshow("掩膜操作后", dest);
cvWaitKey(10000);
return 0;
}
5.使用filter2D()API实现掩膜操作
代码如下:
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
//掩膜操作调用API操作
int main()
{
Mat src, dest;
src = imread("D:/demo.jpg");
if (src.empty()) {
cout << "文件打开失败" << endl;
return -1;
}
namedWindow("掩膜操作前", WINDOW_AUTOSIZE);
imshow("掩膜操作前", src);
dest = Mat::zeros(src.size(), src.type());//生成一个和源图像大小相等类型相同的全0矩阵
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//定义掩膜
double t = getTickCount();//获取时间
filter2D(src, dest, src.depth(), kernel);//API
double timeconsume = (getTickCount() - t) / getTickFrequency();//计算耗时(查看程序运行效率使用)
cout << timeconsume << endl;
namedWindow("掩膜操作后", CV_WINDOW_AUTOSIZE);
imshow("掩膜操作后", dest);
cvWaitKey(0);
return 0;
}
计算耗时可以使用getTickCount()与getTickFreqency()搭配使用。详细使用见:https://blog.csdn.net/sinat_36264666/article/details/77058
运行结果对比如下: