python实现数字水印的嵌入和提取
时间: 2023-08-21 16:06:32 浏览: 139
Python实现数字水印的嵌入和提取,需要用到一些相关的第三方库,比如Pillow、numpy、scikit-image等。下面是数字水印的嵌入和提取的基本步骤:
1. 数字水印的嵌入
(1)读取原始图像,将其转化为灰度图像。
(2)生成数字水印,比如一个二进制序列或者一个字符串。
(3)对数字水印进行加密处理,比如使用AES算法进行加密。
(4)将加密后的数字水印嵌入到图像中,比如使用DWT离散小波变换将数字水印嵌入到LL分量中。
(5)保存嵌入了数字水印的图像。
2. 数字水印的提取
(1)读取嵌入了数字水印的图像。
(2)对图像进行DWT离散小波变换,提取出LL分量。
(3)对LL分量进行逆DWT离散小波变换,得到包含数字水印的图像。
(4)从图像中提取数字水印,比如使用AES算法进行解密。
(5)判断提取出的数字水印是否与原始数字水印一致。
下面是一个简单的Python代码示例,实现数字水印的嵌入和提取:
```python
from PIL import Image
import numpy as np
from skimage import io
from Crypto.Cipher import AES
import binascii
# 嵌入数字水印
def embed_watermark(image_path, watermark, key):
# 读取原始图像
image = Image.open(image_path).convert('L')
# 将图像转化为numpy数组
image_array = np.array(image)
# 生成数字水印
watermark_bin = ''.join(format(ord(c), '08b') for c in watermark)
# 将数字水印转化为numpy数组
watermark_array = np.array(list(watermark_bin), dtype=int).reshape((len(watermark_bin), 1))
# 加密数字水印
cipher = AES.new(key.encode(), AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(watermark_bin.encode())
# 将加密后的数字水印嵌入到图像中
watermark_size = len(ciphertext)
image_array[:watermark_size, :watermark_size] |= (ciphertext.reshape((watermark_size, 1, 1)) >> np.arange(8)[::-1]) & 1
# 保存嵌入了数字水印的图像
io.imsave('watermarked_image.png', image_array)
print('数字水印嵌入成功!')
# 提取数字水印
def extract_watermark(image_path, key):
# 读取嵌入了数字水印的图像
image_array = io.imread(image_path)
# 提取数字水印
watermark_size = 16
ciphertext = np.packbits(image_array[:watermark_size, :watermark_size] & 1, axis=-1).reshape((watermark_size,))
cipher = AES.new(key.encode(), AES.MODE_EAX, nonce=ciphertext[:8])
watermark_bin = cipher.decrypt(ciphertext[8:])
# 解密数字水印
plaintext = binascii.unhexlify(watermark_bin.decode('utf-8'))
print('提取的数字水印为:', plaintext)
# 测试
key = '1234567890123456'
watermark = 'Hello, world!'
embed_watermark('test_image.png', watermark, key)
extract_watermark('watermarked_image.png', key)
```
在上述代码中,我们使用了AES算法对数字水印进行加密和解密,用DWT离散小波变换将数字水印嵌入到LL分量中,使用Pillow、numpy、scikit-image等第三方库读取和保存图像,提取数字水印时,需要注意提取的密文前8个字节是随机数,用于初始化AES算法。
阅读全文