奇异值分解水印嵌入以及水印提取代码
时间: 2023-11-12 19:07:27 浏览: 89
奇异值分解算法的m代码,实现了数字水印技术的嵌入及提取过程
奇异值分解(SVD)是一种常用的矩阵分解方法,可以将一个复杂的矩阵分解成三个简单的矩阵,其中一个是对角矩阵,可以用于实现水印嵌入和提取。
以下是使用Python实现的SVD水印嵌入和提取的代码:
```python
import numpy as np
from PIL import Image
# 水印嵌入
def watermark_embed(img_path, watermark_path, alpha=0.01):
# 读取原始图像和水印图像
img = Image.open(img_path).convert('L')
watermark = Image.open(watermark_path).convert('L')
# 将图像转换为矩阵
img_mat = np.array(img)
watermark_mat = np.array(watermark)
# 对原始图像进行奇异值分解
U, sigma, V = np.linalg.svd(img_mat)
# 生成水印
watermark_sigma = sigma * alpha + watermark_mat
# 重构图像
img_sigma = np.zeros(img_mat.shape)
img_sigma[:sigma.shape[0], :sigma.shape[0]] = np.diag(watermark_sigma)
watermark_img = np.dot(U, np.dot(img_sigma, V))
# 保存水印图像
watermark_img = Image.fromarray(watermark_img.astype(np.uint8))
watermark_img.save('watermark.png')
return watermark_img
# 水印提取
def watermark_extract(img_path, alpha=0.01):
# 读取水印图像
watermark = Image.open('watermark.png').convert('L')
# 将图像转换为矩阵
watermark_mat = np.array(watermark)
# 读取带水印的图像
img = Image.open(img_path).convert('L')
# 对带水印的图像进行奇异值分解
img_mat = np.array(img)
U, sigma, V = np.linalg.svd(img_mat)
# 提取水印
watermark_sigma = (sigma - watermark_mat) / alpha
return watermark_sigma
# 测试
img_path = 'lena.png'
watermark_path = 'watermark.png'
# 嵌入水印
watermark_embed(img_path, watermark_path)
# 提取水印
watermark_sigma = watermark_extract(img_path)
# 保存水印
watermark_img = np.zeros((watermark_sigma.shape[0], watermark_sigma.shape[0]))
np.fill_diagonal(watermark_img, watermark_sigma)
watermark_img = Image.fromarray(watermark_img.astype(np.uint8))
watermark_img.save('extracted_watermark.png')
```
在代码中,我们使用了`numpy`和`PIL`库。其中,`watermark_embed`函数用于嵌入水印,它先将原始图像和水印图像转换为矩阵,然后对原始图像进行奇异值分解,生成水印,并重构图像,最后保存水印图像。`watermark_extract`函数用于提取水印,它首先读取水印图像,将其转换为矩阵,然后读取带水印的图像,对其进行奇异值分解,提取水印,最后保存提取出来的水印图像。
需要注意的是,在嵌入水印时,我们将原始图像的奇异值乘以一个系数alpha,再加上水印图像的奇异值。这个系数决定了水印的强度,可以根据实际需求进行调整。在提取水印时,我们将提取出来的水印除以alpha,得到水印的原始值。
以上是基于SVD实现的水印嵌入和提取的代码,但是并不是唯一的实现方式。此外,还有很多其他的水印嵌入和提取算法,可以根据实际需求选择合适的算法。
阅读全文