这次的内容主要为水印图像经过阿诺德置乱算法后通过离散小波变换进行嵌入,仅考虑嵌入方式,其余部分处理从简,之后再做探究。
嵌入部分参考上图公式,为验证方便,代码中将三级小波变换与一级小波变换的嵌入方式简化为一级小波变换与一级小波变换的嵌入,当然,嵌入效果不会很好。
为使结果仍为彩色图像,在小波变换前将原图像通道分离(本次选取B通道)在嵌入完成后,再将通道合并。
import cv2 import pywt import numpy as np import matplotlib.pyplot as plt Img = cv2.imread('lena.bmp') # 原图 waterImg = cv2.imread('new.bmp',0) # 水印图像,灰度读取 # 水印图像尺寸数据 r = waterImg.shape[0] c = waterImg.shape[1] # 原图尺寸数据 R = Img.shape[0] C = Img.shape[1] img = cv2.resize(Img, (r, c))
(b, g, r) = cv2.split(img) # 水印图像一级小波变换 coeffs1 = pywt.dwt2(waterImg, 'haar') ca1, (ch1, cv1, cd1) = coeffs1 coeffs2 = pywt.dwt2(b, 'haar') # blue通道 ca2, (ch2, cv2, cd2) = coeffs2 # 自定义嵌入系数,这部分可以用随机数处理 a1 = 0.1 a2 = 0.2 a3 = 0.1 a4 = 0.1 ca2 = ca2 + ca1 * a1 ch2 = ch2 + ch1 * a2 cv2 = cv2 + cv1 * a3 cd2 = cd2 + cd1 * a4 newimg = pywt.idwt2((ca2, (ch2, cv2, cd2)), "haar") merged = np.ones(img.shape, dtype=np.uint8) merged[:,:,2] = newimg merged[:,:,1] = g merged[:,:,0] = r plt.imshow(merged) plt.axis('off') # 去掉多余空白边缘,同时使图像重新转化为原来的尺寸 fig = plt.gcf() fig.set_size_inches(float(R/100)/3, float(C/100)/3) plt.gca().xaxis.set_major_locator(plt.NullLocator()) plt.gca().yaxis.set_major_locator(plt.NullLocator()) plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0) plt.margins(0, 0) plt.savefig("lena.png", transparent=True, dpi=300, pad_inches=0) plt.show()
结果示例:
嵌入后
(嵌入内容为100*100的校徽logo)
原图
之后会继续做精细化处理,确保处理后的图像与原图尽可能不存在肉眼可见的差异。
参考来源: