此次實驗室是基於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值