请给出完整代码仿真实现基于DWT的邻近值水印算法matlmap
时间: 2024-02-15 10:03:56 浏览: 78
好的,以下是基于 Python 语言仿真实现基于DWT的邻近值水印算法matlmap的完整代码:
```python
import cv2
import numpy as np
from math import log2, ceil
def binary_to_decimal(binary):
"""
将二进制序列转换为十进制数值
"""
decimal = 0
for i in range(len(binary)):
decimal += binary[i] * pow(2, len(binary) - i - 1)
return decimal
def decimal_to_binary(decimal, length):
"""
将十进制数值转换为指定长度的二进制序列
"""
binary = []
while decimal > 0:
binary.insert(0, decimal % 2)
decimal //= 2
while len(binary) < length:
binary.insert(0, 0)
return binary
def matlmap_embed(img_path, watermark, alpha):
"""
利用邻近值水印算法将水印嵌入到图像中
img_path: 原始图像路径
watermark: 水印信息,字符串形式
alpha: 嵌入强度,取值范围为[0, 1]
"""
# 加载原始图像
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
rows, cols = img.shape
# 对图像进行二维离散小波变换,得到四个子带的系数矩阵
level = ceil(log2(min(rows, cols))) - 1
coeffs = pywt.wavedec2(img, 'haar', level=level)
LL, (LH, HL, HH) = coeffs[0], coeffs[1], coeffs[2], coeffs[3]
# 将水印信息转换为二进制序列
watermark = ''.join(map(lambda x: '{:08b}'.format(ord(x)), watermark))
w_length = len(watermark)
# 计算嵌入强度对应的阈值
max_HH = np.max(HH)
threshold = alpha * max_HH
# 将水印信息嵌入到HH子带的系数矩阵中
w_index = 0
for i in range(rows // 2, rows):
for j in range(cols // 2, cols):
if abs(HH[i][j]) > threshold:
HH[i][j] += (-1) ** int(watermark[w_index])
w_index += 1
if w_index == w_length:
break
if w_index == w_length:
break
# 对修改后的系数矩阵进行离散小波反变换,得到带有水印的图像
coeffs_new = (LL, (LH, HL, HH))
img_new = pywt.waverec2(coeffs_new, 'haar')
return img_new
def matlmap_extract(img_path, alpha, w_length):
"""
从图像中提取嵌入的水印信息
img_path: 带有水印的图像路径
alpha: 嵌入强度,取值范围为[0, 1]
w_length: 水印信息的长度
"""
# 加载带有水印的图像
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
rows, cols = img.shape
# 对图像进行二维离散小波变换,得到四个子带的系数矩阵
level = ceil(log2(min(rows, cols))) - 1
coeffs = pywt.wavedec2(img, 'haar', level=level)
LL, (LH, HL, HH) = coeffs[0], coeffs[1], coeffs[2], coeffs[3]
# 计算嵌入强度对应的阈值
max_HH = np.max(HH)
threshold = alpha * max_HH
# 从HH子带的系数矩阵中提取水印信息
watermark = ''
w_index = 0
for i in range(rows // 2, rows):
for j in range(cols // 2, cols):
if abs(HH[i][j]) > threshold:
watermark += str(abs(int(HH[i][j])) % 2)
w_index += 1
if w_index == w_length:
break
if w_index == w_length:
break
# 将二进制序列转换为字符串
w_chars = []
for i in range(0, len(watermark), 8):
w_chars.append(chr(binary_to_decimal(list(map(int, watermark[i:i+8])))))
watermark_str = ''.join(w_chars)
return watermark_str
# 测试样例
if __name__ == '__main__':
img_path = 'lena.png'
watermark = 'This is a watermark.'
alpha = 0.1
img_embed = matlmap_embed(img_path, watermark, alpha)
cv2.imwrite('lena_watermarked.png', img_embed)
watermark_extract = matlmap_extract('lena_watermarked.png', alpha, len(watermark))
print('Extracted watermark:', watermark_extract)
```
在代码中,matlmap_embed() 函数实现了将水印信息嵌入到图像中的过程,matlmap_extract() 函数实现了从带有水印的图像中提取水印信息的过程。具体实现过程和原理在前面的回答中已经说明,这里不再赘述。
阅读全文