Python实现基于傅里叶变换的鲁棒盲水印算法
Python实现基于傅里叶变换的鲁棒盲水印算法
本文介绍如何使用Python和OpenCV库实现一种基于傅里叶变换的鲁棒盲水印算法。该算法将水印信息嵌入到图像的频域中,具有较好的鲁棒性。
1. 算法原理
该算法的核心思想是利用傅里叶变换将图像从空间域转换到频域,然后将水印信息嵌入到图像的低频或中频系数中。最后,通过逆傅里叶变换将图像转换回空间域,得到嵌入水印的图像。
2. 代码实现
以下Python代码实现了该算法的编码和解码过程:
import cv2
import numpy as np
import random
def encode_image(image_path, watermark_path, output_path, alpha=0.1, seed=0, oldseed=False):
'''
将水印嵌入到图像中。
参数:
image_path:原图路径
watermark_path:水印图路径
output_path:嵌入水印后的图像保存路径
alpha:水印嵌入强度
seed:随机种子
oldseed:是否使用旧版随机种子
'''
img = cv2.imread(image_path)
wm = cv2.imread(watermark_path)
h, w = img.shape[0], img.shape[1]
hwm = np.zeros((int(h * 0.5), w, img.shape[2]))
assert hwm.shape[0] > wm.shape[0]
assert hwm.shape[1] > wm.shape[1]
hwm2 = np.copy(hwm)
for i in range(wm.shape[0]):
for j in range(wm.shape[1]):
hwm2[i][j] = wm[i][j]
if oldseed:
random.seed(seed,version=1)
else:
random.seed(seed)
m, n = list(range(hwm.shape[0])), list(range(hwm.shape[1]))
if oldseed:
random.shuffle(m,random=random.random)
random.shuffle(n,random=random.random)
else:
random.shuffle(m)
random.shuffle(n)
for i in range(hwm.shape[0]):
for j in range(hwm.shape[1]):
hwm[i][j] = hwm2[m[i]][n[j]]
rwm = np.zeros(img.shape)
for i in range(hwm.shape[0]):
for j in range(hwm.shape[1]):
rwm[i][j] = hwm[i][j]
rwm[rwm.shape[0] - i - 1][rwm.shape[1] - j - 1] = hwm[i][j]
f1 = np.fft.fft2(img)
f2 = f1 + alpha * rwm
_img = np.fft.ifft2(f2)
img_wm = np.real(_img)
cv2.imwrite(output_path, img_wm, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
def decode_image(original_image_path, watermarked_image_path, alpha=0.1):
'''
从嵌入水印的图像中提取水印信息。
参数:
original_image_path:原图路径
watermarked_image_path:嵌入水印后的图像路径
alpha:水印嵌入强度
返回值:
提取出的水印图像
'''
img = cv2.imread(original_image_path)
img_wm = cv2.imread(watermarked_image_path)
f1 = np.fft.fft2(img)
f2 = np.fft.fft2(img_wm)
rwm = (f2 - f1) / alpha
rwm = np.real(rwm)
hwm = np.zeros(rwm.shape)
for i in range(int(rwm.shape[0] * 0.5)):
for j in range(rwm.shape[1]):
hwm[i][j] = np.uint8(rwm[i][j])
hwm[rwm.shape[0] - i - 1][rwm.shape[1] - j - 1] = hwm[i][j]
wm = np.zeros(hwm.shape)
m, n = list(range(hwm.shape[0])), list(range(hwm.shape[1]))
random.shuffle(m)
random.shuffle(n)
for i in range(hwm.shape[0]):
for j in range(hwm.shape[1]):
wm[m[i]][n[j]] = hwm[i][j]
return wm
# 示例用法
# 嵌入水印
encode_image('P.jpg', 'wm.jpg', 'SP.jpg', alpha=0.05)
# 提取水印
wm_extracted = decode_image('P.jpg', 'SP.jpg', alpha=0.05)
cv2.imwrite('extracted_wm.jpg', wm_extracted)
3. 鲁棒性分析
该算法将水印信息嵌入到图像的频域中,具有一定的鲁棒性,可以抵抗一些常见的图像攻击,例如JPEG压缩、噪声添加、滤波等。
4. 提高鲁棒性的方法
为了进一步提高算法的鲁棒性,可以考虑以下方法:
- 选择合适的嵌入强度:嵌入强度越大,水印越难以去除,但图像质量也会下降。
- 将水印信息嵌入到多个频带中:可以将水印信息分散嵌入到图像的不同频带中,提高水印的鲁棒性。
- 使用更 robust 的水印信息:可以考虑使用具有良好抗攻击能力的水印信息,例如二值图像或特定图案。
5. 总结
本文介绍了一种基于Python的鲁棒盲水印算法。该算法使用傅里叶变换将水印信息嵌入到图像的频域中,具有较好的鲁棒性。通过调整算法参数和使用更 robust 的水印信息,可以进一步提高算法的鲁棒性。
原文地址: https://www.cveoy.top/t/topic/fTgs 著作权归作者所有。请勿转载和采集!