Matlab-LSB信息隐藏实验

一、实验内容

实验完成形式: 
用MATLAB函数实现LSB信息隐藏和提取
实验选择载体: 
512×512灰度图像
实验效果和分析: 
1.完成基本的LSB信息隐藏及提取
2.能随机选择嵌入位进行信息隐藏及提取(考虑安全性因素) 
3.能够计算PSNR,分析信息隐藏图像质量
4.完成对秘密信息的图像载体进行攻击,采用的攻击方法: jpeg压缩,resize缩放                         

5.计算每种攻击方法提取的秘密信息误码率 

二、实验涉及到的相关算法

1.基本LSB信息隐藏及提取算法——图像的第一层是LSB层,替换后对原图像的影响较小,第8层为MSB层对原图像影响较大。 
1)读入图像载体:gray=imread('lena_gray.bmp');
2)读入要隐藏的图像,并转换为二进制:woman=imread('woman_rgb.bmp'); woman_to_binary=im2bw(woman);
3)在图像载体的第一层隐藏图像:gray_set=bitset(gray,1,woman_to_binary);
4)提取隐藏的图像:gray_get_1=bitget(gray_set,1);
算法实现源代码:
gray=imread('lena_gray.bmp');
gray_8=bitget(gray,8);
gray_6=bitget(gray,6);
gray_7=bitget(gray,7);
woman=imread('woman_rgb.bmp');
woman_to_binary=im2bw(woman);
gray_set=bitset(gray,1,woman_to_binary);
gray_set_8=bitset(gray,8,woman_to_binary);
gray_get_8=bitget(gray_set_8,8);
gray_get_1=bitget(gray_set,1);
subplot(221),imshow(gray),title('原始图像');
subplot(222),imshow(logical(gray_8)),title('原始图像的第8层');
subplot(223),imshow(gray_set_8),title('在第8层隐藏信息后');
subplot(224),imshow(logical(gray_get_8)),title('获取隐藏的图像');
figure,%新打开一个窗口
subplot(221),imshow(gray),title('原始图像');
subplot(222),imshow(woman_to_binary),title('要隐藏的图像');
subplot(223),imshow(gray_set),title('在第1层隐藏信息后');
subplot(224),imshow(logical(gray_get_1)),title('获取隐藏的图像');

2.完成随机选择嵌入位进行LSB信息隐藏及提取算法。


随机选择嵌入位,嵌入水印信息,input为载体图像,file为要嵌入的文本文件,output为嵌入水印后的图像,key为随机数种子。

%2.随机选择嵌入位
function [ste_cover,len_total]=rand_lsb_hide(input,file,output,key)
%读入图像矩阵
cover=imread(input);
ste_cover=cover;
ste_cover=double(ste_cover); 
%将文本文件转换为二进制
f_id=fopen(file,'r');
[msg,len_total]=fread(f_id,'ubit1');
%判断嵌入的信息量是否过大
[m,n]=size(ste_cover);
if len_total>m*n
  error('嵌入信息量过大,请重新选择图像');
end
%p作为消息嵌入位计数器
p=1;
%调用随机间隔函数选取像素点
[row,col]=randinterval(ste_cover,len_total,key);
%在LSB隐藏信息
for i=1:len_total
    ste_cover(row(i),col(i))=ste_cover(row(i),col(i))-mod(ste_cover(row(i),col(i)),2)+msg(p,1);
    if p==len_total
        break;
    end
    p=p+1;
end
ste_cover=uint8(ste_cover);
imwrite(ste_cover,output);
%显示实验结果
subplot(1,2,1);imshow(cover);title('原始图像');
subplot(1,2,2);imshow(output);title('隐藏信息的图像');

实现效果:


读取嵌入的水印信息,output为嵌入水印后的图像,goalfile为提取出的水印文件,key与嵌入水印时的值相同:

function result = rand_lsb_get(output,len_total,goalfile,key)
ste_cover=imread(output);
ste_cover=double(ste_cover);
%判断嵌入信息量是否过大
[m,n]=size(ste_cover);
if len_total>m*n
  error('嵌入信息量过大,请重新选择图像');
end
frr=fopen(goalfile,'a');
%p作为消息嵌入位计数器,将消息序列写回文本文件
p=1;
%调用随机间隔函数选取像素点
[row,col]=randinterval(ste_cover,len_total,key);
for i=1 :len_total
    if bitand(ste_cover(row(i),col(i)),1)==1
        fwrite(frr,1,'ubit1');
        result(p,1)=1;
    else
        fwrite(frr,0,'ubit1');
        result(p,1)=0;
    end
    if p ==len_total
        break;
    end
    p=p+1;
end
fclose(frr);

随机数生成算法:

%书上50页
function [row,col]=randinterval(matrix,count,key)
%计算间隔的位数
[m,n]=size(matrix);
interval1=floor(m*n/count)+1;
interval2=interval1-2;
if interval2==0
    error('载体太小,不能将私密信息隐藏进去');
end
%生成随机序列
rand('seed',key);
a=rand(1,count);
%初始化
row=zeros([1 count]);
col=zeros([1 count]);
%计算row,col
r=1;
c=1;
row(1,1)=r;
col(1,1)=c;
for i=2:count
    if a(i)>=0.5
        c=c+interval1;
    else
        c=c+interval2;
    end
    if c>n
        r=r+1;
        if r>m
            error('载体太小,不能私密信息隐藏进去');
        end
        c=mod(c,n);
        if c==0
            c=1;
        end
    end
    row(1,i)=r;
    col(1,i)=c;
end

3.计算误码率的算法——分别对含有秘密信息的图像载体进行攻击,攻击方式为jpeg压缩,resize缩放,根据不同的压缩比例,缩放比例的分别计算误码率并显示如下:

这部分代码是参考别人的博客编写的:https://blog.csdn.net/cheeseandcake/article/details/52997903?locationNum=11&fps=1

扫描二维码关注公众号,回复: 2360915 查看本文章
function ber_resize=calcute_resize_ber(input,messagefile,len_total,key)
for resize =0.5:1:10
%读取已经隐藏信息的图像。
fp=imread(input);
%使用 imresize 函数对图像进行缩放,设定缩放比例。
output=imresize(fp,resize,'bicubic'); %利用双三次插值方法将 Ifp放大 size 倍
intchanged=double(output);
%p作为消息嵌入位计数器,将消息序列写回文本文件
p=1;
%调用随机间隔函数选取像素点
[row,col]=randinterval(intchanged,len_total,key);
for i=1 :len_total
    if bitand(intchanged(row(i),col(i)),1)==1
        result(p,1)=1;
    else
        result(p,1)=0;
    end
    if p ==len_total
        break;
    end
    p=p+1;
end
%读取原文件,即隐藏的信息,以二进制读取。并取得消息长度
message=fopen(messagefile,'r'); 
%按位以二进制形式读取文本内容与长度
[msg,len_total]=fread(message,'ubit1');
%比较取得的信息和原信息的每一位,记录不相等位数的个数。
bit_error=find(result~=msg); %寻找不相等的位置 
bit_error_count=size(bit_error,1); %统计不相等的个数
%用不相等个数除以总长度即可得到误码率ber
ber_resize(resize+0.5)=bit_error_count/len_total;
end
% plot参数说明: 
% 参数1是横坐标自变量,参数2是纵坐标自变量,参数3是指用说明形式描点,参数4和5代表把散点链接起来 
resize=0.5:1:10; 
plot(resize,ber_resize,'*',resize,ber_resize); 
title('基于图片缩放质量的误码率图表');
function ber_jpeg=calcute_jpeg_ber(input,output,messagefile,len_total,key)
for compressibility=10:10:100 
%Compressiblity是图像的质量因子,可设置在0-100范围内
%compressibility=90;
%读取已经隐藏信息的图像。
fp=imread(input);
%使用 imwrite 函数对图像进行压缩,设定压缩比例。
imwrite(fp,output,'quality',compressibility);
intchanged=imread(output);
intchanged=double(intchanged);
%p作为消息嵌入位计数器,将消息序列写回文本文件
p=1;
%调用随机间隔函数选取像素点
[row,col]=randinterval(intchanged,len_total,key);
for i=1 :len_total
    if bitand(intchanged(row(i),col(i)),1)==1
        result(p,1)=1;
    else
        result(p,1)=0;
    end
    if p ==len_total
        break;
    end
    p=p+1;
end
%读取原文件,即隐藏的信息,以二进制读取。并取得消息长度
message=fopen(messagefile,'r'); 
%按位以二进制形式读取文本内容与长度
[msg,len_total]=fread(message,'ubit1');
%比较取得的信息和原信息的每一位,记录不相等位数的个数。
bit_error=find(result~=msg); %寻找不相等的位置 
bit_error_count=size(bit_error,1); %统计不相等的个数
%用不相等个数除以总长度即可得到误码率ber
ber_jpeg(compressibility/10)=bit_error_count/len_total;
end
% plot参数说明: 
% 参数1是横坐标自变量,参数2是纵坐标自变量,参数3是指用说明形式描点,参数4和5代表把散点链接起来 
compressibility=10:10:100; 
plot(compressibility,ber_jpeg,'*',compressibility,ber_jpeg); 
title('基于图片压缩质量因子的误码率图表');

4.计算水印相关系数PSNR——PSNR值越大,图像质量越好:

function PSNR=calcute_psnr(input,inputchange)
img=imread(input);  
[h,w]=size(img);  
%imgn=imresize(img,[floor(h/2) floor(w/2)]);  
%imgn=imresize(imgn,[h w]); 
imgn=imread(inputchange);
img=double(img);  
imgn=double(imgn);  
%编码一个像素用多少二进制位    
B=8;  
%图像有多少灰度级  
MAX=2^B-1;         
MES=sum(sum((img-imgn).^2))/(h*w);     %均方差  
PSNR=20*log10(MAX/sqrt(MES));           %峰值信噪比

猜你喜欢

转载自blog.csdn.net/wmrem/article/details/80922808