图片嵌入隐藏-大容量的信息隐藏算法

2024-04-04 10:38

本文主要是介绍图片嵌入隐藏-大容量的信息隐藏算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  今天分享一下最近看到的一个图片嵌入隐藏的算法。

  这是一种基于空间域的自适应多平面位的信息隐藏算法。该算法计算复杂度低、信息隐藏量大。且有实验表明在不影响图像视觉效果的前提下,其信息隐藏量比LSB算法大,并具有更高的安全性。该算法的主要思想是对每个像素点进行判断,根据HVS的特性,在最高非0有效位后的指定位(y)开始嵌入隐藏信息,嵌入到另一个指定位(z)为止。

  下面直接贴上MATLAB代码和实验结果:


%下面是主函数main_ImgEmbed.m
clc;
clear all;
close all;
warning off all;yr=4;
yg=5;
yb=3;Img=imread('介质图片.jpg');
figure;imshow(Img,[]);title('介质图片');Img=double(Img);
ImgR=Img(:,:,1);
ImgG=Img(:,:,2);
ImgB=Img(:,:,3);Imgmark=imread('待嵌入图片_gray.jpg');
Imgmark=double(Imgmark);
figure;imshow(Imgmark,[]);title('待嵌入图片_gray');
[markm,markn]=size(Imgmark);
Imgmarkline = Imgmark(:); %二维数组转成一列Imgmarklinebin=zeros(markm*markn*8,1); %转化为二进制
for ii=1:markm*markn[Imgmarklinebin(8*ii-7),Imgmarklinebin(8*ii-6),Imgmarklinebin(8*ii-5),Imgmarklinebin(8*ii-4),Imgmarklinebin(8*ii-3),...Imgmarklinebin(8*ii-2),Imgmarklinebin(8*ii-1),Imgmarklinebin(8*ii)]=Find8bits(Imgmarkline(ii));   
end%%
%嵌入
%对于红色通道
embedNumsed=0;%已嵌入个数
[M,N,Z]=size(Img);
y=zeros(8,1);
flag=0; %辅助跳出的标志ImgRline=ImgR(:); %转换为一列
ImgRlineNew=ImgRline; %嵌入后
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgRline(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yr; %能嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsembedNumsed=embedNumsed+1; %已嵌入个数if embedNumsed>markm*markn*8 %嵌入完成flag=1; %设置标识,使外层循环也跳出break;end y(jj)=Imgmarklinebin(embedNumsed);%嵌入end  end  ImgRlineNew(ii)=bin2dec_trans(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));%嵌入后的  
end
ImgR2=reshape(ImgRlineNew,[M,N]);%对于G通道
ImgGline=ImgG(:); %转换为一列
ImgGlineNew=ImgGline; %嵌入后
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgGline(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yg; %能嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsembedNumsed=embedNumsed+1; %已嵌入个数if embedNumsed>markm*markn*8 %嵌入完成flag=1; %设置标识,使外层循环也跳出break;end y(jj)=Imgmarklinebin(embedNumsed);%嵌入 end  end  ImgGlineNew(ii)=bin2dec_trans(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));%嵌入后的  
end
ImgG2=reshape(ImgGlineNew,[M,N]);%对于B通道
ImgBline=ImgB(:); %转换为一列
ImgBlineNew=ImgBline; %嵌入后
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgBline(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yb; %能嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsembedNumsed=embedNumsed+1; %已嵌入个数if embedNumsed>markm*markn*8 %嵌入完成flag=1; %设置标识,使外层循环也跳出break;end y(jj)=Imgmarklinebin(embedNumsed);%嵌入 end  end  ImgBlineNew(ii)=bin2dec_trans(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));%嵌入后的  
end
ImgB2=reshape(ImgBlineNew,[M,N]);ImgNew=zeros(M,N,Z);
ImgNew(:,:,1)=ImgR2;
ImgNew(:,:,2)=ImgG2;
ImgNew(:,:,3)=ImgB2;figure;imshow(uint8(ImgNew),[]);title('嵌入后的RGB图');
imwrite(uint8(ImgNew),'介质图片_嵌入图像后.jpg'); %保存图片%%
%提取嵌入图像
flag=0;
Imgmark_extractlinebin=zeros(markm*markn*8,1);
extractNumsed=0;%已提取个数% R通道
ImgRline2=ImgR2(:); %转换为一列
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgRline2(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yr; %已嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsextractNumsed=extractNumsed+1; %已提取个数if extractNumsed>markm*markn*8 %提取完成flag=1; %设置标识,使外层循环也跳出break;end Imgmark_extractlinebin(extractNumsed)=y(jj);%提取end  end  
end% G通道
ImgGline2=ImgG2(:); %转换为一列
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgGline2(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yg; %已嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsextractNumsed=extractNumsed+1; %已提取个数if extractNumsed>markm*markn*8 %提取完成flag=1; %设置标识,使外层循环也跳出break;end Imgmark_extractlinebin(extractNumsed)=y(jj);%提取end  end  
end% G通道
ImgBline2=ImgB2(:); %转换为一列
for ii=1:M*Nif flag==1; %跳出外层循环break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=Find8bits(ImgBline2(ii));   posNzreo=FindNotZero(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNums=posNzreo-yb; %已嵌入的个数if  embedNums>0 %符合嵌入条件for jj=1:embedNumsextractNumsed=extractNumsed+1; %已提取个数if extractNumsed>markm*markn*8 %提取完成flag=1; %设置标识,使外层循环也跳出break;end Imgmark_extractlinebin(extractNumsed)=y(jj);%提取end  end  
end%二进制转十进制
Imgmarklinedec=zeros(markm*markn,1); %转化为十进制
for ii=1:markm*markn Imgmarklinedec(ii)=bin2dec_trans(Imgmark_extractlinebin(8*ii-7),Imgmark_extractlinebin(8*ii-6),Imgmark_extractlinebin(8*ii-5),Imgmark_extractlinebin(8*ii-4),...Imgmark_extractlinebin(8*ii-3),Imgmark_extractlinebin(8*ii-2),Imgmark_extractlinebin(8*ii-1),Imgmark_extractlinebin(8*ii));
end
Imgmarkextract=reshape(Imgmarklinedec,[markm,markn]);
figure;imshow(Imgmarkextract,[]);title('提取的水印');
imwrite(uint8(Imgmarkextract),'待嵌入图片_gray_提取结果.jpg'); %保存图片%检查提取的水印和原水印的区别
difmarked=Imgmarkextract-Imgmark; %做差  
%发现差为0,即说明完全一致,提取正确



3个子函数:

(1)

%bin2dec_trans.m
%二进制转十进制
function Data=bin2dec_trans(y7,y6,y5,y4,y3,y2,y1,y0)Data=y7*128+y6*64+y5*32+y4*16+y3*8+y2*4+y1*2+y0;
end


(2)

% Find8bits.m
function [y7,y6,y5,y4,y3,y2,y1,y0]=Find8bits(Data)
y0=mod(Data,2);
y7=fix(Data/128);Data=Data-y7*128;
y6=fix(Data/64); Data=Data-y6*64;
y5=fix(Data/32); Data=Data-y5*32;
y4=fix(Data/16); Data=Data-y4*16;
y3=fix(Data/8);  Data=Data-y3*8;
y2=fix(Data/4);  Data=Data-y2*4;
y1=fix(Data/2);  Data=Data-y1*2;
end


(3)

%FindNotZero.m
%找出第一个不为零的数位 从最高位(第八位)开始
function posNzreo=FindNotZero(y7,y6,y5,y4,y3,y2,y1,y0)
if y7~=0      posNzreo=8;
elseif y6~=0  posNzreo=7;
elseif y5~=0  posNzreo=6;
elseif y4~=0  posNzreo=5;
elseif y3~=0  posNzreo=4;
elseif y2~=0  posNzreo=3;
elseif y1~=0  posNzreo=2;
else          posNzreo=1;
end
end



结果如图所示:

                                                                                                           (原图)

                                      

                                                                                                


                                                                                               (待嵌入的图像)

                                                                   

                                                                                              


                     

                           

代码下载请到:http://download.csdn.net/download/tianma5/9508467

欢迎一起交流。


这篇关于图片嵌入隐藏-大容量的信息隐藏算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/875563

相关文章

C#实现添加/替换/提取或删除Excel中的图片

《C#实现添加/替换/提取或删除Excel中的图片》在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观,下面我们来看看如何在C#中实现添加/替换/提取或删除E... 在Excandroidel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

C#中图片如何自适应pictureBox大小

《C#中图片如何自适应pictureBox大小》文章描述了如何在C#中实现图片自适应pictureBox大小,并展示修改前后的效果,修改步骤包括两步,作者分享了个人经验,希望对大家有所帮助... 目录C#图片自适应pictureBox大小编程修改步骤总结C#图片自适应pictureBox大小上图中“z轴

使用Python将长图片分割为若干张小图片

《使用Python将长图片分割为若干张小图片》这篇文章主要为大家详细介绍了如何使用Python将长图片分割为若干张小图片,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果1. Python需求

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法