opencv矩阵掩膜操作

僤鯓⒐⒋嵵緔 提交于 2021-01-26 10:57:27

前言

本文介绍opencv的矩阵掩膜操作。

一、图像的基本操作:

1、图像的定义:图像是指由输入设备捕捉的实际场景画面或以数字化形式存储的任意画面(由一个个像素组成)。像素是组成图像的最小单位,而每个像素则由多个(通常为3个)不同颜色(通常为红、绿、蓝)的点组成
在这里插入图片描述

2、图像的基本运算有很多种,例如:+、-、*、/、位运算、平方根、对数、绝对值等;
3、图像也可以放大、缩小、旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作;
4、各个颜色通道可以分别提取及对各个颜色通道进行各种运算操作*(例如RGB有3种颜色通道,都可以进行运算)。在这里插入图片描述

二、掩膜(Mask)是什么?

1、掩膜的组成:掩模是由0和1组成的一个二进制图像。
可简单理解为一个由0和1组成的矩阵。

2、掩膜的定义:用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。

       在OpenCV的中,掩模操作是相对简单的。大致的意思是,通过一个掩模矩阵,重新计算图像中的每一个像素值。掩模矩阵控制了旧图像当前位置以及周围位置像素对新图像当前位置像素值的影响力度。用数学术语讲,即我们自定义一个权重表。

3、掩膜操作举例:我们简单用与运算(&)举个例子:
运算方式:原图中每个像素和掩膜中的每个对应像素进行与运算。
在这里插入图片描述

三、掩膜(Mask)实现图像对比度的调整:

1、掩膜操作计算公式:对比度调整计算公式
2、opencv的语法:

  2.1 获取矩阵的行指针ptr函数 const uchar *current = src.ptr(row);
FF
  2.2 获取矩阵每个像素的通道数 int offsetx = src.channels();

  2.3 像素的点值处理函数,saturate_cast(uchar数值)功能是确保RGB值范围在0〜255之间。
     像素的范围处理:
     saturate_cast ( - 1),小于0返回0
     saturate_cast (256),大于255返回255
     saturate_cast (100),返回100



  2.4 函数调用filter2D功能
      定义掩膜:
      Mat kernel = (Mat_(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
      filter2D( src, dst, src.depth(), kernel ); 其中src与dst是Mat类型变量、src.depth()表示位图深度,有32、24、8等,kernel是Mat对象。


3、代码实现:

  3.1 自定义掩膜操作

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;
int main() {
   
   
	Mat src, dst;
	src = imread("C:\\Users\\ASUS\\Desktop\\1.jpg");
	if (!src.data) {
   
   
		cout << "could not  load image!";
		return 0;
	}
	namedWindow("my_screen", WINDOW_AUTOSIZE); //创建一个窗口,自动大小不可人为改变
	imshow("my_screen", src);

	int cols = src.cols * src.channels();    //cols获取图像的列,因为每个像素有3个像素通道,channels获取像素通道
	int offsetx = src.channels();            //channels获取像素通道
	int rows = src.rows;                     //rows获取像素的行
	dst = Mat(src.size(), src.type());       //创建一个原图像大小,形式的空间
	for (int row = 1; row < rows - 1; row++) {
   
     
		const uchar* current = src.ptr<uchar>(row - 1); //获取上一行的指针
		const uchar* previous = src.ptr<uchar>(row);
		const uchar* next = src.ptr<uchar>(row + 1);  //获取下一行的指针
		uchar* output = dst.ptr<uchar>(row);
		for (int col = offsetx; col < cols; col++) {
   
   
			output[col] = saturate_cast<uchar>(5 * current[col] -
				(current[col - 1 - offsetx] + current[col + offsetx] + previous[col] + next[col]));
			//利用像素处理函数,处理越界数值
		}
	}

	namedWindow("contrast image demo", WINDOW_AUTOSIZE);
	imshow("contrast image demo", dst);
	waitKey(0);

	return 0;
}

  3.2 函数调用filter2D功能操作:

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;
int main() {
   
   
	Mat src, dst;
	src = imread("C:\\Users\\ASUS\\Desktop\\1.jpg");
	if (!src.data) {
   
   
		cout << "could not  load image!";
		return 0;
	}
	namedWindow("my_screen", WINDOW_AUTOSIZE); //创建一个窗口,自动大小不可人为改变
	imshow("my_screen", src);

	//用opencv的API  filter2D
	double t = getTickCount();
	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(src, dst, src.depth(), kernel);
	double timeconsums = (getTickCount() - t) / getTickFrequency();
	cout << "time consume " << timeconsums; //用来计算时长

	namedWindow("contrast image demo", WINDOW_AUTOSIZE);
	imshow("contrast image demo", dst);
	waitKey(0);

	return 0;
}

4、处理结果:在这里插入图片描述

四、总结:

本文的矩阵掩膜就是两幅图像之间进行的各种位运算操作。

如有错误,请指教!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!