-
時我們需要給一張圖片添加logo,例如下圖這樣
-
掩膜操作思路它的思想是:
1.1 先將彩色圖像轉換為灰度圖,然后利於閾值將圖像二值化,變成非黑即白的形式,這樣logo的蒙版就做好來了(學過PS的人應該很容易理解);
1.2 蒙版中黑色的區域表示刪除掉該區域像素,白色表示保留該區域像素。黑色是0,白色是255;
1.3 所以利用二值化得到的蒙版(掩膜)是剔除logo區域的。反之,是用來提出logo上的多余區域的;
1.4 如何剔除掉小姐姐照片中的logo區和logo上的空白區域呢,用cv2.bitwise_and方法。因為0(黑色)與非0數and后為0,這樣就可以把該區域剔除啦;
1.5 最后,將logo補到小姐姐照片上就可以了。 -
完整代碼
import cv2
img1 = cv2.imread('person.jpg')
logo = cv2.imread('food.jpg')
rows, cols, channels = logo.shape # 獲取圖像2的屬性
roi = img1[0:rows, 0:cols] # 選擇roi范圍
logo2gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY) # 轉換為灰度圖像
ret, mask = cv2.threshold(logo2gray, 175, 255, cv2.THRESH_BINARY) # 設置閾值,大於175的置為255,小於175的置為0 logo黑色
mask_inv = cv2.bitwise_not(mask) # 非運算 logo白色
img1_bg = cv2.bitwise_and(roi, roi, mask=mask) # 刪除了ROI中的logo區域(mask的logo為黑色,故and后該區域被舍去)---》上圖中的圖一
logo_fg = cv2.bitwise_and(logo, logo, mask=mask_inv) #刪除了logo中的空白區域(mask_inv的logo為百度色,故and后該區域被保留)----》上圖中的圖二
dst = cv2.add(img1_bg, logo_fg) # 兩個像插銷一樣,一個被鏤空,一個被保留,兩者相加,剛剛好
img1[0:rows, 0:cols] = dst # 將貼圖后的區域圖,覆蓋到原圖
cv2.imshow('res', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 可能的報錯信息
3.1 尺寸不一致導致
報錯如下:
person_ = cv2.bitwise_and(roi, roi, mask=mask)
'cv2.error: OpenCV(4.5.1) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-6uw63ony\opencv\modules\core\src\arithm.cpp:250: error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'
原因:roi和mask的尺寸(長和寬)不一致導致的,比如img.shape=(800,600),roi截取img一部分是,可能超出原本的大小,比如roi=img[0:610,0:610],roi.shape實際等於(610,600),造成與mask.shape=(610,610)不一致,從而報錯
注意:roi是RGB,mask是二值圖,通道本身就不等,我們進要求長和寬一致即可