1.前言:
使用掩码进行运算时,位运算符bitewise_and()、bitewise_or()、bitewise_xor()和bitewise_not()很有用!
void bitwise_and(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray()); //dst = src1 & src2
void bitwise_or(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray()); //dst = src1 | src2
void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray()); //dst = src1 ^ src2
void bitwise_not(InputArray src, OutputArray dst,
InputArray mask = noArray()); //dst = ~src
说明:
(1)bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1 & 1 = 1,1 & 0 = 0,0 & 1 = 0,0 & 0 = 0
(2)bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1 | 1 = 1,1 | 0 = 0,0 | 1 = 0,0 | 0 = 0
(3)bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,1 ^ 1 = 0, 1 ^ 0 = 1, 0 ^ 1 = 1, 0 ^ 0 = 0
(4)bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1 = 0,~0 = 1
2.掩码运算实现裁剪图像实例
先上代码!完整如下:
//main.cpp by yh
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img1 = imread("C:\\Users\\86151\\Pictures\\Camera Roll\\全智贤3.jpg",IMREAD_GRAYSCALE);
if (img1.empty()) //判断图像是否为空
{
cout << "Cannot load image!" << endl;
return -1;
}
namedWindow("Orignal Image", WINDOW_AUTOSIZE);
imshow("Orignal Image",img1);
//创建掩码图像
Mat mask(img1.rows,img1.cols,CV_8UC1,Scalar(0,0,0));
circle(mask, Point( img1.cols/2, img1.rows / 2), 90, 255, -1); //
namedWindow("Mask",WINDOW_AUTOSIZE);
imshow("Mask",mask);
//执行AND运算
Mat r;
bitwise_and(img1, mask, r); //“与”操作
//用白色填充外部
const uchar white = 255;
for (int i = 0; i < r.rows; i++)
{
for (int j = 0; j < r.cols; j++)
{
if (!mask.at<uchar>(i,j))
{
r.at<uchar>(i, j) = white;
}
}
}
namedWindow("Result", WINDOW_AUTOSIZE);
imshow("Result",r);
waitKey();
return 0;
}
结果:
拓展:
(1)首先,对circle函数进行说明,其构造函数如下:
cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color,
int thickness=1, int lineType=8, int shift=0)
其中,img为源图像指针;center为画圆的圆心坐标;radius为圆的半径;color为设定圆的颜色,规则根据B(蓝)G(绿)R(红);thickness 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充;line_type 线条的类型。默认是8;shift 圆心坐标点和半径值的小数点位数。
(2)然后,针对point函数及OpenCV图像坐标系进行说明(对应第21行代码),即图像坐标系与行高列宽的关系:
row = heiht = Point.x
col = width = Point.y
因此,在第21行代码处将圆心坐标写成“先列后行”的形式: Point( img1.cols/2, img1.rows / 2)。
参考文章链接:
https://blog.csdn.net/u011028345/article/details/77278467
https://blog.csdn.net/oqqENvY12/article/details/71933651
https://blog.csdn.net/yangfengman/article/details/52768862
End & Enjoy!