1.1问题描述
LSB隐写时,人眼看不出载体图像变化,但修改了像素值即引入了信号失真,这种失真难以通过肉眼去描述,因此引入嵌入率embedding rate ER、负载payload和峰值信噪比PSNR的概念。在本次实验中通过实验理解嵌入率embedding rate ER、负载payload和峰值信噪比PSNR,并通过实验对其进行简单应用。
1.2基本要求
- 输入的形式和输入值的范围;
task1.m:指定一个嵌入率为0.1bpp~1bpp,本次实验采用嵌入率为0.53 bpp;一个载体图像,本次实验使用Lena.bmp;
task2.m:使用Lena.bmp作为载体图像;
task3.m:使用彩色图像Lena_RGB.bmp作为载体图像;
task4.m:使用1.tiff~10.tiff十张黑白图像作为不同载体图片;
Task5.m:使用Lena.bmp作为载体图像。
- 输出的形式;
task1.m:一张嵌入率为0.53的含密图像;
task2.m:不同嵌入率下产生的含密图像的PSNR值和绘制的率失真曲线;
task3.m:分别对R\G\B空间用同样方法嵌入同样数据最终产生的不同含密图像;
task4.m:用PSNR不低于38来约束最高payload,最高payload值、ER值和载体图像尺寸随载体图像不同的变化曲线;
task2.m:不同嵌入率下产生的含密图像的SSIM值和绘制的率失真曲线。
- 程序所能达到的功能。
task1.m:指定嵌入率为0.53bpp时,用matlab 产生长度为payload的随机数据,用LSB替换算法产生嵌入后的含密图像;
task2.m:计算不同嵌入率下产生的含密图像的PSNR值并绘制率失真曲线;
task3.m:分别对R\G\B空间用同样方法嵌入同样数据最终产生的不同含密图像;
task4.m:用PSNR不低于38来约束最高payload,分析最高payload值随载体图像不同而产生变化的原因;
task5.m:计算不同嵌入率下产生的含密图像的SSIM值并绘制率失真曲线。
2 概要设计
2.1主程序的结构流程及各模块之间的调用关系
2.2 各模块算法设计
task1~task4均调用了psnr.m函数,其可以根据载体图像和含密图像计算出两者的psnr值。
task5调用ssim.m函数,其可以根据载体图像和含密图像计算出两者的ssim值。
3. 测试与分析
测试数据,输出测试的结果,这里的测试数据应该完整和严格。并对结果进行分析。必须有运行截图
task1:指定嵌入率为0.53bpp时,用matlab 产生长度为payload的随机数据,用LSB替换算法产生嵌入后的含密图像;
task2:计算不同嵌入率下产生的含密图像的PSNR值并绘制率失真曲线:横轴嵌入率,纵轴对应的含密图像PSNR值.
task3:分别对R\G\B空间用同样方法嵌入同样数据,观察最终合成的图像人眼视觉效果,可以发现嵌入B空间的最低位对人眼视觉影响相对较小,嵌入G空间的最低位对人眼视觉影响相对大一些。
task4:对于不同载体图像,研究其最大payload值的不同,因此本次实验选用了10张图像作为载体图片,计算出其最大的payload值,并分析这10张图像的区别,以此分析最大的payload值的影响因素。
通过10幅图像的测速结果可知,以PSNR不低于38来约束最高payload,随着载体图像的不同,其最高嵌入率ER是保持稳定的,但随着载体图像的不同,其最高payload值有所不同,但对于1、2、3、4、6、7、8、9、10图像而言,其最高payload值是一致的,通过比较这10副图像的大小如图8所示。
可以得知,在载体图像大小一致时,其最高payload值是大致一致的,在载体图像大小不一致时,其payload值随着图像大小即像素点个数增大而增大。
在图像质量量化评估标准方面,PSNR只是其中的典型方法之一,其中SSIM在图像质量量化评估方面也被经常使用。对此,在本次实验中,编写了SSIM图像质量量化评估的函数,并计算不同嵌入率下产生的含密图像的SSIM值并绘制率失真曲线图像。
通过task2和task5都可以说明嵌入率越大,其图像失真情况越严重。
部分代码如下(task4.m和task5.m后续发布):
task1.m
clc
clear
close all
%% 读取图片
cover=imread("Lena.bmp");
[h,w]=size(cover);
stego=cover; %载密图片
%% 确定嵌入数据
ER=0.53; %设定嵌入率为0.53bpp
payload=ceil(h*w*ER); %待嵌入秘密信息长度
rng(106,'twister');
data_embed = round(rand(1,payload)*1); %嵌入数据
%% data_embed嵌入载体图片
for i=1:h
for j=1:w
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
if(mod(cover(i,j),2)~=data_embed(w*(i-1)+j)) %低位与嵌入数据不一致,则修改低位数据,然后存入载密矩阵中
stego(i,j)=cover(i,j)-mod(cover(i,j),2)+data_embed(w*(i-1)+j); %先去掉载体数据的最低位,再加上嵌入数据
end
end
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
end
%% 输出载体图像和载密图像进行对比
figure();
subplot(1,2,1);
imshow(cover);
title("载体图片");
subplot(1,2,2);
imshow(stego);
title("载密图片");
task2.m
clc
clear
close all
%% 读取图片
cover=imread("Lena.bmp");
[h,w]=size(cover);
stego=cover; %载密图片
rng(106,'twister');
psnrs=zeros(1,100); %为0:0.01:1的嵌入率下的psnr值预分配空间
t=1;
for ER=0.01:0.01:1
%% 不同嵌入率下的嵌入数据
payload=ceil(h*w*ER); %待嵌入秘密信息长度
data_embed=round(rand(1,payload)*1); %嵌入数据
%% 不同嵌入率下含密图像
for i=1:h
for j=1:w
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
if(mod(cover(i,j),2)~=data_embed(w*(i-1)+j)) %低位与嵌入数据不一致,则修改低位数据,然后存入载密矩阵中
stego(i,j)=cover(i,j)-mod(cover(i,j),2)+data_embed(w*(i-1)+j); %先去掉载体数据的最低位,再加上嵌入数据
end
end
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
end
%% 不同嵌入率下含密图像的PSNR值
psnrs(t)=psnr(cover,stego);
t=t+1;
end
plot(0.01:0.01:1,psnrs,'ro-');
title("率失真曲线");
xlabel("嵌入率(bpp)");
ylabel("PSNR值(dB)");
task3.m
clc
clear
close all
%% 读取彩色图片
cover=imread("Lena_RGB.bmp");
[h,w,~]=size(cover);
stego=cover;
figure();
subplot(2,2,1);
imshow(cover);
title("原始载体图片");
%% 生成随机数据
ER=1; %设定嵌入率为1bpp
payload=ceil(h*w*ER); %待嵌入秘密信息长度
rng(106,'twister');
data_embed = round(rand(1,payload)*1); %嵌入数据
%% 分别插入R\G\B空间用同样方法嵌入同样数据
dimension=['R';'G';'B'];
for k=1:3
for i=1:h
for j=1:w
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
if(mod(cover(i,j,k),2)~=data_embed(w*(i-1)+j)) %低位与嵌入数据不一致,则修改低位数据,然后存入载密矩阵中
stego(i,j,k)=cover(i,j,k)-mod(cover(i,j,k),2)+data_embed(w*(i-1)+j); %先去掉载体数据的最低位,再加上嵌入数据
end
end
if((w*(i-1)+j)>payload) %所有的嵌入数据均已嵌入成功
break;
end
end
subplot(2,2,k+1);
imshow(stego);
text=['嵌入',dimension(k,:),'空间的载密图片'];
title(text);
end
psnr.m
function psnrvalue=psnr(origin,test)
%得到图像origin和test 的PSNR
I1=double(origin);
I2=double(test);
E=I1-I2;
MSE=mean2(E.*E);
if MSE==0
psnrvalue=-1;
else
psnrvalue=10*log10(255*255/MSE);
end