- 将对应像素位置的像素值进行位与操作.
- 两幅图像必须大小和类型相同,否则报错
- 可以提供一个掩膜Mask
Mask的作用:
Mask掩膜运算,本质上就是将原来的图像和掩膜进行按位与运算;
注意:不是简单的按位与运算:
- Mask只能是二维矩阵,与原图的size大小一致
- 只能是单通道的矩阵
- 不管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;
}
- 将对应像素做按位或操作
- 如果有掩膜,后面再跟掩膜进行运算,运算规则和
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);
}
- 将对应像素按照按位异或进行操作
- 如果有掩膜,最后再跟掩膜进行运算,运算规则和
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;
}
- 取反操作,就是做位取反,0变成1,1变成0.
- 如果提供了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;
}
结果: