此次实验室是基于AMBTC方法的,通过对量化水平的修改,使得图像的失真降低。同时,paper中也采用了一个阈值机制来选择合适的图像块嵌入数据,相比于以往的方案,该方案明显优于以往方案,尤其是在嵌入容量上。
实验中采用一张512×512的灰度图Lena,根据阈值机制判断每块采用何种方式嵌入数据。对图像分块后,根据预定阈值,判断每块的类型,是属于平滑块还是复杂块,然后根据以下方式进行数据嵌入:
当T<=Tm<Ts时,属于平滑块,采用QM方法嵌入数据,每块能嵌入16个bit;
当T<Tm且Tm>Ts时,要采用QM和QP两种方法嵌入数据,每块能嵌入16+2个bit;
当T>Tm时,采用无损嵌入LL,每块只能嵌入1个bit。
实验数据:(Ts=4 Tm=20)
1) T<=Tm 且Tm>Ts (以第七图像块为例)
根据paper中的方案可知,这种情况可嵌入16bit + 2bit 数据
嵌入数据应为:1000 0100 1001 1101 01
提取数据为:1000 0100 1001 1101 01
嵌入和提取数据一致
2)T>Tm (以104块为例)
此种情况下只能够在每块中嵌入 1bit 数据
可以看到这里的 a>b,有paper的方案可知,这里嵌入的数据应为 0
(这里的7为初始值,忽略)
提取的数据为:0 如下所示:
嵌入和提取数据一致
图像对比(Ts=4):
fig1:原始图像 fig2:Tm=10
fig3:Tm=20 fig4:Tm=30
fig5:Tm=40 fig6:Tm=50
表1:不同阈值下的psnr (Ts=4)
Tm/dB | 50 | 40 | 30 | 20 | 10 |
PSNR/dB | 28.6128 | 29.2749 | 30.3358 | 31.4035 | 32.2406 |
通过实验测量数据可以发现,随着设定阈值Tm越小时,PSNR值越大,图像的失真也越小,视觉效果也就越好。
之前代码错误原因:(数据提取部分代码)
datablock2=cell2mat(ExdataCell(i));
a=int32(AMBTC(i).a);
b=int32(AMBTC(i).b);
bitMap=AMBTC(i).bitMap;
d = abs(a-b);
之前a b的数据类型是uint32,所以当a>b时,计算a-b得到的值就会恒等于 0;
因此在提取数据判断条件时,总是会进入 d<=Tm 中,所以提取出的数据都是错的。这里
if d<=Tm 我将a b的数据类型改成 int32,就解决了该问题。
...
if Tm>Ts
...
if d > Tm
function PSNR=PSNR(Img1,Img2)
Img1=double(Img1(:));
Img2=double(Img2(:));
MSE=sum(((Img1-Img2).*(Img1-Img2)))/numel(Img1);
if MSE == 0
fprintf('MSE = 0\n');
PSNR = -1;
else
PSNR= 10*log10(255*255/MSE);
endImg=uint8(imread('Lena.tiff'));
blockSize=[4 4];
cellSize=size(Img)./blockSize;
cellSize1=ones(1,cellSize(1)).*blockSize(1);
cellSize2=ones(1,cellSize(2)).*blockSize(2);
ImgCell=mat2cell(Img,cellSize1,cellSize2);
Data = uint8(ones(cellSize(1),cellSize(1)*18)*7); %构建一个初始存放数据的容器
blockSize2=[1 18];%存放嵌入数据每块的大小
cellSize3=size(Data)./blockSize2; %分块
cellSize4=ones(1,cellSize3(1)).*blockSize2(1);
cellSize5=ones(1,cellSize3(2)).*blockSize2(2);
EmdataCell=mat2cell(Data,cellSize4,cellSize5); %嵌入数据cell
ExdataCell=EmdataCell; %提取数据cell
Ts = 4;
Tm = 20; %预定阈值
%============================================
for i=1:numel(ImgCell)
block=cell2mat(ImgCell(i)); % 读入图像块i
datablock=cell2mat(EmdataCell(i));%读入嵌入数据cell
ave=mean(double(block(:)));
bitMap1=(block>=ave);
a1=uint32(mean(block(bitMap1))); %求高均值
b1=uint32(mean(block(~bitMap1))); %求低均值
T = abs(a1-b1); %计算高低均值绝对差值
if T<=Tm %判断条件 采用QM方法嵌入数据 16bit
mbitMap = rand(4,4)>0.5; %随机产生嵌入数据
datablock(1:16)=mbitMap;%保存要嵌入的数据
p00=0;
p01=0;
p10=0;
p11=0;
for j=1:16 %统计p00 p01 p10 p11
if (bitMap1(j)==0)&&(mbitMap(j)==0)
p00 = p00 + 1;
elseif (bitMap1(j)==0)&&(mbitMap(j)==1)
p01 = p01 + 1;
elseif (bitMap1(j)==1)&&(mbitMap(j)==0)
p10 = p10 + 1;
elseif (bitMap1(j)==1)&&(mbitMap(j)==1)
p11 = p11 + 1;
end
end
am=double(a1*p00+b1*p10)/double(p00+p10); %根据paper修改a b值
bm=double(a1*p01+b1*p11)/double(p01+p11);
a2=round(am);
b2=round(bm);
if Tm>Ts %判断条件 采用QP方法嵌入数据 2bit
qbitMap = rand(1,2)>0.5; %随机产生嵌入数据
datablock(17:18)=qbitMap; %保存要嵌入的数据
s1=qbitMap(1);
s2=qbitMap(2);
if s1==0 %根据嵌入数据 1 or 0,修改a2 b2
if(mod(a2,2)==1)
if (am>=a2)
a2=a2+1;
else
a2=a2-1;
end
end
elseif s1==1
if(mod(a2,2)==0)
if(am>a2)
a2=a2+1;
else
a2=a2-1;
end
end
end
if s2==0
if(mod(b2,2)==1)
if(bm>=b2)
b2=b2+1;
else
b2=b2-1;
end
end
elseif s2==1
if(mod(b2,2)==0)
if(bm>b2)
b2=b2+1;
else
b2=b2-1;
end
end
end
end
AMBTC(i) = struct('a', {a2}, 'b', {b2},'bitMap', {mbitMap});
EmdataCell(i)=mat2cell(datablock,size(datablock,1),size(datablock,2));%将嵌入数据存放入cell
end
if T>Tm %判断条件 采用LL方法嵌入数据 1bit
lbitMap = rand(1)>0.5; %随机产生嵌入数据
s0 = lbitMap(1);
datablock(1)=lbitMap;%保存要嵌入的数据
EmdataCell(i)=mat2cell(datablock,size(datablock,1),size(datablock,2));%将嵌入数据存放入cell
if s0==0
AMBTC(i) = struct('a', {a1}, 'b', {b1},'bitMap', {bitMap1});
elseif s0==1
AMBTC(i) = struct('a', {b1}, 'b', {a1},'bitMap', {~bitMap1});
end
end
end
%===========================================
for i=1:numel(ImgCell) %===========数据的提取====================
datablock2=cell2mat(ExdataCell(i)); %读入提取数据cell
a=int32(AMBTC(i).a);
b=int32(AMBTC(i).b);
bitMap=AMBTC(i).bitMap;
d = abs(a-b); %计算d值
if d<=Tm %QM 可提取16bit数据
datablock2(1:16) = bitMap; %保存提取出的数据
if Tm>Ts %QP 可提取2bit数据
s1=mod(a,2);
s2=mod(b,2);
datablock2(17) = s1;%保存提取出的数据
datablock2(18) = s2;
end
ExdataCell(i)=mat2cell(datablock2,size(datablock2,1),size(datablock2,2));%将提取的数据存入cell
end
if d > Tm %LL 可提取出 1bit数据
if a > b
s0=0;
else
s0=1;
end
datablock2(1) = s0; %保存提取出的数据
ExdataCell(i)=mat2cell(datablock2,size(datablock2,1),size(datablock2,2));%将提取的数据存入cell
end
end
%============================================
AMBTCdeCell=ImgCell;
%============================================
%解码
for i=1:numel(ImgCell)
a=AMBTC(i).a;
b=AMBTC(i).b;
bitMap=AMBTC(i).bitMap;
AMBTCde=zeros(size(bitMap));
AMBTCde(bitMap)=a;
AMBTCde(~bitMap)=b;
AMBTCdeCell(i)=mat2cell(AMBTCde,size(AMBTCde,1),size(AMBTCde,2));
end
%============================================
AMBTCde=uint8(cell2mat(AMBTCdeCell));
imshow(AMBTCde); %显示解码后的图像
%============================================
%比较嵌入和提取cell是否一致 验证正确性
count=0; %用来统计数据不一致的块数
for i=1:numel(ImgCell)
A = cell2mat(EmdataCell(i)); %读入嵌入的数据块
B = cell2mat(ExdataCell(i)); %读入提取的数据块
if(A~=B) % 判断A B中数据是否相同
disp(i) %输出数据不一致的块号
count=count+1; %累计数据不一致的块数
end
end
%判断 ============================================
if count==0
disp('数据完全一致') %若无数据不一致块 打印 '数据完全一致'
else
disp(['共有',num2str(count),'块数据不一致']) %若有数据不一致块存在 打印出共有多少块
end
psnr=PSNR(Img,AMBTCde) %计算PSNR值