数字水印技术:LSB加密详解(附python代码)

概要

数字水印是一种将标识信息嵌入到载体当中,且不影响载体使用的一种技术,主要分为时域水印嵌入算法(将水印嵌入到时域采样数据中)和变换域水印嵌入算法(先对音频做变换,将水印嵌入到变换域系数中)。本文主要介绍的是时域水印嵌入算法—LSB算法。

LSB算法原理

基于不可感知的要求,即数据的变化几乎不会引起使用的者的察觉,将水印信息嵌入到数据的最低有效位(Least Significant Bit),也就是将图片的RGB数值转换为二进制数据,然后用水印替换掉最低位,这种变化对于人眼来说是不可察觉的。当然,水印的形式也是多种多样的,有图片,文字等,这里主要介绍如何把图片作为水印写入到另一张图片中。

注意事项

  • LSB隐写(最低有效位的隐写),是指通过改变图片中像素的最低位来实现信息的隐藏的。这种隐写方式需要图片是无压缩的位图,因此一般用于bmp和png图片。
  • 本文采用python代码实现,下面是需要预先安装的包
    from PIL import Image

加密过程

假设载体图片和水印图片分别是这样的:
在这里插入图片描述
在这里插入图片描述

  • 获取图片
img1 = Image.open('1.bmp')
img2 = Image.open('2.bmp')
rgb_im1 = img1.convert('RGB')
rgb_im2 = img2.convert('RGB')

除了获取图片外,还要将图片变为RGB通道模式,否则后面是获取不到RGB值的,其中1.bmp是载体图片,2.bmp是水印图片。

  • 获取水印图片每个像素的RGB值
    for i in range(img.size[0]):
        for j in range(img.size[1]):

            # 获取水印的每个像素值
            rgb = img.getpixel((i, j))

采用循环遍历水印图片,获取每个像素的RGB值,可以将值输出来看一下
在这里插入图片描述
可以看到,获取到的RGB值是以元组的方式存储的。

  • 将RGB值转为二进制形式
# 将像素值转为二进制后保存
str = str + plus(bin(rgb[0]).replace('0b', ''))
str = str + plus(bin(rgb[1]).replace('0b', ''))
str = str + plus(bin(rgb[2]).replace('0b', ''))

其中bin是python的进制转换函数,能将十进制转换为二进制,唯一不足的就是会自动在转换的数字前面加0b,因此以空字符串替换掉0b。
此外,十进制转换二进制的时候,如果转换的二进制是以0开头的,那么会自动省略前方的0,这不符合我们的要求。因此以255为标准,二进制为1111 1111,其余的不足8位的在最前方补0,如1就是0000 0001。plus函数如下:

def plus(str):
    # 返回指定长度的字符串,原字符串右对齐,前面填充0。
    return str.zfill(8)

这样一转换,水印图片的所有RGB值都被转换为二进制并当做字符串存储在str里了,如下图:
在这里插入图片描述
这里的每一位,都是要替换掉载体图片每一个像素点的R,G,B三个值的二进制形式的末尾数字,因此载体的图片像素点的RGB值会改变,但变化最大不会超过1,主观上无法察觉。

  • 遍历载体图片
    for i in range(img.size[0]):
        for j in range(img.size[1]):
            # 获取到图片的每个像素值
            data = img.getpixel((i, j))

很明显,每次循环,data就会获得一个RGB值,也可以分别保存。

r = data[0]
g = data[1]
b = data[2]
  • 改变像素点的RGB值
    此时,需要两个信号,一个是上面str的长度,来判断此时替换的是str的哪一位,以及来判断何时替换完毕;另一个是计数器,因为载体图片也有RGB三个数值,每次都需要替换完整的R,G,B三个数值后,才能完成一个像素点的修改,也就是说,str里的3位数字分别替换载体图片一个像素点的R,G,B的最后一位,此时该像素点修改完毕。当计数器数值等于str的长度时,代表水印完全写入载体。
# 计数器
count = 0
# 二进制像素值的长度,可以认为要写入图像的文本长度,提取(解密)时也需要此变量
codeLen = len(code)
print(codeLen)
if count == codeLen:
	break
	
	"""
	下面的是像素值替换,通过取模2得到最后一位像素值(0或1),
	然后减去最后一位像素值,在将code的值添加过来
	"""

r = (r 
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值