OpenCV笔记2-矩阵的掩膜操作

1、矩阵的掩膜操作

  • 含义:根据掩膜来重新计算每个像素的像素值,掩膜(Mask也称kernel)
  • 功能:可以通过掩膜来提高图像对比度
  • 公式:
    I ( i , j ) = 5 I ( i , j ) [ I ( i 1 , j ) + I ( i + 1 , j ) + I ( i , j 1 ) + I ( i , j + 1 ) ] I(i, j) = 5 * I(i ,j) - [I(i - 1, j) + I(i + 1, j) + I(i, j - 1) + I(i, j + 1)]
  • 红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象

2、获取图像像素指针

  • cv_Assert(myImage.depth() == CV_8U);
  • Mat.ptr < uchar >(int i = 0)获取像素矩阵的指针,索引i表示第几行,从0开始计行数
  • 获取当前行指针const uchar* current = myImage.prt< uchar >(row);
  • 获取当前像素点P(row, col)的像素值P(row, col) = current[col];

3、像素处理范围saturate_cast< uchar >

  • saturate_cast< uchar >(-100),返回0
  • saturate_cast< uchar >(288),返回255
  • saturate_cast< uchar >(100),返回100
  • 这个函数的功能是确保RGB值的范围在0~255之间

4、函数调用filter2D功能

  • 定义掩膜:Mat kernel = (Mat_< char>(3, 3) << 0,-1,0,-1,5,-1,0,-1,0);
  • filter2D(sec, dst, src,depth(), kernel);
    • 其中src与dst是Mat类型变量,src.depth表示位图深度,有32、24、8等

5、代码

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace std;
using namespace cv;

int main()
{
	Mat src, dst;	//src表示源文件source,dst表示目标文件destination
	src = imread("D:/C++Project/OpenCVProject/test.jpg");	//读取图片
	if (!src.data) {		//读取时没有数据
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);	//创建窗口
	imshow("input image", src);		//显示图像
	
	//获取图像的列数,RGB为三通道,三通道的列为图像的宽度*通道数
	int cols = (src.cols - 1) * src.channels();		
	int offsetx = src.channels();	//通道数,偏移量
	int rows = src.rows;					//行数
	dst = Mat::zeros(src.size(), src.type());	//初始化为纯黑图像
	for (int row = 1; row < (rows - 1); row++) {
		const uchar* current = src.ptr<uchar>(row);			//当前行像素指针
		const uchar* previous = src.ptr<uchar>(row - 1);	//上一行像素指针
		const uchar* next = src.ptr<uchar>(row + 1);		//下一行的像素指针
		uchar* output = dst.ptr<uchar>(row);
		for (int col = offsetx; col < cols; col++) {
			//saturate_cast<uchar>作用是保证范围在0~255
			//current[col]即为I(i,j),即当前行的像素
			//current[col - offsetx]即为I(i,j-1),当前像素点左边的像素点。减去offsetx的原因是一个像素点有三个通道
			//current[col + offsetx]即为I(i, j+1)
			//previous[col]即为I(i-1, j)即为上一个行的像素点
			//next[col]即为I(i+1, j)即为下一行的像素点
			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));	
		}
	}

	//filter2D()等价于上述代码
	//Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);		//定义掩膜
	//filter2D(src, dst, src.depth(), kernel);
	//filter2D(src, dst, -1, kernel);表示与原图相同
	
	namedWindow("contrast image demo", WINDOW_AUTOSIZE);	
	resizeWindow("contrast image demo", 500, 500);		//定义显示窗口的大小
	imshow("contrast image demo", dst);
	waitKey(0);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CC_monster/article/details/86624662