1.实验目的
(1)了解信息隐藏中最常用的LSB算法特点,掌握LSB算法原理,设计并实现一种基于图像的LSB隐藏算法
(2)了解如何通过峰值信噪比来对图像质量进行客观评价,并计算峰值信噪比
2.实验内容
(1)LSB隐藏算法
(2)计算峰值信噪比
3.实验原理
任何多媒体信息,在数字化时,都会产生物理随机噪声,而人的感观系统对这些随机噪声不敏感。替换技术就是利用这个原理,通过使用秘密信息比特替换随机噪声,从而完成信息隐藏目标。
BMP灰度图像的位平面,每个像素值为8bit二进制值,表示该点亮度。
图像高位平面对图像感官质量起主要作用,去除图像最低几个位平面并不会造成画面质量的明显下降。利用这个原理可用秘密信息(或称水印信息)替代载体图像地位平面以实现信息嵌入。
算法选用最低位平面来嵌入秘密信息。最低位平面对图像的视觉效果影响最轻微,但很容易受噪声影响和攻击,解决办法可采用冗余嵌入的方式来增强稳健性。即在一个区域(多个像素)中嵌入相同的信息,提取时根据该区域中的所有像素判断。
4.实验记录
(1)隐藏算法
算法分为三个部分实现:
- 隐藏算法
- 提取算法
- 测试脚本
1)隐藏算法
源代码hide_lsb.m文件:
function o=hide_lsb(block,data,I) %block:隐藏的最小分块大小 data:秘密信息 I:原始载体
si=size(I);
lend=length(data);
% 将图像划分为M*N个小块
N=floor(si(2)/block(2));
M=min(floor(si(1)/block(1)),ceil(lend/N));
o=I;
for i=0:M-1
% 计算每小块垂直方向起止位置
rst=i*block(1)+1;
red=(i+1)*block(1);
for j=0:N-1
% 计算每小块隐藏的秘密信息的序号
idx=i*N+j+1;
if idx>lend
break;
end;
% 取每小块隐藏的秘密信息
bit=data(idx);
% 计算每小块水平方向起止位置
cst=j*block(2)+1;
ced=(j+1)*block(2);
% 将每小块最低位平面替换为秘密信息
o(rst:red,cst:ced)=bitset(o(rst:red,cst:ced),1,bit);
end
end;
2)提取算法
源代码dh_lsb.m文件:
function out=dh_lsb(block,I) % block:隐藏的最小分块大小 I:携密载体
si=size(I);
% 将图像划分为M*N个小块
N=floor(si(2)/block(2));
M=floor(si(1)/block(1));
out=[];
% 计算比特1判决阈值:即每小块半数以上元素隐藏的是比特1时,判决该小块嵌入的信息为1
thr=ceil((block(1)*block(2)+1)/2);
idx=0;
for i=0:M-1
% 计算每小块垂直方向起止位置
rst = i*block(1)+1;
red=(i+1)*block(1);
for j=0:N-1
% 计算每小块图像隐藏的秘密信息序号
idx=i*N+j+1;
% 计算每小块水平方向起止位置
cst=j*block(2)+1;
ced=(j+1)*block(2);
% 提取小块最低位平面,统计1比特个数,判决输出秘密信息
tmp=sum(sum(bitget(I(rst:red,cst:ced),1)));
if(tmp>=thr)
out(idx)=1;
else
out(idx)=0;
end;
end;
end;
3)测试脚本
源代码test.m文件:
fid=1;
len=10;
% 随机生成要隐藏的秘密信息
d=randsrc(1,len,[0,1]);
block=[3,3];
[fn,pn]=uigetfile({'*.bmp','bmp file(*.bmp)';},'选择载体');
s=imread(strcat(pn,fn));
ss=size(s);
if(length(ss)>=3)
I=rgb2gray(s);
else
I=s;
end;
si=size(I);
sN=floor(si(1)/block(1))*floor(si(2)/block(2));
tN=length(d);
% 如果载体图像尺寸不足以隐藏秘密信息,则在垂直方向上复制填充图像
if sN<tN
multiple=ceil(tN/sN);
tmp=[];
for i=1:multiple
tmp=[tmp;I];
end;
I=tmp;
end;
% 调用隐藏算法,把携密载体写至硬盘
stegoed=hide_lsb(block,d,I);
imwrite(stegoed,'hide.bmp','bmp');
[fn,pn]=uigetfile({'*.bmp','bmp file(*.bmp)';},'选择隐蔽载体');
y=imread(strcat(pn,fn));
sy=size(y);
if(length(sy)>=3)
I=rgb2gray(y);
else
I=y;
end;
% 调用提取算法,获得秘密信息
out=dh_lsb(block,I);
% 计算误码率
len=min(length(d),length(out));
rate=sum(abs(out(1:len)-d(1:len)))/len;
y=1-rate;
fprintf(fid,'LSB:len:%d\t error rate:%f\t error num:%d\n',len,rate,len*rate);
通过运行测试代码,对灰度图xxx3.bmp文件进行LSB算法的信息隐藏,并生成文件bide.bmp。

图1-1 运行测试脚本,选择载体图像xxx3.bmp

图1-2 生成hide.bmp隐藏文件,并选择该文件

图1-3 产生结果
(2)计算峰值信噪比
1)峰值信噪比函数:
源代码psnr.m文件:
function y = psnr(org ,stg)
y=0;
sorg=size(org);
sstg=size(stg);
if sorg~=sstg
fprintf(1,'org and stg must have same size!\n');
end;
np=sum(sum((org-stg).^2));
y=10*log10(max(max(double((org.^2))*sorg(1)*sorg(2)/np)));
2)测试脚本
源代码cs.m文件:
org=imread('xxx3.bmp');
stg=imread('hide.bmp');
fprintf(1,'psnr:%f\n',psnr(org,stg));
运行cs.m测试脚本文件,将隐藏信息前后的两个图像进行一个峰值信噪比检测,产生结果。

图2-1 运行cs.m测试脚本文件,产生结果
5.实验结论与建议
经过该次实验,对LSB算法有了更清晰的认识与了解,并能够编写代码对灰度图进行随机信息隐藏,同时也能够通过计算峰值信噪比来对隐藏信息前后的两张图片进行检测。