信息隐藏之数字水印

信息隐藏技术因其不可感知的特性一直都有种神秘感。古希腊战争中,为了安全传送军事情报,奴隶主剃光奴隶的头发,将头发缝在其头皮上,待头发长起来后再派出去传送消息,这就是一种信息隐藏,再比如古代的藏头诗、藏尾诗等,都是将隐秘信息用巧妙的方法藏起来使外人无从知晓。对于携带保密信息的载体,其加密技术并不一定多么高明,然而未授权的人看到载体根本不知道保密信息存在与否!这就是信息隐藏的魅力所在。

信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。

现代社会,计算机已经深入到人们生活的方方面面,而在计算机上一切信息都是由0/1数字组成的,文本、图片、音频、视频,在计算机的世界里可以将它们拆解成同样的本元再用各种方法将它们重新组合,因此,这样想来可以玩出许许多多有趣的信息隐藏的伎俩。目前,信息隐藏技术主要的用途在于数字作品的版权保护方面,也就是在数字作品中嵌入代表版权的数字水印,并且这种水印是肉眼不可见的。本文将讲解一种在图片文件中嵌入水印的方法。

图像的表示

世界的一切都是数字组成的

忘记哪位哲人说过这句话,这似乎在揭示数字背后深不可测的涵义,但我不想究其深意,我觉得从描述世界的角度来看,一切事物都是需要用数字来度量的。在计算机的世界中,不存在模糊不存在无穷,所有的东西都是数字来表示和计算。对于一张灰度图片,用分辨率表示图片的长宽,用像素表示其明暗,以二维矩阵的大小度量分辨率,以矩阵元素的值度量像素值,如此,则将一个灰度图像与一个二维矩阵相对应起来。(彩色图片又是怎样的呢?固定大小的矩阵又如何表示无限多的图片呢?

那么接下来就是对这个矩阵中的数字做手脚了,在矩阵中藏进一些新的数字,而使对应的图片与原来的图片看起来一样。

嵌入水印

怎样在一个铁盒中藏下一个铁块?将铁块熔于铁盒。

我们的水印不管是文本还是图片,它都可以提取成一串数字,怎样将这串数字熔于载体图像的那个矩阵中呢?当然了将这串数字与矩阵进行简单的四则运算就可以消失得无影无踪,但我们总要把水印再提取出来的,并且还要求这个图片能抵御压缩、剪切、变换等攻击,这样看来粗暴的『物理反应』并不能达到目的,或许需要来点『化学反应』,对,就像把金属藏于金属化合物一样!

其实,一个图片有两种展现形式,一种是在空间域,就是我们看到的样子,由不同位置深浅不一的点构成,另一种是在频率域,由不同频率的强弱各异的波构成。

就像同一事物用不同的两种语言表达,这里的傅里叶变换充当的就是一种翻译工具而已,也可能,在这种语言里增加一个词对应的意思在另一种语言的表达里可能完全没变,我们要利用的就是这一点!

程序实现与实验

算法实现的思路为,利用分块DCT变换,水印信息按位嵌入一个个DCT系数块,通过调整两个中频DCT系数的相对大小就达到了隐藏一位密文信息的目的。水印的提取只要用逆过程就可完成。

关键代码行:

T=dctmtx(8);
DCTrgb=blkproc(data,[8 8],'P1*x*P2',T,T');
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8);
a=zeros([row col]);
[k1,k2]=randinterval(a,count,key);
for i=1:count
      k1(1,i)=(k1(1,i)-1)*8+1;
    k2(1,i)=(k2(1,i)-1)*8+1;
end
for i=1:count
if msg(i,1)==0
    if DCTrgb(k1(i)+4,k2(i)+1)>DCTrgb(k1(i)+3,k2(i)+2)
        temp=DCTrgb(k1(i)+4,k2(i)+1);
        DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+3,k2(i)+2);
        DCTrgb(k1(i)+3,k2(i)+2)=temp;
    end
else
     if DCTrgb(k1(i)+4,k2(i)+1)<DCTrgb(k1(i)+3,k2(i)+2)
        temp=DCTrgb(k1(i)+4,k2(i)+1);
        DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+3,k2(i)+2);
        DCTrgb(k1(i)+3,k2(i)+2)=temp;
    end
end
if DCTrgb(k1(i)+4,k2(i)+1)>DCTrgb(k1(i)+3,k2(i)+2)
    DCTrgb(k1(i)+3,k2(i)+2)=DCTrgb(k1(i)+3,k2(i)+2)-alpha;
else
    DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+4,k2(i)+1)-alpha;
end
end
data=blkproc(DCTrgb,[8 8],'P1*x*P2',T',T);

实验:

初始图片Lena

嵌入密文『I am here』后的图片

经验证提取算法可提取出密文信息

其他

本文算是博客中的一篇技术文,写的过程中几经易稿,总觉得写出的东西显偏颇,我想阐述出各种技术的前因后果适用情况,又想表达出水印算法的精要之处奥妙所在,还想分析清除算法的鲁棒性准确性等等,恨不得来个数字水印的前世今生。可一来所知尚浅,二来篇幅所限,最后只写了部分而已,更重要的原因是,我不想把这里当做一个记录已知的地方,而应是一个拓展未知的起点。因此我想着重写出我在学的过程中的理解,也许未必正确或准确,我希望留下的不单是所学所知,还有所思所得。