前言
在前面博文讲解位平面分解的时候,我们就提到过可以通过位平面分解的方式给图像添加水印。而数值水印是图片版权用到最多的加密方式。
通过在最低有效位的位平面分解图中隐藏二值图像信息,具有极高的隐蔽性。所以,友情提示各位程序员,不要以为网上的图像可以随便用,现在的加密方式真是让你防不胜防。就算你知道了添加数值谁水印的原理,恐怕也无法找到其哪个是秘密的信息。(尊重版权,不要存在侥幸心理)
数字水印的处理过程
从位平面来看,数字水印的处理过程分为如下几步:
(1)嵌入过程:将载体图像的第0个位平面替换为数字水印信息。
(2)提取过程:将载体图像的最低有效位平面提取出来,得到数字水印信息。
代码实现嵌入与提取数字水印
原理我们都清楚之后,我们可以直接开始编写代码:
import cv2 import numpy as np img = cv2.imread("4.jpg", 0) watermark = cv2.imread("watermark.jpg", 0) #因为水印图像就是让人不易察觉也不影响原图像,所以要将水印非0位全部替换位最小值1 w = watermark[:, :] > 0 watermark[w] = 1 #嵌入水印 r, c = img.shape #生成元素都是254的数组 img254=np.ones((r,c),dtype=np.uint8)*254 #获取高7位平面 imgH7=cv2.bitwise_and(img,img254) #将水印嵌入即可 water_img=cv2.bitwise_or(imgH7,watermark) cv2.imshow("1",img) cv2.imshow("2",watermark*255) cv2.imshow("3",water_img) #生成都是1的数组 img1=np.ones((r,c),dtype=np.uint8) #提取水印 water_extract=cv2.bitwise_and(water_img,img1) #将水印里面的1还原成255 w=water_extract[:,:]>0 water_extract[w]=255 cv2.imshow("4",water_extract) cv2.waitKey() cv2.destroyAllWindows()
前面我们介绍过,图像的最低位平面就是00000001,而其他7个位平面合并就是11111110,也就是254,所以我们创建了一个全部为254的数组。通过它获取高7个位平面,然后与数字水印图合并即可。
同样的,提取图像中数字水印,我们只需要获取最低有效位平面,然后将其1值,全部换成255,就可以显示出原水印图。
运行之后,显示的效果如下图所示: