Python实现图像信息隐藏
之前学习密码学的时候老师有提到过『信息隐藏』,现在用图像的方法尝试一下。思想是:把信息藏到RGB通道中的B通道,然后利用奇偶性可以恢复过来
原理
- 从源图中提取文字图像信息,记录这个文字图像信息像素点在图像矩阵中的位置
- 对载体图片进行预处理,将B通道的像素值全部设置成偶数
- 把载体图片中,把第一步已经记录的位置的像素B通道设置为奇数
- 信息解码的过程就是逆过程,只要找出载体图片中B通道是奇数的像素位置,然后统一着色就可以恢复
实现
一、写入要隐藏的信息
source = cv2.imread('img/source.png')
h, w = source.shape[:2]
message = 'Hello World!'
x, y = (180, 250)
color = [88, 26, 16]
cv2.putText(source, message, (x, y), cv2.QT_FONT_BLACK, 3, color, thickness=5)
cv2.imwrite('img/s.png', source)
原图source.png
加入信息后的图片s.png
二、预处理载体图片
carrier = cv2.imread('img/carrier.png')
for i in xrange(h):
for j in xrange(w):
# 把整幅图的B通道全设置为偶数
if carrier[i, j, 0] % 2 == 1:
carrier[i, j, 0] -= 1
三、把隐藏信息的位置设置成奇数
for i in xrange(h):
for j in xrange(w):
# 找出有文字的位置
if list(source[i, j]) == color:
carrier[i, j, 0] += 1
cv2.imwrite('img/hide.png', carrier)
加入信息之后的载体图片与原来几乎不变
原载体图片carrier.png
隐藏信息后的图片hide.png
四、信息恢复
img = cv2.imread('img/hide.png')
h, w = img.shape[:2]
# 新建一张图用来放解出来的信息
info = np.zeros((h, w, 3), np.uint8)
for i in xrange(h):
for j in xrange(w):
# 发现B通道为奇数则为信息的内容
if img[i, j, 0] % 2 == 1:
info[i, j, 0] = 255
info[i, j, 1] = 255
info[i, j, 2] = 255
cv2.imwrite('img/info.png', info)
恢复结果info.png
小结
这种信息隐藏的方法,主要是用『修改像素奇偶性后,图片变化不明显』来实现的,感觉非常巧妙。
不过值得注意的是,\(隐写术\neq 加密\),这种信息隐藏的安全性也依赖于算法本身,而不是密码学里的『密钥』。