-
图像的掩模(Mask)
以RGB图像为例:RGB图像它分别用红(R)、绿(G)、蓝(B)三原色的组合来表示每个像素的颜色。RGB图像每一个像素的颜色值(由RGB三原色表示)直接存放在图像矩阵中,由于每一像素的颜色需由R、G、B三个分量来表示,M、N分别表示图像的行列数,三个M x N的二维矩阵分别表示各个像素的R、G、B三个颜色分量。RGB图像的数据类型一般为8位无符号整形,通常用于表示和存放真彩色图像,当然也可以存放灰度图像。我们平常是以图像分辨率(即像素点)和颜色数来描述数字图象的。例如一张分辨率为640480,16位色的数字图片,就由2^16=65536种颜色的307200(=640480)个素点组成。
图像的掩模操作即是指用选定的图像、图形或物体、对待处理的图像(全部或局部)进行遮挡来控制图像处理的区域或处理过程。对所操作的图像的每一点的像素值进行重新计算。
数字图像处理中,图像掩模主要用于:
①提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
②屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
③结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。④特殊形状图像的制作。 -
图像掩模操作需要用到的内容
①要想对图像矩阵进行操作就必须要能够操作每一点的像素,因此需要获得像素指针
Mat.prt(row)获取图像像素的指针,row代表行数,从0开始。
获取当前行指针:const uchar* current = image.prt(row);
获取当前像素点P(row,col)= current [col]
②像素范围处理函数(功能是确保RGB值得范围在0-255)
saturate_case
③通过掩模操作实现图像对比度调整公式为:
P(i,j)=5*P(i,j)-P(i-1,j)-P(i+1,j)-P(i,j-1)-P(i,j+1)
即重新计算每个像素点的像素值 -
程序源码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src;
src = imread("C:/Users/he104/Desktop/timg.jpg");
if (!src.data)
{
printf("could not load timg.jpg....");
return -1;
}
namedWindow("test",WINDOW_AUTOSIZE);
imshow("test",src);
CV_Assert(src.depth() == CV_8U);
Mat dst;
src.copyTo(dst);
int rows = src.rows; //获取图像的行数
int cols = (src.cols-1)*src.channels(); //获取图像的总通道数,因为对于一个矩阵来说其边界部分无法进行完整的变换,因而去掉边界部分,因而有(src.cols-1)以及下面的(rows-1)
for (int row = 1; row < (rows - 1); row++)
{
//原图像的指针
const uchar* ago = src.ptr<uchar>(row - 1);
const uchar* current = src.ptr<uchar>(row );
const uchar* future = src.ptr<uchar>(row + 1);
//变换后图像的指针
uchar* Imshow = dst.ptr<uchar>(row);
for (int col = src.channels(); col < cols; col++)
{
//进行计算变换
Imshow[col] = saturate_cast<uchar>(5 * current[col] - current[col - src.channels()] - current[col + src.channels()] - ago[col] - future[col]);
}
}
namedWindow("mask",CV_WINDOW_AUTOSIZE);
imshow("mask", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
- 显示效果
- 我们还可以通过函数调用filter2D功能来进行同样的操作,来改变对比度
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src;
src = imread("C:/Users/he104/Desktop/timg.jpg");
if (!src.data)
{
printf("could not load timg.jpg....");
return -1;
}
namedWindow("test",WINDOW_AUTOSIZE);
imshow("test",src);
Mat dst;
src.copyTo(dst);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);
namedWindow("mask",CV_WINDOW_AUTOSIZE);
imshow("mask", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
Mat kernel = (Mat_(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);为定义掩模的语句,我们通过公式计算一个矩阵得到一组数据,来定义掩模。
src.depth()表示位图深度,有32,24,8等,如果不了解的话可以直接将其赋值为-1。
经过测试可以得到与上面相同的图像处理结果。