1 简介
提出了一种基于DCT变换的图像数字水印算法,重点解决了水印嵌入过程中不可见性和鲁棒性折衷问题。首先对原始图像进行分块并对各子块做DCT变换,接着将经过Arnold置乱的水印图像嵌入到各子块的中频DCT系数中,通过选择适当的嵌入强度,可以得到较好的不可见性和鲁棒性。实验结果表明,该算法能够有效抵抗噪声、JPEG压缩和剪裁等攻击。
在图像隐写分析中,这几个特征是比较经典的 图像隐写分析中DCT特征与Markov特征展现出了极大a的潜力,小波变换的奇异值分解(Wavelet Singular Value Decomposition , WSVD)特征也有奇效,本文实现前人论文的特征提取编程代码。 先说说理论知识 1 扩展DCT统计特征提取 大多数的隐密算法都是对JPEG图像的DCT系数进行操作,以此来嵌入秘密信息。DCT系数统计特征,旨在捕捉DCT系数的统计量的特征,以此来区分载体图像和隐密图像。 DCT系数统计算法由Fridrich【1】提出,其中包含了DCT系数直方图,共生矩阵,空域块间相关性等部分。首先用DCT系数替换相同位置的原始图像像素,使用dij(k) 来表示DCT系数矩阵,其中i,j=1, … ,8,k=1, … ,nB。而dij(k)则代表的是在第k个8×8 DCT块中处于(i,j)位置的DCT系数,而DCT块一共有nB 块。为了减少计算量和特征维度,在计算特征之前需要进行预处理,将所有DCT系数值范围限定在[-5,5]之间,大于和小于该范围内的值全部变换为-5到+5之间。
其中,Ir和Ic表示图像DCT系数块的两种排列方式,分别是行扫描顺序和列扫描顺序。 接下来的两个特征Bα是从解压的JPEG图像中计算,也是一种块间相关性的特征:
在DCT系数统计的隐密分析中,Fridrich首次提出了用于隐密分析的“校准”概念和计算原理:特征计算函数F,训练或测试图像J1,将图像J1解压到空域并沿各个方向裁剪四个像素,然后使用同J1相同的量化表压缩得到的图像J2。f表示最终获取的特征,而最后的特征由f=F(J1)-F(J2)计算得到。
采用如此计算方式的原理如下:裁剪之后的图像和原始图像内容上大体上完全一致,虽然裁剪之后的图像失去了原来的DCT分块,但是其统计特征应与原来相差不多。而这个过程会对嵌入的信息十分敏感,使裁剪前后的特征差别较大。经过实验证明,如此提取特征的方法非常有效果。
总结来说,DCT系数统计特征对DCT系数全局和局部进行了统计分析,并且捕获DCT系数的块间相关性和空域像素的相关性等特征。对于JPEG图像来说,所有隐密算法都是针对DCT系数进行修改,该算法确实是有一定的效果。实验中,该特征集展现了不错的分析效果,在0.2的嵌入率情况下可以达到平均95%的准确率,但是对MB算法的效果一般,尤其是MB2。
原始DCT统计特征已经有一定的检测效果,本文先对其进行扩展,加强特征的检测效果。对于全局直方图函数H,可以得到范围在[-5,+ 5]中的元素个数的差异,包括全局直方图和局部直方图,局部直方图选择的位置为{(1, 2),(2, 1),(3, 1),(2, 2),(1, 3)}。 因此,直方图特征是:
如此的DCT扩展特征共有193维,其特征组成见下表。
2 源代码
% 基于DCT变换的信息隐藏(数字水印)嵌入算法的设计 %
close all;
clc;
%-----------------读入"隐藏的图片"---------------------
wm0=imread('taiji.bmp');
wm0=rgb2gray(wm0);
wm0=imresize(wm0,[32 32]);
%wm0=im2bw(wm0);
[Mm,Nm]=size(wm0) ; %计算水印图象(秘密信息)的高度和宽度
n=Mm*Nm;
subplot(221)
imshow(wm0);
title('origanal message');
wm=double(wm0);
%-----------------------读入"载体图像"-------------------------
cover_image=imread('lena.bmp');
cover_image=rgb2gray(cover_image);
[Mc,Nc]=size(cover_image); %计算载体图象的高度和宽度
subplot(222);
imshow(cover_image);
title('origanal image');
cover_image=double(cover_image);%读入原始载体图象,并转换为双精度
%------------------分块DCT变换,嵌入水印----------------------------
%设置水印嵌入强度
k=2;
%设置嵌入位置
x=5;
y=2; %隐藏信息的密钥
%设定图象的分块大小为8*8
blocksize=8;
c=Mc/blocksize;
d=Nc/blocksize;
m=c*d;%计算载体图像能够划分的图象块
%判断载体图像尺寸是否适合水印大小
if n>m
error('The watermark is too large to be imbeded into the coverimage');
end
%分块DCT变换,嵌入水印
for j=1:c
for i=1:d
dct_block=dct2(cover_image((1+(j-1)*8):j*8,(1+(i-1)*8):i*8));
dct_block2= dct_block;
%dct_block2(x,y)=k*wm(j,i);
dct_block2(x,y)= dct_block(x,y)+k*wm(j,i);
watermarked_image((1+(j-1)*8):j*8,(1+(i-1)*8):i*8)=idct2(dct_block2);
end
end
%------------------------------------------------------------------
watermarked_image=imrotate( watermarked_image,10,'bilinear','crop');
%生成并输出嵌入水印后的图象
imwrite(uint8(watermarked_image),'watermarked_image.bmp','bmp');
%显示嵌入水印后的图象
subplot(223);
uint8_watermarked_image=uint8(watermarked_image);
imshow(uint8_watermarked_image)
title('watermarkedImage')
wm2=zeros(c,d);
%实现watermarked_image.bmp中所嵌秘密信息的提取
for j=1:c
for i=1:d
dct_block3=dct2(watermarked_image((1+(j-1)*8):j*8,(1+(i-1)*8):i*8));
dct_block=dct2(cover_image((1+(j-1)*8):j*8,(1+(i-1)*8):i*8));
%g=dct_block3(x,y)/k;
g=(dct_block3(x,y)-dct_block(x,y))/k ;
wm2(j,i)=g;
end
end
wm3=uint8(wm2);
%------------------------------------------------------------------
subplot(224);
imshow(wm3);
title('recovered message')
%e=cover_image-watermarked_image;
e=wm0-wm3;
[m,n]=size(e);
mse=sum((e(:).^2))/(m*n);
psnr=10*log10(255^2/mse)%原始水印与提取水印的峰值信噪比
3 运行结果
4 参考文献
[1]李石峰. 基于DCT数字水印算法的研究与应用[D]. 东北大学, 2008.