我编写了下面的代码,该代码对图像进行Haar变换,并在系数的最低有效位中逐位嵌入一条秘密消息。要使用bitset函数,我将双系数转换为uint64,并在嵌入后将其更改回来。
function DwtSteg(address,message)
coverImage=imread(address);
ascii=uint8(message);
[LL LH HL HH]=dwt2(coverImage,'haar');
LH=round(LH);
HL=round(HL);
subplot(1,2,1)
imshow(LH)
[r c]=size(LL);
wc=1;
bc=1;
done=false;
for i=1:r
if(done)
break
end
for j=1:c
if(bc==8)
bc=1;
wc=wc+1;
end
if(wc==length(message))
done=true;
break;
end
xb = typecast(LH(i,j), 'uint64' );
xb=bitset(xb,1,bitget(ascii(wc),bc));
xb%***
LH(i,j)=typecast(xb, 'double');
bc=bc+1;
end
end
subplot(1,2,2)
imshow(LH)
stegoImage=idwt2(LL ,HL,LH, HH,'haar');
figure(2)
imshow(uint8(stegoImage));
imwrite(uint8(stegoImage),'stegoImage.tiff');
end
但是当我在代码下面运行以从Image中提取我的消息时。系数与转换后的系数相同。(考虑' ***'对于这两个函数):
function [ str ] = DwtDesteg( address)
str='';
image=imread(address);
[LL LH HL HH]=dwt2(image,'haar');
[r c]=size(LL);
LH=round(LH);
bc=1;
ch=0;
for i=1:r
for j=1:c
if(bc==8)
bc=1;
str=strcat(str,ch);
char(ch)
end
xb = typecast(LH(i,j), 'uint64');
xb%***
ch=bitset(ch,bc,bitget(xb,1));
bitget(xb,1)
bc=bc+1;
end
end
end
答案 0 :(得分:0)
由于您将DWT系数操作为整数,因此您可以使用整数变换IWT。所以,而不是做
[LL LH HL HH]=dwt2(coverImage,'haar');
使用lwt2()
的提升方案。
% set up a Haar integer lifting scheme
els = {'p',[-0.125 0.125],0};
lshaarInt = liftwave('haar','int2int');
lsnewInt = addlift(lshaarInt,els);
% transform away!
[LL,LH,HL,HH] = lwt2(double(image),lsnewInt);
此时,您不必进行任何舍入,例如LH = round(LH)
。只需直接嵌入即可。
imread()
将图像加载为uint8类型。当您将其传递给dwt2()
时,它会将所有内容转换为double。但是,如果您尝试将uint8矩阵传递给lwt2()
,它会抱怨,因此您必须手动将其转换为double。对于inverse transform,只需执行
image = ilwt2(LH,LH,HL,HH,lsnewInt);
image = uint8(image);
现在,您的代码还有一些其他错误,例如将LH
系数强制转换为uint64
会使得bitsetting混乱。追逐一切有点麻烦,所以我重写了你的功能。
<强> embed.m 强>
function embed(filein,fileout,message)
image = imread(filein);
message = double(message);
els = {'p',[-0.125 0.125],0};
lshaarInt = liftwave('haar','int2int');
lsnewInt = addlift(lshaarInt,els);
[LL,LH,HL,HH] = lwt2(double(image),lsnewInt);
col = size(LH,2);
r = 1;
c = 1;
for i = 1:length(message);
letter = message(i);
for b = 8:-1:1;
LH(r,c) = bitset(LH(r,c),1,bitget(letter,b));
c = c + 1;
if (c > col)
r = r + 1;
c = 0;
end
end
end
stego = uint8(ilwt2(LL,LH,HL,HH,lsnewInt));
imshow(stego);
imwrite(stego,fileout);
end
<强> extract.m 强>
function extract(filename,messageLength)
image = imread(filename);
els = {'p',[-0.125 0.125],0};
lshaarInt = liftwave('haar','int2int');
lsnewInt = addlift(lshaarInt,els);
[LL,LH,HL,HH] = lwt2(double(image),lsnewInt);
col = size(LH,2);
r = 1;
c = 1;
secret = zeros(messageLength,1);
for i = 1:messageLength;
letter = 0;
for b = 8:-1:1;
letter = bitset(letter,b,bitget(LH(r,c),1));
c = c + 1;
if (c > col)
r = r + 1;
c = 0;
end
end
secret(i) = char(letter);
end
disp(char(secret'));
end
您会注意到提取功能需要将消息长度作为参数。这是因为您的嵌入方法不以任何方式编码何时停止提取位。如果您不希望接收器依赖于该参数的知识,就像他不应该这样,您有几个选择。但是,我将把这个实现留给你,因为它超出了这个问题的范围。