一、添加水印
添加水印的概念其实可以理解为将一张图片中的某个物体或者图案提取出来,然后叠加到另一 张图片上。
具体的操作思想是通过将原始图片转换成灰度图,并进行二值化处理,去除背景部分,得到 一个类似掩膜的图像。然后将这个二值化图像与另一张图片中要添加水印的区域进行“与”运算,使得目 标物体的形状出现在要添加水印的区域。最后,将得到的目标物体图像与要添加水印的区域进行相加, 就完成了添加水印的操作。这样可以实现将一个图像中的某个物体或图案叠加到另一个图像上,从而实 现添加水印的效果。
二、模板输入
用模板输入所输入的图片其实是作为要添加的水 印,有了水印的彩色图之后,我们需要用它来制作一个掩模,这就用到了灰度化和二值化,即先灰度化 后二值化,这就得到了带有水印图案的掩模。
三、与运算
有了模板的掩膜之后(也就是二值化图),我们就可以在要添加水印的图像中,根据掩膜的大小切割出 一个ROI区域,也就是我们要添加水印的区域,之后让其与模板的掩膜进行与运算,与运算 的过程中,只要有黑色像素,那么得到的结果图中的对应位置也会是黑色像素。由于模板的掩膜中目标 物体的像素值为黑色,所以经过与运算后,就会在ROI区域中得到模板图的形状。
四、图像融合
将模板的形状添加到水印区域之后,就可以将该图像与原始的模板图进行图像融合。该组件的目的就是 将图像对应的数组中的对应元素进行相加(一定要注意这里的两个数组是规格相同的,也就是说要么都 是灰度图,要么都是彩图),其过程如下图所示。
因此就可以让原始的模板图与添加模板图形状的ROI区域进行图像融合,得到添加水印的ROI区域。
五、图像添加水印
导入模块
import cv2
输入原图像
img=cv2.imread('lena.png')
输入模板图
img_logo=cv2.imread('light.jpg')
roi切割 原图像切割模板图大小
rows,cols=img_logo.shape[:2]
roi=img[:rows,:cols]
模板图灰度化
img_logo_gray=cv2.cvtColor(img_logo,cv2.COLOR_BGR2GRAY)
模板图二值化 反阈值法
ret,mask=cv2.threshold(img_logo_gray,135,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
与运算
img_and=cv2.bitwise_and(roi,roi,mask=mask)
图像融合
dst=cv2.add(img_and,img_logo)
替换原切割区域
img[:rows,:cols]=dst
输出图像
cv2.imshow('img',img)
cv2.waitKey(0)
完整代码
import cv2
# 读取背景图片
img = cv2.imread('lena.png')
# 读取logo图片
img_logo = cv2.imread('light.jpg')
# 获取logo图片的尺寸
rows, cols = img_logo.shape[:2]
# 截取lena图片左上角区域,与logo图片大小一致,作为logo的背景区域
roi = img[:rows, :cols]
# 将logo图片转换为灰度图
img_logo_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY)
# 使用阈值处理生成掩膜(mask),用于提取logo的形状
# ret, mask = cv2.threshold(img_logo_gray, 127, 255, cv2.THRESH_BINARY_INV)
# cv2.THRESH_BINARY_INV:将大于阈值的像素设置为0,小于阈值的像素设置为255。
# cv2.THRESH_OTSU:使用Otsu算法自动计算最佳阈值。
ret, mask = cv2.threshold(img_logo_gray, 135, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 使用bitwise_and操作,将背景区域roi与掩膜mask进行与运算,提取出背景区域中与logo形状对应的部分
img_and = cv2.bitwise_and(roi, roi, mask=mask)
# 将提取出的logo区域与logo图片本身相加,得到最终的logo图像
dst = cv2.add(img_and, img_logo)
# 将最终的logo图像放置回lena图片的左上角
img[:rows, :cols] = dst
# 显示结果图像
cv2.imshow('img', img)
# 等待按键按下
cv2.waitKey(0)
注意:
该logo图像尺寸必须小于原图像,如果logo图像尺寸大于原图像,需使用resize 修改
六、库函数
6.1、add()
cv.add( src1, src2[, dst[, mask[, dtype]]] ) -> dst
方法 | 描述 |
---|---|
src1 | 输入图像1 |
src2 | 输入图像2 |
dst | 输出图像,该为返回值 |
mask | 可选作掩膜 - 8 位单通道数组,指定要更改的输出数组的元素。 |
dtype | output 数组的可选深度 |