目录
二、cv2.bitwise_and(参数1,参数2,mask=参数3)
上一篇讲到利用掩膜可以抠出图像的某个区域,那么把这个区域无缝添加到另一张图上即为添加水印。在开始添加之前,需要介绍几个方法:
一、ROI切割
ROI:Region of Interest,翻译过来就是感兴趣的区域。什么意思呢?比如对于一个人的照片,假如我们要检测眼睛,因为眼睛肯定在脸上,所以我们感兴趣的只有脸这部分,其他都不care,所以可以单独把脸截取出来,或者直接截取眼睛。
而完成这个操作呢则是利用numpy里的切片操作,代码实施如下:
def test001():
img=cv2.imread("./src/11.jpg")
img2=img[300:300+300,300:300+300] #roi切割
cv2.imshow("img",img)
cv2.imshow("img2",img2)
cv2.waitKey(0)
前面的300表示起始的(x, y),后面的300表示要切割的roi区域大小
运行结果图示:
所以对于添加水印操作,我们完全可以在原图截取一部分与logo图大小相同的ROI区域,在这上面操作,节省计算量,提高运行速度。
二、cv2.bitwise_and(参数1,参数2,mask=参数3)
上篇讲掩膜的制作就是用到这个方法,复习一下:图与图本身进行按位与运算,在掩膜为白色的区域输出原图对应区域,掩膜为黑色的区域保持黑色。
三、添加水印
接下来开始添加水印,具体步骤如下(假设要添加的logo图为白底):
首先读取原图与原logo图:
def test1():
img1 = cv2.imread("./src/11.jpg") #要添加水印的图
logo = cv2.imread("./src/mylogo.png") #水印图
logo_gray = cv2.cvtColor(logo,cv2.COLOR_BGR2GRAY) #将水印图转为灰度图
运行结果图示:
将logo图转为灰度图是为了制作掩膜,接下来:
1、制作logo图的两张掩膜,一张前景色为黑色,即logo为黑色的掩膜,称为黑化白底logo(blacklogo),另一张前景色为白色,即logo为白色的掩膜,称为白化黑底logo(whitelogo):
_,blacklogo = cv2.threshold(logo_gray,220,255,cv2.THRESH_BINARY) #阈值法
_,whitelogo = cv2.threshold(logo_gray,220,255,cv2.THRESH_BINARY_INV) #反阈值法
运行结果图示:
这里为什么不用 cv2.inRange()制作掩膜是因为这个方法默认生成的掩膜前景色为白色,而前景色为黑色的掩膜我们同样需要,所以就直接用阈值法和反阈值法就好,这两个方法在这里不过多介绍,至于阈值的确定,我是用QQ的截图工具识别的logo灰度图的颜色,目前我暂时没想到方法
至于为什么要制作两张,后面解释
2、将原图切割得到与logo图大小相同的ROI区域;
h,w,c = logo.shape #获得logo图的尺寸
roi = img1[200:200+h,200:200+w] #切割与logo图大小相同的ROI区域,起始坐标随意只要加起来不超过原图
运行结果图示:
即接下来都在ROI区域内进行操作。
3、将ROI区域与自身进行cv2.bitwise_add()运算,黑化白底logo控制输出,此时ROI区域中会出现黑色的logo区域,称为(ROI加黑化logo图);再将原logo图与自身进行cv2.bitwise_add()运
算,白化黑底logo控制输出,得到黑底的logo图(原logo图是白底):
#print(roi.shape)
#print(blacklogo.shape)
roi_blacklogo = cv2.bitwise_and(roi,roi,mask=blacklogo) #得到ROI加黑化logo图
logo_heidi = cv2.bitwise_and(logo,logo,mask=whitelogo) #得到黑底logo图
运行结果图示:
这一步要确保进行与运算的图与掩膜的大小尺寸都相同,所以可以先打印两者的shape看看。
到这里刚刚制作的两张掩膜就派上用场了:因为我们的目的是在ROI区域内添加logo,所以需要在ROI区域内挖出logo区域,再用logo填充。blacklogo(黑logo白底)是ROI区域与自身按位与运算时进行控制的掩膜,所以会得到logo区域为黑色的ROI图,而whitelogo(白logo黑底)是原logo图与自身按位与运算时进行控制的掩膜,所以会得到黑底的logo图。得到这两张图之后:
4、将(ROI加黑化logo图)与黑底logo图进行图像融合,直接用cv2.add(),就得到了成功添加原彩色logo的ROI区域:
# print(roi_blacklogo.shape)
# print(logo.shape)
roi_logo = cv2.add(roi_blacklogo,logo_heidi)
运行结果图示:
cv2.add()加法在上一篇里也有介绍,就是两幅图像的对应像素值进行相加,黑化的logo+彩色logo结果当然是彩色logo,ROI区域+白底结果当然还是ROI区域,所以就顺利将彩色logo图填充到了roi_blacklogo,得到roi_logo,接下来就是最后一步:
5、修改原图的ROI区域使其等于成功添加水印的ROI区域,就成功在原图添加了水印:
img1_logo = img1.copy() #获得原图副本
img1_logo[200:200+h,200:200+w] = roi_logo #修改副本对应的ROI区域
运行结果图示:
成功在原图显示水印!这里的img_logo只是为了对比,当然也涉及到一个小知识点:.copy()是浅拷贝,修改图像的ROI区域相当于修改原图。
以上是添加白底的水印,如果是黑底的水印则更简单,只需要黑化白底的掩膜(blacklogo)用于挖空ROI区域内的logo区域,再直接叠加原logo图就行,不用像白底水印一样还需要一张掩膜去白底。下一篇是图像旋转,包括插值方法。