LSB图像信息隐藏实验(附源代码)

一、【实验目的】

1.掌握对图像的基本操作。

2.能够用 LSB 算法对图像进行信息隐藏

3.能够用 LSB 提取算法提取隐藏进图像的信息

4.能够反映 jpeg 压缩率与误码率之间的关系

二、【实验环境】
Win7系统 Matlab软件

三、【实验过程】

实验算法 1:LSB 嵌入

1.读取一副 256*256 大小的图片,判断是否为 RGB 图像。若为 RGB 图像,则读取图像的一层信息(如 R 层)。

通过读取图像的尺寸大小来判断是否为RGB图像。RGB图像是三维多彩图,size有3个参数,最小参数是3,只要判断读取到的图像大小大于2,就确定读入的是RBG图像

image=imread('1.jpg');
mysize=size(image);
if numel(mysize)>2
   ['the photo is a rgb style photo'] %是rgb图像输出到命令行窗口
image1=Hide_image(:,:,1);
%第三个参数 1代表的读取的是红层,但是没有将2,3层设为0,因为会叠加,所以显示出来的第一层图像还是灰色的

2.以二进制形式读取要嵌入到图片里的消息。并读取消息的长度(嵌入消息的长度不能超过图像位数)。

message=fopen('message.txt','r');
[msg,msg_len]=fread(message,'ubit1') %按位以二进制形式读取文本内容与长度
[m,n]=size(image1)  %读取bin_iamge1的行和列
Msg就是二进制的文本内容,msg_len就是二进制长度

3.产生与消息长度一致的一串随机数(不能相同)。

自定义一个randinterval函数来实现伪随机数的生成
产生的伪随机数是代表消息要隐藏的像素位置(行和列的信息)

%function[row,col]=randinterval(matric,count,key)
% 三个参数说明
% matrice为载体矩阵,即要隐藏信息的图层
% count为要嵌入信息的像素数量
% key为秘钥,随机数种子,自己设定
[row,col]=randinterval(image1,msg_len,1996);

4.按照产生的随机数的序列依次将图片层的最后一位改为消息的信息。即用消息替换图片的最后一位信息。

for i=1:msg_len
    image1(row(i),col(i))=image1(row(i),col(i))-mod(image1(row(i),col(i)),2)+msg(p,1);
    if p==msg_len
        break;
    end ;
    p=p+1;
End

最后一位对图片的影响最小,几乎是肉眼无法识别的。如果是最高位,那么图片就会发生明显的改变

5.嵌入完成后,如果为 RGB 则将该层返回原图像。然后将数据信息写回图像。LSB 就完成了。

%还原图像,就是把嵌入隐藏信息的红层赋值给原图像的红层
Hide_image(:,:,1)=image1;
Hide_image=uint8(Hide_image);
imwrite(Hide_image,'Hide_image.tif');
%输出隐藏信息的图像
subplot(121);imshow(image);title('未嵌入信息的图片');
subplot(122);imshow(Hide_image);title('嵌入信息的图片');

LSB完成后,对比隐藏信息嵌入前后的图片:

结论:可以发现,嵌入信息前后,图片并没有发生肉眼可见的任何改

变,说明该LSB信息隐藏是比较成功的。

————————————————-

实验算法 2:读取 LSB 隐藏的信息

1.读取已经隐藏信息的图像。如果为 RGB 图像,则读取图像的一层(该层为嵌入信息的那层)。

2.用与 LSB 算法中相同的随机数种子产生相同的一串随机数。随机数串的长度由 LSB 中获得(长度不得大于图像大小)。

用同一个伪随机生成算法,相同的种子,来产生像素点位置,可以确保隐藏时和提取时位置顺序是一模一样的,在顺序读取这些位置上的数据(利用与运算,与上1,任何数与上1还是本身的性质),就是隐藏的信息。
[row,col]=randinterval(Picture_R,msg_len,1996);

3.按照产生的随机数序列依次读取图像的相应点最后一位的信息。并将其以二进制形式写到文件中。

for i=1:msg_len
    if bitand(Picture_R(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==msg_len
        break;
    end
        p=p+1;
end
%fwrite函数的作用是将内存中的二进制数据原样写入文件中
%是ubit后面的数字表示是一次读几位,中间的数据表示读几次。

Ubit1就代表每次读取1位,写入文件,每8位识别一个ASCII码值。所以可以成功写入26个字母和数字。其他字符由于文本文档识别不了,所以写入文本之后都变成了乱码。

4.看文件,即获取的信息,与嵌入的信息进行比较。

Message.txt是原始信息文档,txt是提取出来的信息文档,可以发现

二者信息内容是一模一样的,说明隐藏信息提取是成功的。

这里写图片描述


实验算法 3: JPEG 压缩率与误码率之间的关系

1.读取已经隐藏信息的图像。

fp=imread(‘Hide_image.tif’);

2.使用 imwrite 函数对图像进行压缩,设定压缩比例。

imwrite(fp,’out.jpg’,’quality’,compressibility)
Compressiblity是图像的质量因子,可设置在0-100范围内;

3.如果为 RGB 图像,则读取嵌有信息的一层。按照读取 LSB 隐藏信息算法的步骤,读取 信息,不写入文件。
out=imread('out.jpg');
if size(fp)>2
outr=out(:,:,1);
[m,n]=size(outr);
msg_len=184;
p=1;
[row,col]=randinterval(outr,msg_len,1996);
for i=1:msg_len
if bitand(outr(row(i),col(i)),1)==1 %按位与运算
result(p,1)=1;
else
result(p,1)=0;
end
if p==msg_len
break;
end
p=p+1;
end

4.读取原文件,即隐藏的信息,以二进制读取。并取得消息长度。

message=fopen(‘message.txt’,’r’);
[msg,msg_len]=fread(message,’ubit1’)
%按位以二进制形式读取文本内容与长度

5.比较取得的信息和原信息的每一位,记录不相等位数的个数。
bit_error=find(result~=msg); %寻找不相等的位置
bit_error_count=size(bit_error,1); %统计不相等的个数

6.用不相等个数除以总长度即可得到误码率ber。
ber(compressibility/10)=bit_error_count/msg_len;

7.改变压缩率。得到一组误码率关于压缩率的函数。

在开始时,设置9次循环,压缩图片的质量因子compressibility从10开始增加,每次递增10,直到compressibility=100,记录下每次的误码率,用plot函数做出关于以质量因子为横坐标,误码率为纵坐标的图表。
for compressibility=10:10:100 %九次不同压缩率的图片压缩
fp=imread(‘Hide_image.tif’);
imwrite(fp,’out.jpg’,’quality’,compressibility)

% plot参数说明:
% 参数1是横坐标自变量,参数2是纵坐标自变量,参数3是指用说明形式描点,参数4和5代表把散点链接起来
compressibility=10:10:100;
plot(compressibility,ber,’*’,compressibility,ber);
title(‘基于图片压缩质量因子的误码率图表’);
实验结果:
这里写图片描述

结论:LSB算法抗JPEG压缩能力很弱,即使只是进行微压,误码率也能高达0.5极其以上。

四、【实验日志】
1.当文本文档的写入方式为bit时,电脑会向文本文档中写入数据,但是打开时会显示一片空白。
这里写图片描述

改成ubit 后,就可以正常显示了。
这里写图片描述
2.在图片压缩算法中,刚开始没有在plot输出图像函数前加上压缩骗徒质量因子的数组,所以输出图像只有一个压缩率,但是对应很多个误码率。
这里写图片描述

上图说明我的压缩图片质量因子只读取了最后一个质量因子,所以在输出图像的时候,应该再增加一个质量因子的数组。
compressibility=10:10:100;

然后就可以输出正确的对应点。如下图:

这里写图片描述

3.当输入的文本信息是非法字符时(即除了26个字母和数字外),提取出来的文件信息会是乱码!

这里写图片描述

五、【实验小结】

经过这次实验操作,对matlab词法分析有了更深的了解,开始熟练使用matlab的一些关于图片处理的方法和函数

列表内容

,对LSB有了更加深入地理解和认识,能够通过代码来实现具体操作。对于各种错误,也稍微直到解决的办法。

LSB优点:
① 算法简单,便于实现,计算速度快;
② 在基础算法上能很快的进行改进,并在脆弱水印中广泛应用;
③ 由于能在最低有效位进行嵌入,所以对于图像影响很小,几乎无法用肉眼识别;

LSB缺点:
① 嵌入消息较大似乎,耗时长;
② 只能处理简单的流格式的文件;
③ 为满足水印的不可见性,允许嵌入的水印强度较低,对于空域的各种操作较敏感;
④ 基本的LSB抗JPEG压缩能力差;
⑤ 鲁棒性差;

附源码:
1.信息隐藏

image=imread(‘1.jpg’);
Hide_image=image;
Hide_image=double(Hide_image);
mysize=size(image);
if numel(mysize)>2
[‘the photo is a rgb style photo’] %是rgb图像输出到命令行窗口
image1=Hide_image(:,:,1);
message=fopen(‘message.txt’,’r’);
[msg,msg_len]=fread(message,’ubit1’) %按位以二进制形式读取文本内容与长度
[m,n]=size(image1) %读取bin_iamge1的行和列

p=1; %p为秘密信息的位计数器
[row,col]=randinterval(image1,msg_len,1996);

for i=1:msg_len
image1(row(i),col(i))=image1(row(i),col(i))-mod(image1(row(i),col(i)),2)+msg(p,1);
if p==msg_len
break;
end ;
p=p+1;
end

%还原图像
Hide_image(:,:,1)=image1;
Hide_image=uint8(Hide_image);
imwrite(Hide_image,’Hide_image.tif’);
%输出隐藏信息的图像
subplot(121);imshow(image);title(‘未嵌入信息的图片’);
subplot(122);imshow(Hide_image);title(‘嵌入信息的图片’);

else [‘the photo is not a rgb style’]
fclose(‘all’);
end

2.隐藏信息提取
%功能:用来提取隐藏信息
Picture=imread(‘Hide_image.tif’);
Picture=double(Picture);
Picture_R=Picture(:,:,1);
[m,n]=size(Picture_R);
frr=fopen(‘txt’,’w’); %以写入方式打开只写文件
msg_len=184;
p=1;
[row,col]=randinterval(Picture_R,msg_len,1996);
for i=1:msg_len
if bitand(Picture_R(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==msg_len
break;
end
p=p+1;
end
fclose(frr);
%fwrite函数的作用是将内存中的二进制数据原样写入文件中
%是ubit后面的数字表示是一次读几位,中间的数据表示读几次。

3.基于图片压缩率的误码率关系
close all;
clc;

for compressibility=10:10:100
fp=imread(‘Hide_image.tif’);
imwrite(fp,’out.jpg’,’quality’,compressibility)
out=imread(‘out.jpg’);
out=double(out);
if size(fp)>2
outr=out(:,:,1);
[m,n]=size(outr);
msg_len=184;
p=1;
[row,col]=randinterval(outr,msg_len,1996);
for i=1:msg_len
if bitand(outr(row(i),col(i)),1)==1 %按位与运算
result(p,1)=1;
else
result(p,1)=0;
end
if p==msg_len
break;
end
p=p+1;
end
message=fopen(‘message.txt’,’r’);
[msg,msg_len]=fread(message,’ubit1’) %按位以二进制形式读取文本内容与长度

bit_error=find(result~=msg); %寻找不相等的位置
bit_error_count=size(bit_error,1); %统计不相等的个数
ber(compressibility/10)=bit_error_count/msg_len;

end
end

% plot参数说明:
% 参数1是横坐标自变量,参数2是纵坐标自变量,参数3是指用说明形式描点,参数4和5代表把散点链接起来
compressibility=10:10:100;
plot(compressibility,ber,’*’,compressibility,ber);
title(‘基于图片压缩质量因子的误码率图表’);

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页