1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| import cv2 import numpy as np import matplotlib.pyplot as plt
def svd_watermark_embed(original_img, watermark, alpha=16): """ SVD水印嵌入算法 :param original_img: 原始图像(灰度) :param watermark: 水印矩阵(与图像同尺寸) :param alpha: 水印强度系数 :return: 含水印图像,嵌入用的U_w, S_w, Vh_w """ U, S, Vh = np.linalg.svd(original_img, full_matrices=False) S_diag = np.diag(S)
watermarked_S = S_diag + alpha * watermark
U_w, S_w, Vh_w = np.linalg.svd(watermarked_S, full_matrices=False) S_w_diag = np.diag(S_w)
watermarked_img = U @ S_w_diag @ Vh
return np.clip(watermarked_img, 0, 255).astype(np.uint8), (U_w, S, Vh_w)
def svd_watermark_extract(watermarked_img, U_w, Vh_w, original_S, alpha=16): """ SVD水印提取算法 :param watermarked_img: 含水印图像 :param U_w: 嵌入时生成的U_w :param Vh_w: 嵌入时生成的Vh_w :param original_S: 原始图像的奇异值矩阵 :param alpha: 水印强度系数 :return: 提取的水印 """ U_wm, S_wm, Vh_wm = np.linalg.svd(watermarked_img, full_matrices=False)
D_w = U_w @ np.diag(S_wm) @ Vh_w
extracted_watermark = (D_w - np.diag(original_S)) / alpha
return extracted_watermark
def watermark_padding(logo, target_size): logo = (logo.astype(np.float32) - 128) / 128 target_size = min(original.shape) top = 0 bottom = target_size - logo.shape[0] left = 0 right = target_size - logo.shape[1] padding_logo = cv2.copyMakeBorder(logo, top, bottom, left, right, cv2.BORDER_CONSTANT, value=0) return padding_logo
def watermark_resize(logo): logo = (logo.astype(np.float32) - 128) / 128 resize_logo = cv2.resize(logo, (min(original.shape), min(original.shape))) return resize_logo
if __name__ == "__main__": original = cv2.imread('img/lena.bmp', cv2.IMREAD_GRAYSCALE)
raw_logo = cv2.imread('img/key_100.png', cv2.IMREAD_GRAYSCALE) logo = watermark_padding(raw_logo, min(original.shape))
watermarked_img, (U_w, S_orig, Vh_w) = svd_watermark_embed(original, logo)
extracted_watermark = svd_watermark_extract(watermarked_img, U_w, Vh_w, S_orig)[:100, :100]
correlation = np.corrcoef(raw_logo.flatten(), extracted_watermark.flatten())[0, 1]
plt.figure(figsize=(10, 5))
plt.subplot(2, 2, 1), plt.imshow(original, cmap='gray') plt.title('Original Image'), plt.axis('off')
plt.subplot(2, 2, 2), plt.imshow(watermarked_img, cmap='gray') plt.title('Watermarked Image'), plt.axis('off')
plt.subplot(2, 2, 3), plt.imshow(raw_logo, cmap='gray') plt.title('Original Watermark'), plt.axis('off')
plt.subplot(2, 2, 4), plt.imshow(extracted_watermark, cmap='gray', vmin=-1, vmax=1) plt.title(f'Extracted Watermark\nCorrelation: {correlation:.4f}'), plt.axis('off')
plt.tight_layout() plt.show()
|