matlab图像增强-利用位面图传输密文

2020.10.4更新:

发现虽然在图像中加入密文成功,但在利用函数imwrite()保存图像时,因为格式jpg为压缩格式,实际上对图像数据进行了变换,属于有损压缩。

因此需要选择矢量图的保存方式,如bmp.因此原本上传的图像无法正常解密,现在更新的图像可以。此处感谢@yezixuan的指正!

任务

数字图像课程中一个很有趣的一个地方是位面图,即把灰度图的8位拆解,并将各位输出图像。但前面的高位体现出图像的细节,低位几乎没有影响。因此老师提到一个思路是通过图像传输密文,这里进行模拟体验。

过程

获取位面图

首先将图片转为灰度图,再将灰度值用二进制编码表示,最终得到各平面的结果。

下面代码是第8位(最低位)的位面图输出过程,其他各位相似。

grayImg=rgb2grayL(Img);
[M,N]=size(grayImg);
%% 将10进制转化为2进制
binImg=dec2bin(grayImg,8);
subplot(subplotN,subplotM,9)
imshow(Img)
title('原图');
a8=uint8(reshape(binImg(:,8),M,N));
subplot(subplotN,subplotM,8)
imshow(a8,[])
title('8bit');

位面图像

加密

利用工具:汉字二进制转换器。将需要传递的文字信息转化为二进制编码。

下一步,只需要将二进制编码以约定形式集成到图片中,再通过叠加传输至对方手中,进行解密即可。

字符串切分

在工具中将utf-8编码的汉字转化为二进制,根据网页提供的资料可知,每个汉字对应的编码为3字节,即占据3*8bit=24bit。

不同的字符集对同一个多字节字符的编码可能不同,并且对其编码的字节数也可能不同。例如“中”字,Unicode使用4字节表示,UTF-8使用3字节,GB18030则使用2字节不同的编码表示。所以在汉字与二进制转换中需要考虑到字符的编码,通常,按照UTF-8编码与二进制进行转换。

汉字二进制转换器

因为matlab提供字符串分割函数split(str,' '),与python中用法相同,即将字符串str用引号内的字符分割开来,且引号中的字符被舍去。

hint:与split()形成反函数的对应函数为join(),可以将得到的密文字符串重新合并。

需要注意的问题是,应用函数split()后得到的是cell类型的数组,不可能直接赋值给char类型的数组,需要强制类型转换。

%% 先将M*Nx1大小的字符最低位数组reshape为MXN大小的数组matA1
% 并将加密编码写入
matA8=reshape(binImg(:,8),M,N);
codeLen=24;
binStr=['用工具汉字二进制转换器得到的密文对应的二进制编码'];
% 用空格分割
subStrs=split(binStr,' ');
[num,~]=size(subStrs);
% 写入加密编码
matA8(1:num,1:codeLen)=char(subStrs);
%% 再将加密编码写入后的MXN大小的数组matA1reshape为M*Nx1大小的字符最低位数组
% 并重新叠加至原图
binImg(:,8)=reshape(matA8,M*N,1);
codeImg=uint8(reshape(bin2dec(binImg),[M,N]));
%% 显示图片
figure(2)
imshow(codeImg)
title('加密图');
imwrite(codeImg,'codeImg.jpg')

加密效果

由于只更改了部分像素点灰度值的最末位,故显示在灰度图上肉眼不可区分,能够实现传输密文功能。

解密

下面是添加密文之后得到的图片,全部过程已经包含在代码中。有兴趣的朋友可以尝试解密,成功者惊喜奉上。

下载图片链接

Leave a comment

Your email address will not be published. Required fields are marked *