·实验的相关理论介绍
由于在空间域隐藏信息后的结果不可觉察性和鲁棒性比较低,所以考虑在载体的频域隐藏秘密信息。
数字图像I(m,n)是具有M行N列的一个矩阵。为了同时减弱或去除图像数据的相关性,可以运用二维DCT,将图像从空间域转换到DCT变换域。二维DCT变换是在一维DCT变换的基础上再做一次DCT变换,定义如下:
在matlab中使用到的矩阵运算公式为:
在频域中流行的对秘密信息进行编码的方法是在一个图像块中调整两个(或多个)DCT系数的相对大小。在编码处理过程中,发送者将载体图像分成8×8的像素块,每一块只精确地编码一个秘密信息位。嵌入过程开始时,首先伪随机地选择一个图像块bi,用它对第i个消息比特进行编码。令Bi=D{bi}为DCT变换后的图像块。
在通信开始前,发送者和接收者必须对嵌入过程中使用的两个DCT系数的位置达成一致,用(u1,v1)和(u2,v2)来表示这两个索引。这两个系数应该相应于余弦变换的中频,确保信息保存在信号的重要部位(从而使嵌入信息不容易因JPEG压缩而完全丢失)。我们普遍认为中频DCT系数有相似的数量级,我们可以假定嵌入过程不会使载体产生严重降质。因为构造的系统要在抵抗JPEG压缩方面是健壮的。我们就选择在JPEC压缩算法中它们的量化值一样的那些DCT系数。根据量化表可知,系数(5,2)和(4,3),(4,1)和(3,2),或者(1,2)和(3,0)是比较好的。
如果块Bi(u1,v1)>Bi(u2,v2)就编码为“1”,否则编码为“0”。在编码阶段,如果相对大小与要编码的比特不匹配,就相互交换两个系数。由于JPEC压缩(在量化阶段)能影响系数的相对大小,算法应通过在两个系数中加随机值,以确保对某个x>0,使得|Bi(u1,v1)-Bi(u2,v2)|>x。x值越大,算法抵抗JPEG压缩的能力就越健壮,然而图像的质量就越差。最后,发送者执行逆DCT变换把系数变换回空间域。为了从图像中提取信息,必须对所有图像块进行DCT变换。通过比较每一块中的两个系数,就可以得到隐藏的信息。
压缩流程:
- 实验代码及注释
%% DCT隐写——两点法
clear
clc
A=imread('lena.bmp');
fid=fopen('info.txt','r');%打开文件
[txt1,count]=fread(fid);
A=rgb2gray(A);
%文本信息处理
txts=dec2bin(txt1);%转二进制
txt=reshape(txts',[],1);%二维变一维
txt=str2num(txt);
%%
I = im2double(A);
D = dctmtx(8);%生成变换矩阵
C = blkproc(I,[8,8],'P1*x*P2',D,D');%分块_变换
mask1=[16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];%量化矩阵
C = blkproc(C,[8,8],'x./P1',mask1);%量化
[m,n]=size(C);
u=[5 2];%[2 3]
v=[4 3];%[4 1]
x=1;
len=length(txt);
capacity=m*n/64;
if len>capacity
disp('隐藏信息过多');
exit;
end
a=0.01;%影响因子
%隐藏
for i=1:8:m
for j=1:8:n
if x<=len
if txt(x)==1
if C(i+u(1)-1,j+u(2)-1)>C(i+v(1)-1,j+v(2)-1)
medium=C(i+u(1)-1,j+u(2)-1)+a;
C(i+u(1)-1,j+u(2)-1)=C(i+v(1)-1,j+v(2)-1);
C(i+v(1)-1,j+v(2)-1)=medium;
x=x+1;
elseif C(i+u(1)-1,j+u(2)-1)==C(i+v(1)-1,j+v(2)-1)
C(i+v(1)-1,j+v(2)-1)=C(i+v(1)-1,j+v(2)-1)+a;
x=x+1;
else
x=x+1;
continue;
end
elseif txt(x)==0
if C(i+u(1)-1,j+u(2)-1)<C(i+v(1)-1,j+v(2)-1)
medium=C(i+u(1)-1,j+u(2)-1);
C(i+u(1)-1,j+u(2)-1)=C(i+v(1)-1,j+v(2)-1)+a;
C(i+v(1)-1,j+v(2)-1)=medium;
x=x+1;
elseif C(i+u(1)-1,j+u(2)-1)==C(i+v(1)-1,j+v(2)-1)
C(i+u(1)-1,j+u(2)-1)=C(i+u(1)-1,j+u(2)-1)+a;
x=x+1;
else
x=x+1;
continue;
end
end
else
break;
end
end
end
C = blkproc(C,[8,8],'x.*P1',mask1);
%图像重构
C = blkproc(C,[8,8],'P1*x*P2',D',D);
figure(1)
subplot(1,2,1),imshow(I),title('原图');
subplot(1,2,2),imshow(C),title('嵌入信息');
%%
%提取
%img=C;%不压缩
img=I1;%压缩
img = blkproc(img,[8,8],'P1*x*P2',D,D');%分块_变换
s=1;
for i=1:8:m
for j=1:8:n
if s<=len
if img(i+u(1)-1,j+u(2)-1)>img(i+v(1)-1,j+v(2)-1)
txtn(s)=0;
s=s+1;
elseif img(i+u(1)-1,j+u(2)-1)<img(i+v(1)-1,j+v(2)-1)
txtn(s)=1;
s=s+1;
end
else
break;
end
end
end
txtn=reshape(txtn,8,len/8);%二维变一维
txtn=txtn';
txtc=num2str(txtn);
txtn=bin2dec(txtc);
fid=fopen('info_out.txt','w+','n','UTF-8');%打开文件,因为是中文所以采用UTF-8编码
[r,j]=size(txtn);
%写入
for i=1:r
fwrite(fid,txtn(i));
end
fclose(fid);
%%
%压缩
X=blkproc(C,[8,8],'P1*x*P2',D,D');%DCT
X = blkproc(X,[8,8],'x./P1',mask1);%量化
X=X*100000;
X=floor(X);
X=X/100000;
X1= blkproc(X,[8,8],'x.*P1',mask1);%反量化
I1=blkproc(X1,[8,8],'P1*x*P2',D',D);%重构图像-IDCT
subplot(1,2,1),imshow(I),title('加密')
subplot(1,2,2),imshow(I1),title('JPEG')
% I1=C;
%%
- 实验结果及分析
图1 α=0.01加密
由于我用的载体图像大小为256×256,其允许隐藏的信息容量为1024(bit),隐藏的信息大小为744(bit),且添加的差值控制值为0.01,所以从上图中可以看出嵌入信息的图像上3/4部分有比较明显的变化。
图2 α=0.01压缩
图3 α=0.01提取
由上述结果可以看出由于添加的控制量比较大为0.01,而原来的数值数量级约为10-6,所以图像隐写后变化明显。
图4 α=0.001加密
图5 α=0.001压缩
图6 α=0.001提取
从改变差值控制量后的结果可以看出,此时我们肉眼几乎无法看出隐藏前和隐藏后的图像区别,并且此时也能准确的提取到隐藏的信息,所以此时是一个比较理想的状态,此时的图像不可觉察性高,鲁棒性强。