opencv-python掩膜操作

  1. 时我们需要给一张图片添加logo,例如下图这样

  2. 掩膜操作思路它的思想是:
    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补到小姐姐照片上就可以了。

  3. 完整代码

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()
  1. 可能的报错信息
    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是二值图,通道本身就不等,我们进要求长和宽一致即可

posted @ 2021-01-27 21:44  盐亭的森林  阅读(1969)  评论(0编辑  收藏  举报