位运算bitwise_and函数

今天在学习opencv时,把OpenCV 的标志放到另一幅图像上。这时要用到cv2.bitwise_and函数,加下来从原理和效果讲一下这个函数。

目标:将下面这个logo加到蚂蚁图像的左上角并且背景无遮挡(logo图片白的部分不遮挡蚂蚁图片蓝的地方)。

位运算bitwise_and函数_第1张图片

位运算bitwise_and函数_第2张图片

效果:

位运算bitwise_and函数_第3张图片

下面直接上代码,根据代码讲解原理:

import cv2
img1 = cv2.imread(r'D:\Pycharm\learn_opencv\pic\ants_image\0013035.jpg')
img2 = cv2.imread('D:\Pycharm\learn_opencv\pic\logo.jfif')

rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols]

img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv)
dst = cv2.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst
cv2.imshow('sasa',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

 首先下面这两行的代码作用是将我们的蚂蚁图像中的对应logo图像的区域找出来记为roi

rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols]

我们将这个roi图像显示出来,与我们预想的一致,正是蚂蚁图像的左上角对应logo图像的区域:

位运算bitwise_and函数_第4张图片

 下面三行代码是生成一个mask掩码矩阵和mask_inv逆掩码矩阵方便我们后面cv2.bitwise_and函数的使用,我们稍微讲一下参数和原理,后面再看效果。

img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

第一行是将我们的logo图像变成灰度图像,第二行cv2.threshold函数的参数:第一个参数为原图像,第二个参数为进行分类的阈值,第三个参数为高于(低于)阈值时赋予的新值,第四个方法选择参数,常用的有:
• cv2.THRESH_BINARY(黑白二值)
• cv2.THRESH_BINARY_INV(黑白二值反转)
• cv2.THRESH_TRUNC (得到的图像为多像素值)
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV

返回值为:第一个retVal(得到的阈值值),第二个就是阈值化后的掩码图像

根据我们选择的模式为cv2.THRESH_BINARY,以及第二三个参数为200、255,表示:高于200的像素设置为255,否则像素值置零。其他模式见文章:(13条消息) 图像阈值处理cv2.threshold()函数(python)_肥宅_Sean的博客-CSDN博客_cv2threshold

于是我们的mask图像便是对于img2gray图像的高于200的像素值置255(白),否则置0(黑),我们来验证一下: 

img2gray图像:

位运算bitwise_and函数_第5张图片

mask掩码矩阵图像:

 位运算bitwise_and函数_第6张图片

可以看见img2gray中黑的和灰的像素值较低被置为黑色,背景白色仍置为白色。

得到mask掩码矩阵图像后我们接着往下看:

img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv)

cv2.bitwise_and函数的作用取与运算,第一个参数为输入图像,第二个参数为输出图像,第三个参数mask:图像掩膜,可选参数,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0

roi图像和mask图像上面已给出,下面我们给出img1_bg的图像:

位运算bitwise_and函数_第7张图片

与声明的一致,同理img2_fg图像只是将参数mask换成了其反矩阵,并且作用对象变成了我们的logo图像。我们看看效果:

img2_fn图像:

位运算bitwise_and函数_第8张图片

 也即在原来mask矩阵图像为白的时候输出原图logo图像,反之置黑。

最后,我们将上面两张图加起来就达到了我们想要的左上角部分,再把原图蚂蚁图像的左上角替换成我们加起来后的左上角部分即得到结果:

dst = cv2.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst

你可能感兴趣的:(opencv)