矩阵的掩膜操作主要有以下用途:
1、提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
2、屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
3、结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
4、特殊形状图像的制作。
因此掩膜操作可以实现图像对比度的调整,使得图像可以锐化,提高图像对比度。
获取图像后,要对单个像素点进行操作,就要先获取图像像素指针。
Mat.ptr(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
获得当前行指针const uchar* current= myImage.ptr(row );
获取当前像素点P(row, col)的像素值 p(row, col) =current[col]
像素范围处理saturate_cast
saturate_cast(-100),返回 0。
saturate_cast(288),返回255
saturate_cast(100),返回100
这个函数的功能是确保RGB值得范围在0~255之间
掩膜操作实现图像对比度调整
-红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象。
公式为:I(i,j)=5*I(i,j)-[I(i-1,j)+I(i+1,j)+I(i,j-1)+I(i,j+1)]
实际上是一个矩阵
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
Mat src, dest;
src = imread("E:/03OpenCV/PIC/test1.jpg");
if (!src.data)
{ cout << "文件打开失败" << endl; return -1;}
cv::namedWindow("original image",WINDOW_AUTOSIZE);
cv::imshow("original image", src);
int cols = (src.cols - 1)*src.channels();//获取像素的列,三通道
int offsetx = src.channels();//有几个通道
int rows = src.rows;//image row
dest = Mat::zeros(src.size(), src.type());//set the default color into black 是从矩阵的(1,1)开始的所以行列应该写好
for (int row = 1; row < (rows - 1); row++)
{
const uchar*current = src.ptr<uchar>(row);//get the current row;
const uchar*previous = src.ptr<uchar>(row - 1);//the previous row
const uchar*next = src.ptr<uchar>(row + 1);//the next row;
uchar*output = dest.ptr<uchar>(row);
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]));//use mask kernel to recaculate xiangsu value,then enhance picture contrast
}
}
imwrite("E:/03OpenCV/PIC/finshtest1.jpg", dest);//保存处理后的图片
cv::namedWindow("image after", 1);
cv::imshow("image after", dest);
waitKey(0);
destroyAllWindows();
return 0;
}
使用函数saturate_cast(像素值)
这个函数的作用就是确保RGB的值在0~255之间。
saturate_cast(-100)返回0;
saturate_cast(100)返回100;
saturate_cast(280)返回255
使用OpenCV自带函数filter2D来实现掩膜操作:
void MaskOpera2(void)
{
Mat src, dest;
src = imread("E:/03OpenCV/PIC/test1.jpg");
if (!src.data) {cout << "文件打开失败" << endl; return;}
cv::namedWindow("original image", 1);
cv::imshow("original image", src);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//定义掩膜
filter2D(src, dest, src.depth(), kernel);//调用filter2D
cv::namedWindow("image after", 1);
cv::imshow("image after", dest);
}