基于LSB与量化处理的盲提取实现
水印实现的思路为:
先将水印图像W二值化,当水印图像W=255时,若载体图像I对应位像素值为奇数,则I对应位值不变,若为偶数,I对应位值加一;当水印图像W=0时,若载体图像I对应位像素值为偶数,则I对应位值不变,若为奇数,I对应位值减一。
提取时只要判断对应位像素值的奇偶性,二值化赋值就可以提取出水印。
二值化
import cv2 from PIL import Image import numpy as np Img_path = 'C:\\User\\logo.bmp' Img = Image.open(Img_path) Img = Img.convert('L') # 设定阈值 threshold = 180 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(255) waterImg = Img.point(table, '1') waterImg.save('C:\\Users\\2value.bmp')
为确保健壮性,后面的代码仍采用了阈值进行判断,而非0,255二值
水印嵌入部分
import cv2 import numpy as np from PIL import Image Img_path = 'C:\\Users\\20_2.bmp' # 载体图像 waterImg_path = 'C:\\Users\\2value.bmp' # 水印图像 Img = cv2.imread(Img_path) waterImg = cv2.imread(waterImg_path, 0) H = Img.shape[0] W = Img.shape[1] Img = cv2.resize(Img, (W, H)) waterImg = cv2.resize(waterImg, (W, H)) b = np.zeros((H, W), dtype=Img.dtype) g = np.zeros((H, W), dtype=Img.dtype) r = np.zeros((H, W), dtype=Img.dtype) Img_new = np.zeros((H, W), dtype=Img.dtype) b[:, :] = Img[:, :, 0] g[:, :] = Img[:, :, 1] r[:, :] = Img[:, :, 2] for h in range(H): for w in range(W): if int(waterImg[h, w]) >= 180 and int(r[h, w]) % 2 == 0: Img_new[h, w] = int(r[h, w]) + 1 elif int(waterImg[h, w]) < 180 and int(r[h, w]) % 2 == 1: Img_new[h, w] = int(r[h, w]) - 1 else: Img_new[h, w] = int(r[h, w]) watermarkedImg = cv2.merge([Img_new, g, b]) watermarkedImg = Image.fromarray(watermarkedImg) watermarkedImg = watermarkedImg.resize((W, H), Image.ANTIALIAS) watermarkedImg.save('C:\\Users\\2value_new.bmp')
水印提取部分
import cv2 import numpy as np from PIL import Image extract_path = 'C:\\Users\\2value_new.bmp' extract = cv2.imread(extract_path) H = extract.shape[0] W = extract.shape[1] B = np.zeros((H, W), dtype=extract.dtype) G = np.zeros((H, W), dtype=extract.dtype) R = np.zeros((H, W), dtype=extract.dtype) extract_new = np.zeros((H, W), dtype=extract.dtype) B[:, :] = extract[:, :, 0] G[:, :] = extract[:, :, 1] R[:, :] = extract[:, :, 2] for h in range(H): for w in range(W): if int(R[h, w]) % 2 == 0: extract_new[h, w] = 0 elif int(R[h, w]) % 2 == 1: extract_new[h, w] = 255 waterImg = Image.fromarray(extract_new) waterImg = waterImg.resize((100, 100), Image.ANTIALIAS) waterImg.save('C:\\Users\\logonew.bmp')
最终结果
提取结果也没有问题。