Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm
最低有效位(Least Significant Bit, LSB)指的是一个二进制数中的第0位(即最低位)。最低有效位信息隐藏指的是,将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,即将载体图像的最低有效位层替换为当前需要隐藏的二值图像,从而实现将二值图像隐藏的目的。由于二值图像处于载体图像的最低有效位上,所以对于载体图像的影响非常不明显,其具有较高的隐蔽性。
在必要时直接将载体图像的最低有效位层提取出来,即可得到嵌入在该位上的二值图像,达到提取秘密信息的目的。
这种信息隐藏也被称为数字水印,通过该方式可以实现信息隐藏、版权认证、身份认证等功能。例如,如果嵌入载体图像内的信息是秘密信息,就实现了信息隐藏;如果嵌入载体图像内的信息是版权信息,就能够实现版权认证;如果嵌入载体图像内的信息是身份信息,就可以实现数字签名,等等。所以,被嵌入载体图像内的信息也被称为数字水印信息。
数字水印信息可以是文本、视频、音频等多种形式,这里我们仅讨论数字水印信息是二值图像的情况。
原理
从位平面的角度考虑,数字水印的处理过程分为下面两步。
● 嵌入过程:将载体图像的第0个位平面替换为数字水印信息(一幅二值图像)。
● 提取过程:将载体图像的最低有效位所构成的第0个位平面提取出来,得到数字水印信息。
eg:编写程序,模拟数字水印的嵌入和提取过程。
代码如下:
import cv2
import numpy as np
#读取原始载体图像
lena=cv2.imread("lena.bmp",0)
#读取水印图像
watermark=cv2.imread("watermark.bmp",0)
#将水印内的255处理为1,以方便嵌入
w=watermark[:,:]>0
watermark[w]=1
#读取原始载体图像的shape值
r,c=lena.shape
#============嵌入过程============
#生成内部值都是254的数组
t254=np.ones((r,c),dtype=np.uint8)*254
#获取lena图像的高7位
lenaH7=cv2.bitwise_and(lena,t254)
#将watermark嵌入到lenaH7内
e=cv2.bitwise_or(lenaH7,watermark)
#============提取过程============
#生成内部值都是1的数组
t1=np.ones((r,c),dtype=np.uint8)
#从载体图像内,提取水印图像
wm=cv2.bitwise_and(e,t1)
print(wm)
#将水印内的1处理为255以方便显示
w=wm[:,:]>0
wm[w]=255
#============显示============
cv2.imshow("lena",lena)
cv2.imshow("watermark",watermark*255) #当前watermark内最大值为1
cv2.imshow("e",e)
cv2.imshow("wm",wm)
cv2.waitKey()
cv2.destroyAllWindows()
运行上述程序,结果如下图所示,其中:
● 图( a )是原始图像lena。
● 图( b )是水印图像watermark。在程序中,该图像首先会被处理为二值图像,在显示时将其元素值乘以255,以方便显示。
● 图( c )是在图像lena内嵌入水印图像watermark后得到的含水印载体图像e。
● 图( d )是从含水印载体图像e内提取到的水印图像wm。
从图3-14可以发现,通过肉眼无法观察出含水印载体图像和原始图像的不同,水印的隐蔽性较高。但是,由于该方法过于简单,其安全性并不高,在实际处理中会通过更复杂的方式实现水印的嵌入。