信息隐藏与数字水印实验:图片类隐写(MATLAB)

一、在BMP图像中隐藏数据

1、在图像文件尾部添加任意长度的数据,仅需修改文件头中文件长度的值即可。 
2、如果将秘密数据放在文件头与图像数据之间,则至少需要修改文件头中文件长度、数据起始偏移地址这两个域的值。 
3、修改文件头和信息头中保留字段隐藏信息。 
4、在图像像素区利用图像宽度字节必须是4的倍数额特点,在补足位处隐藏数据。
在这里插入图片描述

实验一:在BMP图像数据后隐藏数据

待隐藏的密码信息文件名称为:hidden.txt(里面有6个a),pic1.bmp 为载体图像,将载体和秘密信息放置在同一目录下,在Windows的CMD中执行命令:

Copy pic1.bmp /b + hidden.txt /a pic11.bmp

执行该命令后,生成一个新的pic11.bmp文件,使用图像浏览工具浏览该文件会发现它与原始载体图像几乎完全相同。
信息隐藏在pic11.bmp文件的尾部
从BMP图像的结构中可知,图像的3、4、5、6四个字节表示整个BMP图像的长度(大小)。使用该方式隐藏信息时,未修改图像文件的文件长度字节,通过比较文件的实际长度和文件中保存的文件长度,就可发现该图像是否隐藏秘密信息。

clc;
clear;
fid=fopen('pic11.bmp','r');
[a,length]=fread(fid,inf,'uint8');
status=fseek(fid,2,'bof'); 
fileb=fread(fid,4,'uint8'); 
filelength=fileb(1)*1+fileb(2)*256+fileb(3)*256^2+fileb(4)*256^3; 
diff=length-filelength; 
fclose(fid);
clc;
clear;
fid=fopen('pic11.bmp','r');
	% 以只读方式打开pic11.bmp图像文件,该文件必须存在,fid用于存储文件句柄值
[a,length]=fread(fid,inf,'uint8');
	% 创造存放读取数据的矩阵,length中返回所读取的数据元素个数
	% inf读出fid指向的打开文件的全部数据
% fclose(fid);
	% 关闭fid所表示的文件,文件在进行完读、写等操作后,应及时关闭以免数据丢失
% fid=fopen('pic11.bmp','r');
status=fseek(fid,2,'bof'); 
	% fseek函数用于定位文件位置指针,fid为文件句柄,
	% offset(第2个参数)表示位置指针相对移动的字节数,“2”指的是跳过前两个文件标识字节
	% origin(第3个参数)表示位置指针移动的参照,'bof',表示文件头;'cof',表示当前位置 ;'eof',表示文件尾
fileb=fread(fid,4,'uint8'); 
	% 读取4个元素(就是文件大小),精度为uint8
filelength=fileb(1)*1+fileb(2)*256+fileb(3)*256^2+fileb(4)*256^3; 
	% 把这4个字节转换成大小
diff=length-filelength; 
	% 有差值,可发现该图像隐藏秘密信息
fclose(fid);

在这里插入图片描述

实验二:在文件头与图像数据之间隐藏信息

clear;
clc;
fid=fopen('pic1.bmp','r');
[a,length]=fread(fid,inf,'uint8');
fclose(fid);
msgfid=fopen('hidden.txt','r');
[msg,count]=fread(msgfid,inf,'uint8');
fclose(msgfid);
wa=a;
wa(3)=wa(3)+count;
	% 图像头(从3开始)+ 隐藏文件内容的字节
wa(11)=wa(11)+count;
	% 000A-000D:从文件开始到图像数据之间的偏移量
	% 偏移量 + 隐藏文件内容的字节
j=1;
for i=55:55+count-1
    wa(i)=msg(j,1); % msg(行,列)
    j=j+1;
end
	% 文件头有54个字节(从0开始算),从55个字节开始藏
for i=55:length
    wa(i+count)=a(i);
end
	% 把原来的图像信息往后面移动要隐藏的信息长度
new=fopen('newpic11.bmp','wb'); % wb:只写打开或新建一个二进制文件
fwrite(new,wa);
	% 数组wa的元素按 列顺序 以 8 位无符号整数的形式写入二进制文件new
figure;
imshow('newpic11.bmp');

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
36(16)=54,3C(16)=60,61(16)=97=a(ASCII)

二、图像LSB隐写

最低有效位( least significant bit,LSB)指的是一个二进制数字中的第0位(即最低位)。

实验一:在图像中嵌入相同分辨率的二值图像

将BMP图像pic2.bmp转换为二值图像,并将其嵌入相同分辨率的RGB图像pic1.bmp的任一层(R层、G层或B层灰度图像)的最低位平面。

clear;
clc;
I=imread('pic1.bmp');
J=I;
JR=J(:,:,1);
L=imread('pic2.bmp');
BW=im2bw(L);	
set1=bitset(JR,1,BW);
	% 将JR转换成二进制,并将其右边第一个位置(即最低位)换成BW的值
J(:,:,1)=set1;
get1=bitget(J(:,:,1),1);
	% 输出J(:,:,1)最低位的数值
figure;
subplot(2,2,1);imshow(I);title('原图');
subplot(2,2,2);imshow(BW);title('待嵌入原图的二值图');
subplot(2,2,3);imshow(J);title('嵌后图像');
subplot(2,2,4);imshow(get1,[]);title('取出嵌入的图像'); % 加[]让图像自适应显示

在这里插入图片描述

实验二:在图像中嵌入不同分辨率的二值图像

将lena.jpg图像嵌入到不同分辨率RGB图像pic1.bmp任一层(R层、G层或B层灰度图像)的最低位平面并提取。

clear;
clc;
I=imread('pic1.bmp');
L=imread('lena.jpg');
BW=im2bw(L);
J=double(I);
[m,n]=size(BW);
[l,w]=size(I);
if or(m>l,n>w/3)
    error('嵌入信息量过大,请重新选择图像');
end
for i=1:m
    for j=1:n
        J(i,j,1)=J(i,j,1)-mod(J(i,j,1),2)+BW(i,j);
        % 把J的红色图层最低位清空换成二值图像BW相应的行列值
    end
end
M=bitget(J(:,:,1),1);
J=uint8(J);
imwrite(J,'embedded.bmp'); % embed vt.嵌入
figure;
subplot(221);imshow(I);
subplot(222);imshow(BW);
subplot(223);imshow('embedded.bmp');
subplot(224);imshow(M);

在这里插入图片描述

三、直接4bit替换法

图像的低4bit,通常可以做隐藏信息的空间,也就是载体的冗余空间。
直接4bit替换法,就是直接用秘密图像像素值的高4bit去替换载体图像像素值的低4bit

目的:把rice.png(256×256)藏到baboon.bmp(512×512)
不同分辨率直接4位替换法:

clear;
clc;
I=imread('baboon.bmp');
msg=imread('rice.png');
[row,col]=size(msg);
IR=I(:,:,1);
[m,n]=size(IR);
if or(row>m,col>n)
    error('嵌入信息量过大,请重新选择图像');
end
for i=1:row
    for j=1:col
        IR(i,j)=bitand(IR(i,j),240); % 240转二进制为11110000
    end
end
	% 置载体图像R层的低4bit为0 
figure;imshow(IR);
figure;imshow(msg);                      
takemsg4=bitand(msg,240);
	% 置秘密图像的低4bit为0      
figure;imshow(takemsg4);
shiftmsg4=bitshift(takemsg4,-4);
	% 将秘密图像的高4bit右移4位
figure;imshow(shiftmsg4,[]);
for i=1:row
    for j=1:col
        IR(i,j)=bitor(IR(i,j),shiftmsg4(i,j));
    end
end
	% 图像隐藏
I(:,:,1)=IR;
	% 写回并保存
figure;imshow(I);
imwrite(I,'bit4hide.bmp');

不同分辨率直接4位替换法提取

clear;
clc;
I=imread('bit4hide.bmp');
[row,col]=size(I)
A=I(:,:,1);
for i=1:row/2 % 这里除以2是为了完整显示rice.png,下图展示的是不除2的
    for j=1:col/3/2
        M(i,j)=bitand(A(i,j),15); % 1111
    end
end
M=bitshift(M,4);
imshow(M);

在这里插入图片描述

四、灰度图8位分别藏于RGB层

将灰度图rice.png的8位像素数据分别藏于载体图像baboon.bmp的R、G、B层像素值的低几位:

clear;
clc;
I=imread('baboon.bmp');
J=imread('rice.png');
[row,col]=size(J);
for h=1:3
for i=1:row
    for j=1:col
        I(i,j,h)=bitand(I(i,j,h),248);	% 1111 1000
    end
end
end
figure;
subplot(221);imshow(I);
subplot(222);imshow(I(:,:,1));
subplot(223);imshow(I(:,:,2));
subplot(224);imshow(I(:,:,3));
Y=bin2dec('11100000'); % 224
y1=bitshift(Y,-3);
y2=bitshift(Y,-6);
for h=1:3
    M=bitand(J(1:row,1:col),bitshift(Y,-3*(h-1)));
    shiftM=bitshift(M,h*3-8);
    I(1:row,1:col,h)=bitor(I(1:row,1:col,h),shiftM);
end
figure;imshow(I);
imwrite(I,'fullhide.bmp');

将上题中隐藏的灰度图提取出来并保存:

clear;
clc;
I=imread('fullhide.bmp');
for h=1:3
for i=1:256
    for j=1:256
        I(i,j,h)=bitand(I(i,j,h),7); % 0111
    end
end
end
figure;
subplot(221);imshow(I,[]);
subplot(222);imshow(I(:,:,1));
subplot(223);imshow(I(:,:,2));
subplot(224);imshow(I(:,:,3));
K=uint8(zeros(256,256));
for h=1:3
    M=bitshift(I(1:256,1:256,h),8-h*3); % 向左移动8-h*3位,5、2、-1
    K=bitor(K,M);
end
imwrite(K,'riceget.bmp');
figure;imshow('riceget.bmp');

五、图片中隐藏文本信息

目的:实现文本信息在载体图像中的伪随机位置的信息隐藏并提取文本信息。

1、编写伪随机序列发生函数randinterval.m

function [row,col]=randinterval(map,count,key)
[m,n]=size(map);
interval1=floor(m*n/count)+1; % 向下取整,即取不大于m*n/count的最大整数
interval2=floor(m*n/count)-1;
if interval2==0
    error('载体太小,请重新选择载体图像');
end
rand('seed',key);   % 生成随机序 
a=rand(1,count);
row=zeros(1,count);  % 初始化
col=zeros(1,count);
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

2、编写程序binhide.m,完成功能:将文本信息hidden.txt嵌入pic1.bmp图像中的某一层的伪随机位置

clear;
clc;
I=imread('pic1.bmp');
IR=I(:,:,1);
cover=double(IR);
fid=fopen('hidden.txt','r');
[msg,len_total]=fread(fid,inf,'ubit1');
[m,n]=size(cover);
if len_total>m*n
    error('嵌入信息量过大,请重新选择图像');
end
[row,col]=randinterval(cover,len_total,2021);
p=1;
for i=1:len_total
    cover(row(i),col(i))=cover(row(i),col(i))-mod(cover(row(i),col(i)),2)+msg(p,1);
    if p==len_total
        break;
    end
    p=p+1;
end
cover=uint8(cover);
I(:,:,1)=cover;
imwrite(I,'randhide.bmp');
M=cover-IR;
figure;imshow(M,[]);
figure;imshow('randhide.bmp');
fclose(fid);

在这里插入图片描述
在这里插入图片描述

3、编写程序binget.m,将上题中隐藏的文本信息提取出来,并保存在binget.txt中

clear;
clc;
I=imread('randhide.bmp');
IR=double(I(:,:,1));
count=11520;
[row_1,col_1]=randinterval(IR,count,2021);
fid=fopen('binget.txt','a');
for i=1:count
    fwrite(fid,mod(IR(row_1(i),col_1(i)),2),'ubit1');
end
fclose(fid);
  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值