数字水印实验4 基于BTC的信息隐藏实验
【实验名称】基于BTC的信息隐藏实验
【实验目的】
1、加深对图像信息隐藏基本原理和方法的掌握
2、学习并实现基于BTC的信息隐藏和提取算法
【实验原理】
1、将图像分成n×n大小的子块
2、计算子块的像素均值、高均值H和低均值I。根据均值进一步将原图像修改为二进制位图B。
3、在绝对矩阵块截断编码(AMBTC)生成的高低平均值序列上隐藏秘密信息。
【实验内容】
代码:
function BTC()
clc;clear;close all;
I=imread('coverlena.bmp');
figure;subplot(1,2,1);imshow(I);
title('原图');
Secret=10; %待隐藏数据的大小
block=4; %子块大小
data=round(rand(1,Secret)); %随机生成大小为Secret的待隐藏的2进制数据
fprintf('隐藏数据:');disp(data);
[length,width]=size(I);
High=zeros(length/block,width/block);
Low=zeros(length/block,width/block);
for i=1:block:256
for j=1:block:256
all=sum(sum(I(i:i+block-1,j:j+block-1),1),2);
average=all/(block^2);
high=0;low=0;num1=0;num2=0;
for q=i:i+block-1
for p=j:j+block-1
if I(q,p)>average
high=high+double(I(q,p));
num1=num1+1;
else
low=low+double(I(q,p));
num2=num2+1;
end
end
end
High(((i-1)/block)+1,((j-1)/block)+1)=round(high/num1);
Low(((i-1)/block)+1,((j-1)/block)+1)=round(low/num2);
I(i:i+block-1,j:j+block-1)=I(i:i+block-1,j:j+block-1)>average;
end
end
point=1;
for i=1:length/block
if point>Secret
break;
end
for j=i:width/block
%将数据隐藏进High数组
if point>Secret
break;
end
if point==Secret-mod(Secret,3)+1 %剩余数据不足三位时单独处理
High(i,j)=fix(double(High(i,j))/8);
High(i,j)=High(i,j)*8;
if mod(Secret,3)==1
fprintf('待隐藏数据:%-3d 隐藏进High数组 隐藏前值为:%d',data(point),High(i,j));
High(i,j)=High(i,j)+data(point)*4;
point=point+1;
end
if mod(Secret,3)==2
fprintf('待隐藏数据:%d%-2d 隐藏进High数组 隐藏前值为:%d',data(point),data(point+1),High(i,j));
High(i,j)=High(i,j)+data(point)*4+data(point+1)*2;
point=point+2;
end
fprintf(' 隐藏后值为:%d\n',High(i,j));
break;
end
fprintf('待隐藏数据:%d%d%d 隐藏进High数组 隐藏前值为:%d',data(point),data(point+1),data(point+2),High(i,j));
High(i,j)=fix(double(High(i,j))/8); %后三位置0,放入待隐藏数据
High(i,j)=High(i,j)*8;
High(i,j)=High(i,j)+data(point)*4+data(point+1)*2+data(point+2);
fprintf(' 隐藏后值为:%d\n',High(i,j));
point=point+3;
%将数据隐藏进Low数组
if point>Secret
break;
end
if point==Secret-mod(Secret,3)+1 %剩余数据不足三位时单独处理
Low(i,j)=fix(double(Low(i,j))/8);
Low(i,j)=Low(i,j)*8;
if mod(Secret,3)==1
fprintf('待隐藏数据:%-3d 隐藏进Low 数组 隐藏前值为:%d',data(point),Low(i,j));
Low(i,j)=Low(i,j)+data(point)*4;
point=point+1;
end
if mod(Secret,3)==2
fprintf('待隐藏数据:%d%-2d 隐藏进Low 数组 隐藏前值为:%d',data(point),data(point+1),Low(i,j));
Low(i,j)=Low(i,j)+data(point)*4+data(point+1)*2;
point=point+2;
end
fprintf(' 隐藏后值为:%d\n',Low(i,j));
break;
end
fprintf('待隐藏数据:%d%d%d 隐藏进Low 数组 隐藏前值为:%d',data(point),data(point+1),data(point+2),Low(i,j));
Low(i,j)=fix(double(Low(i,j))/8); %后三位置0,放入待隐藏数据
Low(i,j)=Low(i,j)*8;
Low(i,j)=Low(i,j)+data(point)*4+data(point+1)*2+data(point+2);
fprintf(' 隐藏后值为:%d\n',Low(i,j));
point=point+3;
end
end
fprintf('信息隐藏成功!\r\n');
fprintf('将压缩图像信息传送至接收方\r\n');
fprintf('恢复图像并显示\n');
%恢复图像
for i=1:block:length
for j=1:block:width
for q=i:i+block-1
for p=j:j+block-1
if I(q,p)==1
I(q,p)=High(((i-1)/block)+1,((j-1)/block)+1);
else
I(q,p)=Low(((i-1)/block)+1,((j-1)/block)+1);
end
end
end
end
end
subplot(1,2,2);imshow(I);title('压缩图');
%隐藏信息读取
point=1;
for i=1:length/block
if point>Secret
break;
end
for j=i:width/block
%High数组隐藏数据读取
if point>Secret
break;
end
if point==Secret-mod(Secret,3)+1 %之前做单独放入处理的隐藏点进行单独读取
message=double(mod(High(i,j),8));
message=floor(message/2);
if mod(Secret,3)==1
message=floor(message/2);
Data(point)=mod(message,2);
point=point+1;
end
if mod(Secret,3)==2
Data(point+1)=mod(message,2);
message=floor(message/2);
Data(point)=mod(message,2);
point=point+2;
end
break
end
message=double(mod(High(i,j),8)); %读取放置在后三位的隐藏数据
Data(point+2)=mod(message,2);
message=floor(message/2);
Data(point+1)=mod(message,2);
message=floor(message/2);
Data(point)=mod(message,2);
point=point+3;
%Low数组隐藏数据读取
if point>Secret
break;
end
if point==Secret-mod(Secret,3)+1 %之前做单独放入处理的隐藏点进行单独读取
message=double(mod(Low(i,j),8));
message=floor(message/2);
if mod(Secret,3)==1
message=floor(message/2);
Data(point)=mod(message,2);
point=point+1;
end
if mod(Secret,3)==2
Data(point+1)=mod(message,2);
message=floor(message/2);
Data(point)=mod(message,2);
point=point+2;
end
break
end
message=double(mod(Low(i,j),8)); %读取放置在后三位的隐藏数据
Data(point+2)=mod(message,2);
message=floor(message/2);
Data(point+1)=mod(message,2);
message=floor(message/2);
Data(point)=mod(message,2);
point=point+3;
end
end
fprintf('提取数据:');disp(Data);
end
实验结果:
实验结果分析:
由于图片经过压缩的缘故,可以看出压缩并隐藏了信息后恢复出来的图像有明显的失真。
仔细观察每一步隐藏信息的过程
1、待隐藏数据:110,隐藏进High数组,隐藏前值为:162
将162二进制的后三位抹除,得160,放入待隐藏数据110,得166。
2、待隐藏数据:100,隐藏进Low 数组,隐藏前值为:158
将158二进制的后三位抹除,得152,放入待隐藏数据100,得156。
3、待隐藏数据:110,隐藏进High数组,隐藏前值为:159
将159二进制的后三位抹除,得152,放入待隐藏数据110,得158。
4、待隐藏数据:1 ,隐藏进Low 数组,隐藏前值为:152
将158二进制的后三位抹除,得152,放入待隐藏数据1(待隐藏数据位数不够则按二进制位从高位到地位隐藏,不够处补0)即放入100,得156。
将手动推算结果和实验结果对比,可以看出实验正确。
【小结或讨论】
本次实验是第四次实验,实验主要内容是学习并实现基于BTC的信息隐藏和提取算法。
总体来说,基于BTC的信息隐藏实验难度和复杂度都比上一次的龟壳实验低。这个算法的信息隐藏过程使用的是上一次LSB实验的方法,所以对我们来说还是比较得心应手的。但是这个算法的亮点是BTC压缩算法的应用,这也是本实验与之前实验的最大不同之处。因为在当前实际的图片传输中,图片往往是进行压缩传送的。而如果基于我们之前学习的几个图片信息隐藏算法,在进行图片压缩后,图像中的隐藏信息全都会丢失。所以本次实验的基于BTC的信息隐藏算法,主要实现的是既对图片进行了压缩,又能将秘密信息隐藏进图片。
基于BTC的信息隐藏算法基本实现过程是:
1、将图像分成n×n(本实验中以4×4
为例,修改代码第7行的block值即可)大小的子块。
2、计算子块的像素均值以及大于子块均值的所有像素点的高均值H和小于子块均值的所有像素点的低均值I。并将大于子块均值的所有像素点值置1,小于子块均值的所有像素点值置0。
3、在生成的高低平均值序列上使用LSB算法,隐藏秘密信息。
4、将压缩图像信息传送至接收方(这一步是对应实际中的模拟操作,并不是在代码中的真实实现)
5、恢复图像并显示(子块越大,图像失真越大)
6、提取隐藏数据
通过本次实验,我对压缩算法的原理有了一定的了解,并且对LSB信息隐藏算法进行了巩固。希望在后续实验中不断提高自己的能力。