带有高斯噪声攻击、椒盐噪声攻击、旋转攻击的基于DWT的数字图像信息隐藏算法代码,载体图像和水印图像进行灰度变换,用python实现
时间: 2023-06-18 12:04:48 浏览: 197
基于DWT-HD-SVD混合技术的数字图像水印方法测试了jpeg压缩,高斯滤波,中值滤波,高斯噪声,图像变形等attack测试
以下是基于DWT的数字图像信息隐藏算法代码,包括高斯噪声攻击、椒盐噪声攻击、旋转攻击,用Python实现。
```python
import cv2
import numpy as np
from matplotlib import pyplot as plt
import math
# 将灰度图像转换为二进制序列
def gray2bin(gray_img):
bin_img = ''
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
bin_img += '{0:08b}'.format(gray_img[i][j])
return bin_img
# 将二进制序列转换为灰度图像
def bin2gray(bin_str, row, col):
bin_len = row * col * 8
if len(bin_str) != bin_len:
return None
bin_arr = np.array(list(bin_str), dtype=np.uint8).reshape((row, col, 8))
gray_arr = np.packbits(bin_arr, axis=2).reshape((row, col))
return gray_arr
# 将灰度图像转换为水印序列
def gray2watermark(gray_img):
bin_img = gray2bin(gray_img)
watermark = ''
for i in range(0, len(bin_img), 2):
if bin_img[i] == '1' and bin_img[i+1] == '0':
watermark += '1'
else:
watermark += '0'
return watermark
# 将水印序列转换为灰度图像
def watermark2gray(watermark_str, row, col):
bin_img = ''
for i in range(0, len(watermark_str)):
if watermark_str[i] == '1':
bin_img += '10'
else:
bin_img += '00'
gray_img = bin2gray(bin_img, row, col)
return gray_img
# 将灰度图像的每个像素值加上指定的值,避免DWT变换后出现0值
def add_salt(gray_img, salt):
salt_img = gray_img.astype(np.int16)
salt_img += salt
salt_img[salt_img < 0] = 0
salt_img[salt_img > 255] = 255
return salt_img.astype(np.uint8)
# 对灰度图像进行DWT变换
def dwt2(gray_img):
coeffs = pywt.dwt2(gray_img, 'haar')
LL, (LH, HL, HH) = coeffs
return LL, LH, HL, HH
# 对DWT系数进行量化和修改,实现信息隐藏
def embed(LL, LH, HL, HH, watermark, alpha):
LL = LL.astype(np.float)
LH = LH.astype(np.float)
HL = HL.astype(np.float)
HH = HH.astype(np.float)
LL_shape = LL.shape
watermark_len = len(watermark)
for i in range(LL_shape[0]):
for j in range(LL_shape[1]):
if i*LL_shape[1]+j < watermark_len:
if watermark[i*LL_shape[1]+j] == '1':
LL[i][j] += alpha
else:
LL[i][j] -= alpha
LH[i][j] = round(LH[i][j] / alpha) * alpha
HL[i][j] = round(HL[i][j] / alpha) * alpha
HH[i][j] = round(HH[i][j] / alpha) * alpha
return LL, LH, HL, HH
# 对DWT系数进行逆变换,得到修改后的灰度图像
def idwt2(LL, LH, HL, HH):
coeffs = LL, (LH, HL, HH)
img = pywt.idwt2(coeffs, 'haar')
return img.astype(np.uint8)
# 对灰度图像进行加高斯噪声攻击
def add_gaussian_noise(gray_img, mean=0, std=15):
noise = np.random.normal(mean, std, gray_img.shape)
noisy_img = gray_img.astype(np.int16)
noisy_img += noise.astype(np.int16)
noisy_img[noisy_img < 0] = 0
noisy_img[noisy_img > 255] = 255
return noisy_img.astype(np.uint8)
# 对灰度图像进行加椒盐噪声攻击
def add_salt_pepper_noise(gray_img, prob=0.05):
noise = np.random.rand(*gray_img.shape)
noisy_img = gray_img.copy()
noisy_img[noise < prob/2] = 0
noisy_img[noise > 1-prob/2] = 255
return noisy_img
# 对灰度图像进行旋转攻击
def rotate_img(gray_img, angle):
# 对图像进行旋转
rows, cols = gray_img.shape
M = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1)
rotated_img = cv2.warpAffine(gray_img,M,(cols,rows))
# 对旋转后的图像进行裁剪,避免黑边的影响
height, width = rotated_img.shape
left = int((width - cols) / 2)
right = int((width + cols) / 2)
top = int((height - rows) / 2)
bottom = int((height + rows) / 2)
rotated_img = rotated_img[top:bottom, left:right]
return rotated_img
# 读取载体图像和水印图像
carrier_img = cv2.imread('carrier.png', cv2.IMREAD_GRAYSCALE)
watermark_img = cv2.imread('watermark.png', cv2.IMREAD_GRAYSCALE)
# 将灰度值减去128,避免DWT变换后出现负值
carrier_img = add_salt(carrier_img, -128)
# 将水印图像转换为水印序列
watermark = gray2watermark(watermark_img)
# 对载体图像进行DWT变换,得到DWT系数
LL, LH, HL, HH = dwt2(carrier_img)
# 将水印信息嵌入DWT系数中,得到修改后的DWT系数
alpha = 15
LL_new, LH_new, HL_new, HH_new = embed(LL, LH, HL, HH, watermark, alpha)
# 对修改后的DWT系数进行逆变换,得到修改后的灰度图像
carrier_img_new = idwt2(LL_new, LH_new, HL_new, HH_new)
# 将灰度值加上128,得到最终的灰度图像
carrier_img_new = add_salt(carrier_img_new, 128)
# 对最终的灰度图像进行高斯噪声攻击
carrier_img_noisy = add_gaussian_noise(carrier_img_new)
# 对最终的灰度图像进行椒盐噪声攻击
carrier_img_noisy = add_salt_pepper_noise(carrier_img_new)
# 对最终的灰度图像进行旋转攻击
carrier_img_noisy = rotate_img(carrier_img_new, 30)
# 将嵌入水印的灰度图像、加高斯噪声攻击的灰度图像、加椒盐噪声攻击的灰度图像、旋转攻击后的灰度图像保存为文件
cv2.imwrite('carrier_new.png', carrier_img_new)
cv2.imwrite('carrier_noisy.png', carrier_img_noisy)
cv2.imwrite('carrier_salt_pepper.png', carrier_img_noisy)
cv2.imwrite('carrier_rotated.png', carrier_img_noisy)
```
其中,载体图像和水印图像可以任意选择,需要将两幅图像放在代码所在目录下,并分别命名为`carrier.png`和`watermark.png`。
以上代码中用到了`pywt`库,需要先安装该库,可以使用以下命令进行安装:
```
pip install pywavelets
```
运行以上代码后,会生成以下四幅图像:
- carrier_new.png:嵌入水印的灰度图像
- carrier_noisy.png:加高斯噪声攻击后的灰度图像
- carrier_salt_pepper.png:加椒盐噪声攻击后的灰度图像
- carrier_rotated.png:旋转攻击后的灰度图像
可以通过以下代码进行展示:
```python
# 读取四幅图像进行展示
carrier_img = cv2.imread('carrier.png', cv2.IMREAD_GRAYSCALE)
carrier_img_new = cv2.imread('carrier_new.png', cv2.IMREAD_GRAYSCALE)
carrier_img_noisy = cv2.imread('carrier_noisy.png', cv2.IMREAD_GRAYSCALE)
carrier_img_salt_pepper = cv2.imread('carrier_salt_pepper.png', cv2.IMREAD_GRAYSCALE)
carrier_img_rotated = cv2.imread('carrier_rotated.png', cv2.IMREAD_GRAYSCALE)
watermark_img = cv2.imread('watermark.png', cv2.IMREAD_GRAYSCALE)
# 显示图像
plt.figure(figsize=(10,10))
plt.subplot(2, 3, 1)
plt.imshow(carrier_img, cmap='gray')
plt.title('Carrier Image')
plt.subplot(2, 3, 2)
plt.imshow(watermark_img, cmap='gray')
plt.title('Watermark Image')
plt.subplot(2, 3, 3)
plt.imshow(carrier_img_new, cmap='gray')
plt.title('Embedded Image')
plt.subplot(2, 3, 4)
plt.imshow(carrier_img_noisy, cmap='gray')
plt.title('Noisy Image')
plt.subplot(2, 3, 5)
plt.imshow(carrier_img_salt_pepper, cmap='gray')
plt.title('Salt and Pepper Image')
plt.subplot(2, 3, 6)
plt.imshow(carrier_img_rotated, cmap='gray')
plt.title('Rotated Image')
plt.show()
```
运行以上代码后,会将四幅图像展示在一个窗口中。
阅读全文