(OpenCV)bitwise_and 的mask通俗理解[轉錄]

Ryan Lu
Linux on raspberry pi4
4 min readNov 21, 2020

先來兩張圖:

我們要把logo圖貼到美女圖的右下角,應該怎麼做呢?直接上思路圖:

不要怕,聽我慢慢講,首先,理解的一個關鍵問題,是要明白圖中的“黑色”是什麼,黑色代表0,0嘛,如果顏色數字和它想加(cv2.add),就是顏色數字本身,如果顏色數字和它進行位與運算(cv2.bitwise_and),就還是0;反過來理解,對有黑色的部分,用bitwise_and函數,可以把其他圖相應部分被黑化;用cv2. add函數,可以在黑色區域顯示其他圖的東西。囉嗦一下是值得的,這對理解整個過程是至關重要的。

對於上面的思路圖,從左到右是程序的實現過程,但要理解思路,則要從右往左,倒過來看:

1、 我們要得到右下角的圖,其實就是要得到箭頭最右邊的圖。哪怎樣才能得到它呢?

2、 想像自己用剪刀把最右邊的圖剪出logo,我們要得到倒數第二列那兩個圖了;用add函數,使這兩圖的有色部分剛好套進對方的黑色部分,就得到最右邊那張圖了,哪這兩張圖又怎麼得到呢?

3、 看中間列,這次不是剪,而是把掩膜覆蓋到有色圖上,其中黑色是不透明的,而白色的透明的。上下兩組圖分別生產右邊的圖,都是通過bitwise_and函數,作用都是用黑色部分把有色圖的相應部分乾掉了。這四張圖,下面是logo原圖,上面是原圖剪出來的小圖。哪中間的兩個掩膜又是怎樣得到的呢?

4、 有灰度圖就行了,通過閥值把灰度圖把像素推向兩個極端,不就有這兩個掩膜了嗎,那灰度圖又是怎麼來的呢?

5、 把logo原圖灰度化,用​​cvtColor函數,到此,應該有“終於明白了”的感覺了吧

代碼奉上:

import cv2
import numpy as np
img1 = cv2.imread('jiemi.jpg')
img2 = cv2.imread('logo.jpg')
#引入两个图片,第二个是logo
r1,c1,ch1 = img1.shape
r2,c2,ch2 = img2.shape
roi = img1[r1-r2:r1, c1-c2:c1 ]
#设定jiemi图的roi,注意:对roi的操作就是对img1的操作
gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#得到灰度图
ret, ma1 = cv2.threshold(gray, 170, 255, cv2.THRESH_BINARY)
fg1 = cv2.bitwise_and(roi,roi,mask=ma1)
#ma1是黑化logo,黑的地方可以通过bitwise_and把其他黑掉,所以ma1是黑roi的
ret, ma2 = cv2.threshold(gray, 170, 255, cv2.THRESH_BINARY_INV)
fg2 = cv2.bitwise_and(img2,img2,mask = ma2)
#ma2是黑化周边,所以ma2是黑logo的
#ma2=cv2.bitwise_not(ma1) 也可以这样对其反转
roi[:] = cv2.add(fg1, fg2)
#这里终于合体了
cv2.imshow('img1',img1)cv2.waitKey(0)
cv2.destroyAllWindows()

[轉錄]
python openCV掩膜的通俗理解

--

--