LSB算法数字水印的嵌入与提取以及峰值信噪比PSNR值的计算(Matlab语言)
%文件名:lsbhide.m
%函数功能:本函数将完成顺序嵌入水印的LSB算法,载体选用灰度图像,水印选用二值图像(行数列数相同)
%格式:[ste_cover,len_total]=lsbhide(input,watermark)
%参数说明:
%input:载体图像
%watermark:水印
%ste_cover:嵌入水印的图像矩阵
%len_total:水印长度即水印容量
function [ste_cover,len_total] = lsbhide(cover,wm)
%读入图像矩阵
cover=imread('hill.bmp');
ste_cover=cover;
ste_cover=double(ste_cover);
%读入水印图像
wm=imread('wm.bmp');
%判断水印图像是否符合要求
[ m,n]=size(wm);
if m~=n
error('水印图像不符合要求');
end
%将水印矩阵转化为一维序列
for f1=1:m
for f2=1:n
msg((f1-1)*n+f2)=wm(f1,f2);
end
end
%判断嵌入消息量是否过大
len_total=m*n;
[m,n]=size(ste_cover);
if len_total>m*n
error('嵌入水印过大,请更换图像');
end
p=1; %p作为水印嵌入位数计数器
%在图像像素的LSB嵌入水印
for f1=1:m
for f2=1:n
ste_cover(f1,f2)=ste_cover(f1,f2)-mod(ste_cover(f1,f2),2)+msg(p);
if p == len_total
break;
end
p=p+1;
end
if p == len_total
break;
end
end
%得到含水印图像矩阵
ste_cover=uint8(ste_cover);
%文件名:lsbget.m
%函数功能:本函数将完成提取隐秘于LSB的水印。
%格式:result=lsbget(test,len_total)
%参数说明:
%test:待测图像
%len_total:水印长度
%result:提取水印矩阵
function result = lsbget(test,len_total)
%读入图像矩阵
ste_cover=imread(test);
ste_cover=double(ste_cover);
[m,n]=size(ste_cover);
%p作为水印嵌入位数计数器
p=1;
for f1=1:m
for f2=1:n
if bitand(ste_cover(f1,f2),1)==1
wm(p)=1;
else
wm(p)=0;
end
if p==len_total
break;
end
p=p+1;
end
if p==len_total
break;
end
end
%将提取出的一维水印序列转化为二维矩阵
for f1=1:sqrt(len_total)
for f2=1:sqrt(len_total)
result(f1,f2)=wm((f1-1)*sqrt(len_total)+f2);
end
end
function test()
cover=imread('hill.bmp');
wm=imread('wm.bmp');
[ste_cover,len_total]=lsbhide('cover', 'wm');
imwrite(ste_cover,'hill_wm.bmp');
result=lsbget('hill_wm.bmp',len_total);
figure;
subplot(1,2,1),imshow(cover);title('原始图像');
subplot(1,2,2),imshow(ste_cover);title('含水印图像');
figure;
subplot(1,2,1),imshow(wm);title('原始水印');
subplot(1,2,2),imshow(result);title('提取水印');
%文件名:PSNR.m
%函数功能:计算峰值信噪比
%格式:s=PSNR(original,test)
%参数说明:
%original为原始图像文件
%test为待测图像文件
function s=PSNR(original,test)
%读取图像矩阵
io=imread('hill.bmp');
io=double(io);
iw=imread('hill_wm.bmp');
iw=double(iw);
if(size(io)~=size(iw))
error('错误:两个输入图像大小不一致');
end
%计算PSNR
[m,n]=size(io);
sum=0;
zuida=m*n*max(max(io.^2));
for i=1:m
for j=1:n
sum=sum+(io(i,j)-iw(i,j))^2;
end
end
if(sum==0)
sum=1;
end
s=zuida/sum;
s=10*log10(s);