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


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

      这是一种基于空间域的自适应多平面位的信息隐藏算法。该算法计算复杂度低、信息隐藏量大。且有实验表明在不影响图像视觉效果的前提下,其信息隐藏量比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*N
        if 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:embedNums
                
                embedNumsed=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*N
        if 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:embedNums
                embedNumsed=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*N
        if 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:embedNums
                embedNumsed=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*N
        if 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:embedNums
                
                extractNumsed=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*N
        if 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:embedNums
                
                extractNumsed=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*N
        if 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:embedNums
                
                extractNumsed=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

    欢迎一起交流。

     

    出处:https://blog.csdn.net/Tianma5/article/details/51299000

  • 相关阅读:
    Troubleshooting a Jedis Connection Pool Error
    com.mysql.cj.jdbc.exceptions.CommunicationsException
    springboot tomcat连接池
    Spring官方文档
    Troubleshooting-Spring-RestTemplate-Requests-Timeout
    Linux进程和端口命令总结
    Git及GitLab使用手册
    MySQL数据库命令大全
    两天时间,实现自己的 Promise
    vue-cli3.0搭建服务端渲染SSR
  • 原文地址:https://www.cnblogs.com/mq0036/p/12003441.html
Copyright © 2020-2023  润新知