zoukankan      html  css  js  c++  java
  • 图片嵌入隐藏-大容量的信息隐藏算法

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

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

  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/mq0036/p/12003441.html
Copyright © 2011-2022 走看看