方案一、选择中频系数进行水印的嵌入
Dct域分别低频中频和高频区域,传统的dct将水印嵌在低频区域,即能量较为集中的部分,会降低嵌入后的不透明性。选择中频或高频系数嵌入dct水印有助于提升水印的不可见性。但是高频区域的鲁棒性会影响水印嵌入的强度,且大部分图像处理图像攻击对于高频区域的影响也比较大,水印嵌入在高频区域鲁棒性很低,所以中频区域是较为折中的选择,即权衡了水印的不可见性和鲁棒性,保持了低频和高频系数的共同优点。
源码
Dcthide.m
msgfid=fopen(‘hidden.txt’,‘r’);
[msg,count]=fread(msgfid);
count=count*8;
alpha=0.02;%扩大差距的系数
fclose(msgfid);
msg=str2bit(msg)';%转二进制串
fid=fopen(‘a0.txt’, ‘wt’);
fwrite(fid,msg);
[len,col]=size(msg);
io=imread(‘lena.bmp’);
io=double(io)/255;
output=io;
i1=io(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
%ix= blkproc(i1,[8,8],‘P1.x’,mask1); %保留15个系数
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTrgb=blkproc(i1,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
%DCTrgb=blkproc(ix,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8); % 顺序信息嵌入⼊
temp=0;
for i=1:count;
if msg(i,1)==0
if DCTrgb(i+6,i+1)<DCTrgb(i+2,i+5) %选择(5,2)和(4,3)这对系数
temp=DCTrgb(i+6,i+1);
DCTrgb(i+6,i+1)=DCTrgb(i+2,i+5);
DCTrgb(i+2,i+5)=temp;
end
else
if DCTrgb(i+6,i+1)>DCTrgb(i+2,i+5)
temp=DCTrgb(i+6,i+1);
DCTrgb(i+6,i+1)=DCTrgb(i+2,i+5);
DCTrgb(i+2,i+5)=temp;
end
end
if DCTrgb(i+6,i+1)<DCTrgb(i+2,i+5)
DCTrgb(i+6,i+1)=DCTrgb(i+2,i+5)-alpha;%将原本的系数调整,使得系数差别变更⼤
else
DCTrgb(i+2,i+5)=DCTrgb(i+2,i+5)-alpha;
end
end
wi=blkproc(DCTrgb,[8 8],‘P1xP2’,T’,T);%对DCTrgb进行逆变换
output=io;
output(:,:,1)=wi;
imwrite(output,‘watermarkedlena.bmp’);
figure;
subplot(1,2,1);imshow(‘lena.bmp’);title(‘原始图像’);
subplot(1,2,2);imshow(‘watermarkedlena.bmp’);title(‘嵌入图像’);
Dctextract.m
wi=imread(‘watermarkedlena.bmp’);%读取携秘图像
wf=imread(‘lena.bmp’);%读取携秘图像
wi=double(wi)/255;
wi=wi(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTcheck=blkproc(wi,[8 8],'P1xP2’,T,T’);%进行离散余弦变换
% x就是每一个分成的88大小的块,P1xP2相当于像素块的处理函数(记为fun),p1=T p2=T’,也就是fun=p1xp2=TxT’的功能是进行离散余弦变换,T,T’就是前面函数fun参数
for i=1:160
if DCTcheck(i+6,i+1)<=DCTcheck(i+2,i+5)
message(i,1)=1;
else
message(i,1)=0;
end
end
fid=fopen(‘a1.txt’, ‘wt’);
fwrite(fid,message);
out=bit2str(message);
fid=fopen(‘message.txt’, ‘wt’);
fwrite(fid,out)
fclose(fid);
方案二、更改块大小与遮罩压缩改进dct
嵌入程序dcthide.m分别设置分块为88和1616,并做遮罩处理,分别探究其对应压缩攻击后提取信息的准确性。
提取程序dctextract.m仅改变分块大小,并按原本dct提取进行处理。
具体实验内容见实验结果部分。
通过阅读上述文献,可知dct变换分块以88和1616为主,分块大小对压缩性能存在影响。那么我们希望改进后的dct在保留其压缩性能的同时,有更好的抗压缩攻击的能力。
左图中通过实验得出分块尺寸64(88)左右达到压缩性能的峰值。但根据我的改进1616分块有着更好的康压缩攻击性能。
我个人的理解是由于分块增大,能量大的高频区域分散的更多,更改部分内容对于整体的影响也就更小。
88保留3个系数遮罩压缩结果
88保留15个系数遮罩压缩结果
1616保留3个系数遮罩压缩结果
1616保留15个系数遮罩压缩结果
下图为8*8保留3个系数遮罩压缩结果 可以看到没有误码
下图为88保留15个系数遮罩压缩结果,可以看到存在部分误码,二十个中存在五个
这里为什么保留多的反而会出现误码我不太清楚,事实上保留10个系数或多于15个系数也没有出现误码,但保留15个系数一定会出现误码
下图为1616保留3个和15个系数遮罩压缩结果
两个均没有产生误码,可以看到改变分块大小真实有效地改变了抗遮罩压缩攻击能力
源码
Dcthide.m
msgfid=fopen(‘hidden.txt’,‘r’);
[msg,count]=fread(msgfid);
count=count*8;
alpha=0.02;%扩大差距的系数
fclose(msgfid);
msg=str2bit(msg)';%转二进制串
fid=fopen(‘a0.txt’, ‘wt’);
fwrite(fid,msg);
[len,col]=size(msg);
io=imread(‘lena.bmp’);
io=double(io)/255;
output=io;
mask53=[1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0];
mask35=[1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0];
mask1=[1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask2=[1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask3=[1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask11=[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
mask21=[1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
mask31=[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
i1=io(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
ix= blkproc(i1,[16,16],‘P1.x’,mask11); %保留15个系数
T=dctmtx(16);%生成一个88 DCT变换矩阵
%DCTrgb=blkproc(i1,[16 16],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
DCTrgb=blkproc(ix,[16 16],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8); % 顺序信息嵌入⼊
temp=0;
for i=1:count;
if msg(i,1)==0
if DCTrgb(i+4,i+1)<DCTrgb(i+3,i+2) %选择(5,2)和(4,3)这对系数
temp=DCTrgb(i+4,i+1);
DCTrgb(i+4,i+1)=DCTrgb(i+3,i+2);
DCTrgb(i+3,i+2)=temp;
end
else
if DCTrgb(i+4,i+1)>DCTrgb(i+3,i+2)
temp=DCTrgb(i+4,i+1);
DCTrgb(i+4,i+1)=DCTrgb(i+3,i+2);
DCTrgb(i+3,i+2)=temp;
end
end
if DCTrgb(i+4,i+1)<DCTrgb(i+3,i+2)
DCTrgb(i+4,i+1)=DCTrgb(i+4,i+1)-alpha;%将原本的系数调整,使得系数差别变更⼤
else
DCTrgb(i+3,i+2)=DCTrgb(i+3,i+2)-alpha;
end
end
wi=blkproc(DCTrgb,[16 16],‘P1xP2’,T’,T);%对DCTrgb进行逆变换
output=io;
output(:,:,1)=wi;
imwrite(output,‘watermarkedlena.bmp’);
figure;
subplot(1,2,1);imshow(‘lena.bmp’);title(‘原始图像’);
subplot(1,2,2);imshow(‘watermarkedlena.bmp’);title(‘嵌入图像’);
dctextract.m
wi=imread(‘watermarkedlena.bmp’);%读取携秘图像
wf=imread(‘lena.bmp’);%读取携秘图像
wi=double(wi)/255;
wi=wi(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
T=dctmtx(16);%生成一个88 DCT变换矩阵
DCTcheck=blkproc(wi,[16 16],'P1xP2’,T,T’);%进行离散余弦变换
% x就是每一个分成的88大小的块,P1xP2相当于像素块的处理函数(记为fun),p1=T p2=T’,也就是fun=p1xp2=TxT’的功能是进行离散余弦变换,T,T’就是前面函数fun参数
for i=1:160
if DCTcheck(i+4,i+1)<=DCTcheck(i+3,i+2)
message(i,1)=1;
else
message(i,1)=0;
end
end
fid=fopen(‘a1.txt’, ‘wt’);
fwrite(fid,message);
out=bit2str(message);
fid=fopen(‘message.txt’, ‘wt’);
fwrite(fid,out)
fclose(fid);
方案三、利用不同层根据不同dct系数嵌入检验是否遭受攻击
该改进方案在原本蓝色层dct系数为(5,2)(4.3)的基础上增加了绿色层dct系数(5,1)(4,3)嵌入。经过两次对比提取可以看到若检测的信息相同,则基本说明水印未经攻击,提取到的信息可用。事实上,dct无法抵抗大部分空域攻击,如旋转缩放裁剪等,遭受这种攻击是直观肉眼可分辨的。该改进主要针对的是频域攻击的检测,如加噪滤波等,对水印的安全性有进一步提升。同时两层都选择较小的dct系数,由于dct变换后能力主要集中在左上角,在面对压缩攻击时也会有较好的表现。
二进制输出结果
其中加密的字符串长度为20,转化为二进制串长度为160,空位(NULL)为0,方框为1
a0是输入输入hidden二进制串
a1是蓝色层提取二进制串
a2是绿色层提取二进制串
a1与a2相同说明没有遭到攻击,最终提取的message可用。
源码
Dcthide.m
msgfid=fopen(‘hidden.txt’,‘r’);
[msg,count]=fread(msgfid);
count=count*8;
alpha=0.02;%扩大差距的系数
fclose(msgfid);
msg=str2bit(msg)';%转二进制串
fid=fopen(‘a0.txt’, ‘wt’);
fwrite(fid,msg);
[len,col]=size(msg);
io=imread(‘lena.bmp’);
io=double(io)/255;
output=io;
mask53=[1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0];
mask35=[1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0];
mask1=[1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask2=[1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask3=[1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
i1=io(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
i2=io(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
ix= blkproc(i1,[8,8],‘P1.x’,mask3); %保留15个系数
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTrgb1=blkproc(i1,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
DCTrgb2=blkproc(i2,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
%DCTrgb=blkproc(ix,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
[row,col]=size(DCTrgb1);
row=floor(row/8);
col=floor(col/8); % 顺序信息嵌入⼊
temp=0;
for i=1:count;
if msg(i,1)==0
if DCTrgb1(i+4,i+1)<DCTrgb1(i+3,i+2) %选择(5,2)和(4,3)这对系数
temp=DCTrgb1(i+4,i+1);
DCTrgb1(i+4,i+1)=DCTrgb1(i+3,i+2);
DCTrgb1(i+3,i+2)=temp;
end
else
if DCTrgb1(i+4,i+1)>DCTrgb1(i+3,i+2)
temp=DCTrgb1(i+4,i+1);
DCTrgb1(i+4,i+1)=DCTrgb1(i+3,i+2);
DCTrgb1(i+3,i+2)=temp;
end
end
if DCTrgb1(i+4,i+1)<DCTrgb1(i+3,i+2)
DCTrgb1(i+4,i+1)=DCTrgb1(i+4,i+1)-alpha;%将原本的系数调整,使得系数差别变更⼤
else
DCTrgb1(i+3,i+2)=DCTrgb1(i+3,i+2)-alpha;
end
if msg(i,1)==0
if DCTrgb2(i+4,i+2)<DCTrgb2(i+3,i+1) %选择(5,3)和(4,2)这对系数
temp=DCTrgb2(i+4,i+2);
DCTrgb2(i+4,i+2)=DCTrgb2(i+3,i+1);
DCTrgb2(i+3,i+1)=temp;
end
else
if DCTrgb2(i+4,i+2)>DCTrgb2(i+3,i+1)
temp=DCTrgb2(i+4,i+2);
DCTrgb2(i+4,i+2)=DCTrgb2(i+3,i+1);
DCTrgb2(i+3,i+1)=temp;
end
end
if DCTrgb2(i+4,i+2)<DCTrgb2(i+3,i+1)
DCTrgb2(i+4,i+2)=DCTrgb2(i+4,i+2)-alpha;%将原本的系数调整,使得系数差别变更⼤
else
DCTrgb2(i+3,i+1)=DCTrgb2(i+3,i+1)-alpha;
end
end
wi1=blkproc(DCTrgb1,[8 8],‘P1xP2’,T’,T);%对DCTrgb进行逆变换
wi2=blkproc(DCTrgb2,[8 8],‘P1xP2’,T’,T);%对DCTrgb进行逆变换
output=io;
output(:,:,1)=wi1;
output(:,:,2)=wi2;
imwrite(output,‘watermarkedlena.bmp’);
figure;
subplot(1,2,1);imshow(‘lena.bmp’);title(‘原始图像’);
subplot(1,2,2);imshow(‘watermarkedlena.bmp’);title(‘嵌入图像’);
Dctextract.m
wi=imread(‘watermarkedlena.bmp’);%读取携秘图像
wf=imread(‘lena.bmp’);%读取携秘图像
wi=double(wi)/255;
wi1=wi(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
wi2=wi(:,:,2);%取图像的第1层来隐藏,彩色图像空间RGB三层
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTcheck1=blkproc(wi1,[8 8],'P1xP2’,T,T’);%进行离散余弦变换
DCTcheck2=blkproc(wi2,[8 8],'P1x*P2’,T,T’);%进行离散余弦变换
% x就是每一个分成的88大小的块,P1xP2相当于像素块的处理函数(记为fun),p1=T p2=T’,也就是fun=p1xp2=Tx*T’的功能是进行离散余弦变换,T,T’就是前面函数fun参数
for i=1:160
if DCTcheck1(i+4,i+1)<=DCTcheck1(i+3,i+2)
message(i,1)=1;
else
message(i,1)=0;
end
if DCTcheck2(i+4,i+2)<=DCTcheck2(i+3,i+1)
messagecheck(i,1)=1;
else
messagecheck(i,1)=0;
end
end
fid=fopen(‘a1.txt’, ‘wt’);
fwrite(fid,message);
fid=fopen(‘a2.txt’, ‘wt’);
fwrite(fid,messagecheck);
out=bit2str(message);
fid=fopen(‘message.txt’, ‘wt’);
fwrite(fid,out)
fclose(fid);
方案四、利用密钥加密载体信息
嵌入程序dcthide.m在原有dct的基础上,随机生成了密钥二值图,并对应待加密的消息序列的每一位(长度可调)。若当前随机数为1,则密钥图该位为1,并按原本dct规则加密;若当前随机数为-1,则密钥图该位为0,更改待加密序列为相反的0或1,即按相反的dct规则加密。
提取程序dctextract.m则先按原本dct提取规则提取,再根据密钥反解出真实的序列。
该改进方案利用密钥更改了dct的加密内容,这个密钥每次加密都是随机生成的,每次的加密密钥都不相同。由于必须使用独立密钥才能完成水印的加解密,dct水印的安全性提升。同时,缺少密钥的攻击者无法破解出全部水印,解密者需要同时拿到嵌入后水印和密钥水印方可读出完整水印。
源码
Dcthide.h
msgfid=fopen(‘hidden.txt’,‘r’);
[msg,count]=fread(msgfid);
count=count*8;
alpha=0.02;%扩大差距的系数
fclose(msgfid);
msg=str2bit(msg)';%转二进制串
fid=fopen(‘a0.txt’, ‘wt’);
fwrite(fid,msg);
[len,col]=size(msg);
io=imread(‘lena.bmp’);
io=double(io)/255;
output=io;
i1=io(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
%ix= blkproc(i1,[8,8],‘P1.x’,mask3); %保留15个系数
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTrgb=blkproc(i1,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
%DCTrgb=blkproc(ix,[8 8],‘P1xP2’,T,T’);%对图像分块进行离散余弦变换
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8); % 顺序信息嵌入⼊
temp=0;
piccover2=zeros(16,16);
for i=1:16
for j=1:16
tmp = randsrc;
if (tmp==1)
piccover2(i,j)=1;
else
piccover2(i,j)=0;
if(((i-1)*16+j)<=count)
msg((i-1)*16+j,1)=1-msg((i-1)*16+j,1);
end
end
end
end
subplot(1,3,3);imshow(piccover2);title(‘密钥’);
imwrite(piccover2,‘key.bmp’);
for i=1:count;
if msg(i,1)==0
if DCTrgb(i+4,i+1)<DCTrgb(i+3,i+2) %选择(5,2)和(4,3)这对系数
temp=DCTrgb(i+4,i+1);
DCTrgb(i+4,i+1)=DCTrgb(i+3,i+2);
DCTrgb(i+3,i+2)=temp;
end
else
if DCTrgb(i+4,i+1)>DCTrgb(i+3,i+2)
temp=DCTrgb(i+4,i+1);
DCTrgb(i+4,i+1)=DCTrgb(i+3,i+2);
DCTrgb(i+3,i+2)=temp;
end
end
if DCTrgb(i+4,i+1)<DCTrgb(i+3,i+2)
DCTrgb(i+4,i+1)=DCTrgb(i+4,i+1)-alpha;%将原本的系数调整,使得系数差别变更⼤
else
DCTrgb(i+3,i+2)=DCTrgb(i+3,i+2)-alpha;
end
end
wi=blkproc(DCTrgb,[8 8],‘P1xP2’,T’,T);%对DCTrgb进行逆变换
output=io;
output(:,:,1)=wi;
imwrite(output,‘watermarkedlena.bmp’);
subplot(1,3,1);imshow(‘lena.bmp’);title(‘原始图像’);
subplot(1,3,2);imshow(‘watermarkedlena.bmp’);title(‘嵌入图像’);
dctextract.h
wi=imread(‘watermarkedlena.bmp’);%读取携秘图像
wf=imread(‘lena.bmp’);%读取携秘图像
pickey=imread(‘key.bmp’);%读取密钥图像
wi=double(wi)/255;
wi=wi(:,:,1);%取图像的第1层来隐藏,彩色图像空间RGB三层
T=dctmtx(8);%生成一个88 DCT变换矩阵
DCTcheck=blkproc(wi,[8 8],'P1xP2’,T,T’);%进行离散余弦变换
% x就是每一个分成的88大小的块,P1xP2相当于像素块的处理函数(记为fun),p1=T p2=T’,也就是fun=p1xp2=TxT’的功能是进行离散余弦变换,T,T’就是前面函数fun参数
for i=1:160
m = floor(i/16);
n = i-16*m;
if DCTcheck(i+4,i+1)<=DCTcheck(i+3,i+2)
message(i,1)=1;
else
message(i,1)=0;
end
if pickey(m+1,n+1)==0
message(i,1)=1-message(i,1);
end
end
fid=fopen(‘a1.txt’, ‘wt’);
fwrite(fid,message);
out=bit2str(message);
fid=fopen(‘message.txt’, ‘wt’);
fwrite(fid,out)
fclose(fid);