今天为大家介绍一种常见的可逆图像加密算法,学会这个算法,你可以自己实现在不对载体图像造成永久性破坏的前提下,对图像进行信息嵌入与信息提取。
基础知识
首先要为大家介绍的是数字灰度图像(也就是黑白图像)的存储原理
1.灰度值
灰度值,顾名思义,它是描述一个物体颜色有多“灰”的指标,它的取值区间是[0,255]。
当灰度值为0的时候,这个物体就是纯黑色;当灰度值为255时,这个物体就是白色;当灰度值在0到255之间时,这个物体就是介于黑白之间的灰色,并且灰度值越大,灰度越浅,越接近白色,灰度值越小,灰度越深,越接近黑色。
2.灰度图像
如上图所示,可以看到,一个灰度图像是由一个个灰度像素点排列堆叠组合而成的。这个灰度图像在底层的存储其实是由一个灰度矩阵来实现的,灰度矩阵的为一个位置的值,就代表着这个位置的像素点的灰度值。
这是一个512*512的灰度矩阵,每一个位置的元素值都代表着这个位置处像素点的灰度值。
PVO算法理论介绍
接下来,我会为大家介绍对一个图像具体的信息加密解密过程,这个算法不会很复杂,大家来跟着我一步一步做就好,就像把大象放进冰箱的算法,无非是1)把打开冰箱门,2)把大象放进去,3)关上冰箱门,这三部而已
1)将图片切块
首先,将大的完整灰度图像切割为固定尺寸的小块,接下来,我们对每一个小块依次进行处理(下面是对图像分块的示意图,实际的分块尺寸会比示意图更小)
2)对每一个分块进行处理
我们拿到一个图像分块后(一个灰度矩阵),首先对矩阵中的像素按照灰度值大小进行降序排序,以下图为例
我们不妨将上述排序前的四个像素点记为x1(199),x2(200),x3(89),x4(153),则排序后的结果为x2>x1>x4>x3
然后我们需要引入一个中间算子(专业叫法是预测误差),记作emax,它的定义如下:
其中,xσ(n)表示的是一个图像块中灰度值最大的像素点,xσ(n-1)表示一个图像块中灰度值第二大的像素点(以此类推),emax就是用来记录每一个图像块中最大像素点与第二大像素点的灰度值差值的。
在上述准备工作完成后,我们就可以进行正式的图像加密工作了,我们对每一个图像块中灰度值最大的像素点进行如下修改操作:
公式中的b是指嵌入的一位二进制信息,b可以是0或1
这个嵌入方式很简单:
如果原图像块中的emax是0,就把图像块中灰度值最大的像素点+0
如果原图像块中的emax是1,就把图像块中灰度值最大的像素点+b
如果原图像块中的emax大于1,就把图像块中灰度值最大的像素点+1
不难发现,在对图像块中灰度值最大的像素点进行修改操作后,它依然是这个图像块中灰度值最大的像素点,也就是说,我们的修改不会改变图像块中原有的像素灰度值排序,以上面的案例为例,修改后的图像块灰度矩阵是这样的(嵌入信息b=1),像素点的灰度排序依旧还是x2>x1>x4>x3:
下面我们来分析规律,我们对图像灰度值最大的像素点的修改,本质上是构造了一个一对一的可逆映射:
如果我们拿到一个加密后的灰度矩阵,我们首先对矩阵内的元素按灰度值进行降序排序,然后计算新的预测误差emax2(在公式里记作emax撇,这个小撇在这里打不出来)
如果新的emax2是0,说明原来的emax就是0,(没有信息嵌入)
如果新的emax2是1,那么说明原来的emax是1,嵌入的信息b是0
如果新的emax2是2,那么说明原来的emax是1,嵌入的信息b是1
如果新的emax2是 3,4,5,6,7…,那么说明原来的emax分别是2,3,4,5,6…(没有信息嵌入)
利用上述规律,我们就可以对图像块中的加密信息进行提取了。
我们将一个图像中所有图像块提取出的信息汇总在一起,就可以得到一串二进制序列了
我们将这个二进制序列以特定的方式进行解码(比如ASCll码),就可以得到加密文字信息了
3)图像的无损恢复
对照着上述公式
如果新的emax2是0,说明原来的emax就是0,
说明我们之前对灰度值最大的像素点进行的操作是+0,
那么对现在的灰度值最大的像素点进行-0就可以了(相当于不用变化)
如果新的emax2是1,说明原来的emax是1,嵌入的信息b是0
说明我们之前对灰度值最大的像素点进行的操作是+b,
那么对现在的灰度值最大的像素点进行-b就可以了
如果新的emax2是2,说明原来的emax是1,嵌入的信息b是1
说明我们之前对灰度值最大的像素点进行的操作是+b,
那么对现在的灰度值最大的像素点进行-b就可以了
如果新的emax2是一个大于2的数,说明原来的emax是emax2-1,
说明我们之前对灰度值最大的像素点进行的操作是+1,
那么对现在的灰度值最大的像素点进行-1就可以了
PS:关于最大嵌入量
1.单次嵌入量的理论最大值是图像块的数量,所以对一张图像分块时尽量多分,但也不要分得太多
2.因为我们的图像在加密后依然是一张图像(听起来像废话),所以我们仍然可以把加密一次的图像再丢进我们的算法,实现二次信息嵌入,加密两次后的图像依然是一张图像…(无限套娃),直到算法达到极限,找不到emax为1的图像块了,那么此时的已嵌入量就是最大嵌入量了
实验代码
Frank-Sen/Common-Reversible-Data-hiding-Methods-for-Image (github.com)