LSB Least Significant Bit 最低有效位嵌入,这里就不赘述了。很多参考,原理一搜就出来了。
下面是相应的代码
首先,编写encode 和decode 代码,使用位操作
def LSB_encode(cover, m, k):
m = np.array(m, dtype = np.uint8)
cover = np.array(cover, dtype = np.uint8)
k = 2**k -1
mask1 = 255-k
mask2 = k
cover = np.bitwise_and(cover, mask1)
m = np.bitwise_and(m, mask2)
res = np.bitwise_or(cover,m)
return res
def LSB_decode(cover, k):
cover = np.array(cover, dtype = np.uint8)
mask1 = 2**k -1
m = np.bitwise_and(cover, mask1)
res = np.zeros(k, dtype = np.uint8)
m = str(bin(m))
m = m[2:].zfill(k)
for i in range(k):
res[i] = int(m[i])
return res
然后是嵌入和提取水印的代码:
def LSB_embed(im, wm, k):
xsize,ysize = im.shape
num = xsize * ysize
wm = wm.flatten() // 255
im_array = np.array(im)
im_array = im_array.reshape(num)
for i in range(num):
m = int("".join(list(map(str, wm[i:i+k]))),2)
im_array[i] = LSB_encode(im_array[i], m, k)
im_wm = im_array.reshape(xsize,ysize)
return im_wm
def LSB_extract(im, k):
xsize,ysize = im.shape
num = xsize * ysize
im_array = np.array(im)
im_array = im_array.reshape(num)
wm_ex = np.zeros(num*k, dtype= np.uint8)
for i in range(num):
m = LSB_decode(im_array[i], k)
wm_ex[i:i+k] = m
wm_ex = wm_ex.reshape(xsize,ysize,-1)
wm_ex = wm_ex.squeeze()
return wm_ex
最后是主函数,这里为了方便展示效果,将 嵌入的最低位数 K设为1。如果k不是1,嵌入和提取函数还要有稍微的改动。
import numpy as np
from PIL import Image
from skimage import data
import matplotlib.pyplot as plt
wm = Image.open('watermark.png')
wm = np.array(wm)
im = data.camera()
k = 1
# wm = np.random.randint(0,2, (im.shape[0],im.shape[1],k), dtype = np.uint8).squeeze()
im_wm = LSB_embed(im, wm, k)
wm_ex = LSB_extract(im_wm, k)
fig, (ax_wm, ax_im, ax_im_wm, ax_wm_ex)=plt.subplots(nrows = 1,ncols = 4, figsize = [20,20])
ax_wm.imshow(wm, cmap = plt.cm.gray)
ax_wm.set_xlabel('wm')
ax_im.imshow(im, cmap = plt.cm.gray)
ax_im.set_xlabel('im')
ax_im_wm.imshow(im_wm, cmap = plt.cm.gray)
ax_im_wm.set_xlabel('im_wm')
ax_wm_ex.imshow(wm_ex, cmap = plt.cm.gray)
ax_wm_ex.set_xlabel('wm_ex')
下面是效果图:
另外,这里给出为彩色图像加 K=3 随机信息的代码:
### color LSB watermark
k = 3
im = Image.open("lena.png")
im = np.array(im)
r,g,b = im[:,:,0],im[:,:,1],im[:,:,2]
np.random.seed(0)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
r_wm = LSB_embed(r, wm, k)
np.random.seed(1)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
g_wm = LSB_embed(g, wm, k)
np.random.seed(2)
wm = np.random.randint(0,2, im.shape[0]*im.shape[1]*k, dtype = np.uint8)
b_wm = LSB_embed(b, wm, k)
im_wm = np.dstack((r_wm, g_wm, b_wm))
fig, ( ax_im, ax_im_wm, )=plt.subplots(nrows = 1,ncols = 2, figsize = [20,20])
ax_im.imshow(im, cmap = plt.cm.gray)
ax_im.set_xlabel('im')
ax_im_wm.imshow(im_wm, cmap = plt.cm.gray)
ax_im_wm.set_xlabel('im_wm')
运行结果如下所示: