一、【实验目的】
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信息隐藏是比较成功的。
实验算法 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(‘基于图片压缩质量因子的误码率图表’);