基于python的数字图像水印抗攻击
时间: 2023-05-13 09:02:40 浏览: 272
数字图像水印是在数字图像中嵌入信息以证明其真实性或归属权的一种技术。然而,数字图像水印也容易受到攻击,如剪切、旋转、噪声等。为了实现数字图像水印的抗攻击,可以采用基于Python的数字图像水印抗攻击技术。
基于Python的数字图像水印抗攻击技术主要包括以下几个方面:
1. 基于离散小波变换(Discrete Wavelet Transform,DWT)的数字图像水印技术。该方法将水印信息嵌入到原始图像的低频分量中,以保证水印在不影响图像质量的情况下尽可能难以被攻击者检测到。
2. 基于人眼视觉的数字图像水印技术。该方法是根据人眼对图像的不同感知特征来设计数学模型,并将水印嵌入到图像的不同层级的细节信息中。这样,攻击者很难检测到水印信息,同时保持图像的清晰度和鲁棒性。
3. 基于盲水印技术的数字图像水印技术。该方法是指不需要原始图像的图像信息就可以提取出水印信息,从而降低了攻击者获取水印信息的可能性。该技术通常采用一些特殊的加密算法,如数字签名和公共密钥密码体制,来保证水印的秘密性和完整性。
总之,基于Python的数字图像水印抗攻击技术有很多种方法,选择哪种方法取决于具体的应用场景和安全要求。无论使用哪种方法,都需要在不影响图像质量的情况下尽可能增强数字图像水印的抗攻击性,以保证数字图像水印的有效性。
相关问题
带有高斯噪声攻击、椒盐噪声攻击、旋转攻击的基于DWT的数字图像信息隐藏算法代码,载体图像和水印图像进行灰度变换,用python实现
以下是基于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()
```
运行以上代码后,会将四幅图像展示在一个窗口中。
基于DWT的数字图像信息隐藏算法,带有高斯噪声攻击,可以运行,载体图像和水印图像经过灰度处理,用python实现
数字图像信息隐藏算法是一种将机密信息嵌入载体图像中的技术,使得这些信息不可察觉。其中,DWT(离散小波变换)是一种广泛用于数字信号和图像处理的技术,它可以将信号或图像分解成多个频带,其中低频部分代表图像的主要信息,高频部分则代表细节信息。因此,利用DWT进行信息隐藏可以保证被嵌入的信息不会影响到载体图像的主要信息。
以下是基于DWT的数字图像信息隐藏算法的python代码实现:
```python
import numpy as np
import cv2
def embed(img, watermark, alpha):
# 对载体图像和水印图像进行DWT分解
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2GRAY)
LL_img, (LH_img, HL_img, HH_img) = cv2.dwt2(img, 'haar')
LL_wm, (LH_wm, HL_wm, HH_wm) = cv2.dwt2(watermark, 'haar')
# 对水印图像进行归一化
LH_wm = np.asarray(LH_wm, dtype=np.float32) / 255
HL_wm = np.asarray(HL_wm, dtype=np.float32) / 255
HH_wm = np.asarray(HH_wm, dtype=np.float32) / 255
# 将水印图像嵌入载体图像的高频分量
LH_img = np.asarray(LH_img, dtype=np.float32)
LH_img = LH_img + alpha * LH_wm
LH_img = np.asarray(np.clip(LH_img, 0, 255), dtype=np.uint8)
HL_img = np.asarray(HL_img, dtype=np.float32)
HL_img = HL_img + alpha * HL_wm
HL_img = np.asarray(np.clip(HL_img, 0, 255), dtype=np.uint8)
HH_img = np.asarray(HH_img, dtype=np.float32)
HH_img = HH_img + alpha * HH_wm
HH_img = np.asarray(np.clip(HH_img, 0, 255), dtype=np.uint8)
# 重构图像
embedded = cv2.idwt2((LL_img, (LH_img, HL_img, HH_img)), 'haar')
return embedded
def extract(img, watermark_shape, alpha):
# 对载体图像进行DWT分解
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
LL_img, (LH_img, HL_img, HH_img) = cv2.dwt2(img, 'haar')
# 从载体图像的高频分量中提取水印图像
LH_wm = (LH_img - LH_img.mean()) / alpha
LH_wm = np.clip(LH_wm, 0, 1)
LH_wm = cv2.resize(LH_wm, watermark_shape[::-1])
HL_wm = (HL_img - HL_img.mean()) / alpha
HL_wm = np.clip(HL_wm, 0, 1)
HL_wm = cv2.resize(HL_wm, watermark_shape[::-1])
HH_wm = (HH_img - HH_img.mean()) / alpha
HH_wm = np.clip(HH_wm, 0, 1)
HH_wm = cv2.resize(HH_wm, watermark_shape[::-1])
# 重构水印图像
watermark = cv2.idwt2((None, (LH_wm, HL_wm, HH_wm)), 'haar')
watermark = np.asarray(np.clip(watermark, 0, 255), dtype=np.uint8)
return watermark
```
在上述代码中,`embed`函数用于将水印图像嵌入载体图像中,`extract`函数用于从载体图像中提取水印图像。其中,`alpha`参数控制水印图像的嵌入强度,`watermark_shape`参数指定水印图像的大小。
为了模拟高斯噪声攻击,可以使用以下代码向载体图像添加高斯噪声:
```python
def add_noise(img, mean, std):
noise = np.random.normal(mean, std, img.shape)
noisy_img = img.astype(np.float32) + noise
noisy_img = np.asarray(np.clip(noisy_img, 0, 255), dtype=np.uint8)
return noisy_img
```
在上述代码中,`mean`和`std`参数分别指定高斯噪声的均值和标准差。
完整的代码如下:
```python
import numpy as np
import cv2
def embed(img, watermark, alpha):
# 对载体图像和水印图像进行DWT分解
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2GRAY)
LL_img, (LH_img, HL_img, HH_img) = cv2.dwt2(img, 'haar')
LL_wm, (LH_wm, HL_wm, HH_wm) = cv2.dwt2(watermark, 'haar')
# 对水印图像进行归一化
LH_wm = np.asarray(LH_wm, dtype=np.float32) / 255
HL_wm = np.asarray(HL_wm, dtype=np.float32) / 255
HH_wm = np.asarray(HH_wm, dtype=np.float32) / 255
# 将水印图像嵌入载体图像的高频分量
LH_img = np.asarray(LH_img, dtype=np.float32)
LH_img = LH_img + alpha * LH_wm
LH_img = np.asarray(np.clip(LH_img, 0, 255), dtype=np.uint8)
HL_img = np.asarray(HL_img, dtype=np.float32)
HL_img = HL_img + alpha * HL_wm
HL_img = np.asarray(np.clip(HL_img, 0, 255), dtype=np.uint8)
HH_img = np.asarray(HH_img, dtype=np.float32)
HH_img = HH_img + alpha * HH_wm
HH_img = np.asarray(np.clip(HH_img, 0, 255), dtype=np.uint8)
# 重构图像
embedded = cv2.idwt2((LL_img, (LH_img, HL_img, HH_img)), 'haar')
return embedded
def extract(img, watermark_shape, alpha):
# 对载体图像进行DWT分解
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
LL_img, (LH_img, HL_img, HH_img) = cv2.dwt2(img, 'haar')
# 从载体图像的高频分量中提取水印图像
LH_wm = (LH_img - LH_img.mean()) / alpha
LH_wm = np.clip(LH_wm, 0, 1)
LH_wm = cv2.resize(LH_wm, watermark_shape[::-1])
HL_wm = (HL_img - HL_img.mean()) / alpha
HL_wm = np.clip(HL_wm, 0, 1)
HL_wm = cv2.resize(HL_wm, watermark_shape[::-1])
HH_wm = (HH_img - HH_img.mean()) / alpha
HH_wm = np.clip(HH_wm, 0, 1)
HH_wm = cv2.resize(HH_wm, watermark_shape[::-1])
# 重构水印图像
watermark = cv2.idwt2((None, (LH_wm, HL_wm, HH_wm)), 'haar')
watermark = np.asarray(np.clip(watermark, 0, 255), dtype=np.uint8)
return watermark
def add_noise(img, mean, std):
noise = np.random.normal(mean, std, img.shape)
noisy_img = img.astype(np.float32) + noise
noisy_img = np.asarray(np.clip(noisy_img, 0, 255), dtype=np.uint8)
return noisy_img
# 载入图像和水印图像
img = cv2.imread('carrier.png')
watermark = cv2.imread('watermark.png')
# 添加高斯噪声
noisy_img = add_noise(img, 0, 20)
# 嵌入水印
alpha = 0.1
embedded = embed(noisy_img, watermark, alpha)
# 提取水印
extracted = extract(embedded, watermark.shape[:2], alpha)
# 显示图像和水印
cv2.imshow('Original Image', img)
cv2.imshow('Noisy Image', noisy_img)
cv2.imshow('Embedded Image', embedded)
cv2.imshow('Extracted Watermark', extracted)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在上述代码中,载体图像和水印图像分别为`carrier.png`和`watermark.png`,高斯噪声的均值为0,标准差为20。可以调整`alpha`参数来控制水印图像的嵌入强度。运行代码后,可以看到原始图像、添加高斯噪声后的图像、嵌入水印后的图像以及从嵌入后的图像中提取出的水印图像。
阅读全文