圖片嵌入隱藏-大容量的信息隱藏算法

  今天分享一下最近看到的一個圖片嵌入隱藏的算法。html

  這是一種基於空間域的自適應多平面位的信息隱藏算法。該算法計算複雜度低、信息隱藏量大。且有實驗代表在不影響圖像視覺效果的前提下,其信息隱藏量比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) ruby

%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) ui

%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

結果如圖所示:spa

                                                           (原圖)
.net

                                      

                                                                                                

 

                                                                                                   (待嵌入的圖像)
code

                                                                   

                                                                                              

 

                     

                           

代碼下載請到:http://download.csdn.net/download/tianma5/9508467

歡迎一塊兒交流。

 

 

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

相關文章
相關標籤/搜索