欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv 第二课 矩阵的掩膜操作

程序员文章站 2022-07-14 09:04:14
...

                                 第二课 矩阵的掩膜操作

本章主要讲述了 掩膜的基本理论,与对图片的操作:

opencv 第二课 矩阵的掩膜操作

左边是原始图片,右边是通过掩膜操作生成的图片,对比一下可以看出来差别的。

opencv 第二课 矩阵的掩膜操作

先让我们了解下基本函数:

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>-100),返回 0

saturate_cast<uchar>288),返回255

lsaturate_cast<uchar>100),返回100

 

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

using namespace cv;
using namespace std;

int main()
{
	Mat src, dsr;
	src = imread("D:/image/1.png");
	if (!src.data)
	{
		cout << "could not " << endl;
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	
	int cols = (src.cols -1 )* src.channels();
	int offsetx = src.channels(); //通道数
	int rows = src.rows;

	dsr = Mat::zeros(src.size(), src.type());
	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 = dsr.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]
				 ));
		}
	}
	namedWindow("current image demo", CV_WINDOW_AUTOSIZE);
	imshow("current image demo", dsr);
	waitKey(0);

	return 0;
}

      这里要解释一下,src.channels() 是获取图片的通道数,以上述图片的话是是RGB图片,src.channels() 获取的值为3,

     这里解释一下图片数据的存储,R 指红的值,取值为0~255,同理G  ,B 取值也是0~255, 通过RGB三个数据,组成了一个像素,R G B 分别都是 uchar类型,所以是24位,每个是8位。3个字节,也就是3通道。

举个简单的例子,一个图片存的数是 R G B 取值随机的数 0~255

存储的为:

RGB RGB RGB RGB  RGB  RGB  RGB

RGB RGB RGB RGB  RGB  RGB  RGB

RGB RGB RGB RGB  RGB  RGB  RGB

这里为了方便,空格不占数组位,我们要第一个要改变R的值,所以是 row 为 的一行  col 为 的一列

(row - 1, col), (row +1, col)    (row, col - 3),   (row,  col +3)  这4个值 为R的值

R = 5 * R -R(row - 1, col) + R(row +1, col) + R(row, col - 3) + R(row,  col +3);

后面的G ,B 一次类推,这样就把对应的数据都改写了一遍,且周边数据不变。

 

函数调用filter2D功能

opencv为了方便把上述的功能封装起来让我们一起来看:

定义掩膜:Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

filter2D( src, dst, src.depth(), kernel );其中srcdstMat类型变量、src.depth表示位图深度,有32248等。

上面的代码,需要改变一下,可以得到相同的结果。

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

using namespace cv;
using namespace std;

int main()
{
	Mat src, dsr;
	src = imread("D:/image/1.png");
	if (!src.data)
	{
		cout << "could not " << endl;
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	Mat kernel = (Mat_<char>(3,3) << 0,  -1,   0,
		                        -1,   5,  -1,
	                                 0,  -1,   0);
	filter2D(src, dsr, src.depth(), kernel);
	namedWindow("current image demo", CV_WINDOW_AUTOSIZE);
	imshow("current image demo", dsr);
	waitKey(0);

	return 0;
}

 是不是非常的简单,哈哈哈,你学会了吗。  喜欢的同学可以关注我的博客,一起学习,加油!