Opencv_06 图像的逻辑操作

文章目录

      • 按位操作
        • ① 按位与说明
        • ② 按位或操作
        • ③ 按位异或操作
        • ④ 取反 bitwise_not

按位操作

① 按位与说明

  1. 将对应像素位置的像素值进行位与操作.
  2. 两幅图像必须大小和类型相同,否则报错
  3. 可以提供一个掩膜Mask

Mask的作用:
Mask掩膜运算,本质上就是将原来的图像和掩膜进行按位与运算;
注意:不是简单的按位与运算:

  1. 如果和掩膜按位与之后结果为真,就保留原图像素
  2. 如果为假,结果就是0
  3. 如果为真,可能就转换为了1,和原来的数据进行位与
    Opencv_06 图像的逻辑操作_第1张图片
  1. Mask只能是二维矩阵,与原图的size大小一致
  2. 只能是单通道的矩阵
  3. 不管mask的值是10还是255,如果为真,其和1都是等价的效果,最后得到的结果都是保留原图的像素值
#include "MyOpencv.h"
int main(void)
{
	Mat m1 = Mat::zeros(3, 3, CV_8UC1);
	Mat m2 = Mat::ones(3, 4, CV_8UC1);
	Mat m3 = Mat::ones(3, 3, CV_8UC3);
	Mat m4 = Mat::ones(3, 3, CV_8UC1);
	Mat dst1;
	//cv::bitwise_and(m1, m2, dst1); // 报错
	//cv::bitwise_and(m1, m3, dst1); // 报错
	cv::bitwise_and(m1, m4, dst1);
	cout << "m1 & m4 = " << endl;
	cout << dst1 << endl;

	// 使用mask
	Mat mask = Mat::ones(3, 3, CV_8UC1)*2;
	cv::bitwise_and(m4, m4, dst1, mask = mask);
	cout << "m4 & m4 通过mask之后的值: " << endl;
	cout << dst1 << endl;
	
	return 0;
}

结果:
Opencv_06 图像的逻辑操作_第2张图片

② 按位或操作

  1. 将对应像素做按位或操作
  2. 如果有掩膜,后面再跟掩膜进行运算,运算规则和bitwise_and一样
#include "MyOpencv.h"

int main(void)
{
	Mat src1 = Mat::zeros(Size(400, 400), CV_8UC3);
	Rect rect(100, 100, 100, 100);
	src1(rect) = Scalar(0, 0, 255); // BGR 红色
	imshow("Src1", src1);

	Mat src2 = Mat::zeros(Size(400, 400), CV_8UC3);
	rect.x = 150;
	rect.y = 150;
	src2(rect) = Scalar(0, 255, 255);// BGR 黄色
	imshow("Src2", src2);

	// 逻辑或操作
	Mat dst1;
	bitwise_or(src1, src2, dst1);
	imshow("bitwise_or", dst1);

	waitKey(0);

}

结果:
Opencv_06 图像的逻辑操作_第3张图片

③ 按位异或操作

  1. 将对应像素按照按位异或进行操作
  2. 如果有掩膜,最后再跟掩膜进行运算,运算规则和bitwise_and一样
#include "MyOpencv.h"

int main(void)
{
	Mat src1 = Mat::zeros(300, 300, CV_8UC3);
	Mat src2 = Mat::zeros(300, 300, CV_8UC3);
	Rect rect(100, 100, 100, 100);
	src1(rect) = Scalar(255, 0, 0);// 蓝色
	rect.x = 150;
	rect.y = 150;
	src2(rect) = Scalar(255, 255, 0);
	Mat dst;
	// 异或,相同部分为0,不同部分为0,所以和0异或结果不变. 
	// (255,0,0) | (255,255,0) -> (0,255,0) 所以重合部分变成了绿色
	bitwise_xor(src1, src2, dst);
	imshow("Src1", src1);
	imshow("Src2", src2);
	imshow("Src1 | Src2", dst);

	waitKey(0);

	return 0;
}

结果:
Opencv_06 图像的逻辑操作_第4张图片

④ 取反 bitwise_not

  1. 取反操作,就是做位取反,0变成1,1变成0.
  2. 如果提供了mask,取反之后再和mask进行运算

原型:

void bitwise_not(InputArray src,OutputArray dst,InputArray mask = noArray()); // dst = ~src;
#include "MyOpencv.h"

int main(void)
{
	Mat src1 = cv::Mat(Size(300, 300), CV_8UC3, Scalar(0, 0, 0)); // 一开始都是黑色
	Mat src2 = cv::Mat(Size(300, 300), CV_8UC3, Scalar(0, 0, 0)); // 一开始都是黑色
	Rect rect(100, 100, 100, 100);
	src1(rect) = Scalar(255, 0, 0); // 蓝色
	rect.x = 150;
	rect.y = 150;
	src2(rect) = Scalar(0, 255, 255); // 黄色

	// 将蓝色的反转
	Mat dst;
	bitwise_not(src1, dst);
	imshow("Src_1_Not", dst);
	bitwise_not(src2, dst);
	imshow("Src1", src1);
	imshow("Src2", src2);
	imshow("Src_2_Not", dst);

	// 只反转敢兴趣的区域,其他的区域不变,例如其他的区域还是维持黑色
	Mat mask = cv::Mat(Size(300, 300), CV_8UC1, Scalar(0));
	rect.x = 100;
	rect.y = 100;
	mask(rect) = Scalar(1);

	Mat mask2 = cv::Mat(Size(300, 300), CV_8UC1, Scalar(0));
	rect.x = 150;
	rect.y = 150;
	mask2(rect) = Scalar(1);
	Mat dst2;
	bitwise_not(src1, dst2,mask);
	imshow("src1_not_mask", dst2);
	Mat dst3;
	bitwise_not(src2, dst3, mask2);
	imshow("src2_not_mask", dst3);

	waitKey(0);

	return 0;
}

结果:

Opencv_06 图像的逻辑操作_第5张图片
总结:
Opencv_06 图像的逻辑操作_第6张图片

你可能感兴趣的:(Opencv_C++,opencv,计算机视觉,c++)