1. 程式人生 > 其它 >【影象隱寫】基於matlab DWT數字水印多種攻擊效果對比【含Matlab原始碼 1134期】

【影象隱寫】基於matlab DWT數字水印多種攻擊效果對比【含Matlab原始碼 1134期】

一、簡介

小波變換原理
小波變換是一種訊號的時間一尺度(時間一頻率)分析方法,一種視窗大小固定不變形狀可改變,時間窗和頻率窗都可以改變的時頻區域性化分析方法。它具有多解析度分析( Multi-resolution Analysis)的特點,且在時頻兩域都具有表徵訊號區域性特徵的能力。
小波分析方法在低頻部分具有較高的頻率解析度和較低的時間解析度,在高頻部分具有較高的時間分辦率和較低的頻率分辦率,所以被譽為“數學顯微鏡”。正是這種特性,使小波變換具有對訊號的自適應性。
小波分析被看成調和分析這一數學領域半個世紀以來的工作結晶,已經廣泛地應用於訊號處理、影象處理、量子場論、地震勘探、語音識別與合成、音樂、雷達、CT成像、彩色影印、流體湍流、天體識別、機器視覺、機械故障診斷與監控、分形以及數字電視等科技領域。
原則上講,傳統上使用傅立葉分析的地方,都可以用小波分析取代。小波分析優於傅立葉變換的地方是在時域和頻域同時具有良好的區域性化性質。

這樣小波變換對不同的頻率在時域上的取樣步長是調節性的:在低頻時,小波變換的時間解析度較低,而頻率分辦率較高;在高頻時,小波變換的時間解析度較高,而類率解析度較低。這正符合低頻訊號變化緩慢而高頻訊號變化迅速的特點。
這便是它優於經典傅立葉變換與短時傅立葉變換的地方。

二、原始碼

clc
clear all;


k=20;          
blocksize=8;   % 設定塊的大小

% 讀入原影象
file_name='_lena_std_bw.bmp';
cover_object=double(imread(file_name));
 
% 原影象的行數與列數
Mc=size(cover_object,1);         %原影象行數
Nc=size(cover_object,2);         %原影象列數

% 最大嵌入資訊量
max_message=Mc*Nc/(blocksize^2);

% 讀入水印影象
file_name='c.bmp';
message=double(imread(file_name));

%%水印影象的行數與列數
Mm=size(message,1);               %水印行數
Nm=size(message,2);               %水印列數

message_vector=reshape(message,1,Mm*Nm);

% 檢查水印資訊是否過大
if (Mm*Nm> max_message)
  error('水印太大')
end

% 產生watermarked_image,並寫入原圖資訊
watermarked_image=cover_object;


% 將影象分塊嵌入
% 當 (2,2) > (2,3) 且 message_pad(kk)=0
% 當 (2,2) < (2,3) 且 message_pad(kk)=1

%%在提取水印時,如果cD1(2,2)>cD1(2,3)便是嵌入了水印的黑色畫素,
%%反之則是嵌入了白色畫素
x=1;
y=1;
h=waitbar(0,'嵌入水印,請等待');
for (kk = 1:length(message_vector))

  % 對塊進行DWT變換
  [cA1,cH1,cV1,cD1] = dwt2(cover_object(x:x+blocksize-1,y:y+blocksize-1),'haar');
  % 如果 message_pad(kk)== 0
  if (message_vector(kk) == 0)

    % 且(2,2) < (2,3) ,交換它們
    if (cD1(2,2) < cD1(2,3))
          temp=cD1(2,3);
          cD1(2,3)=cD1(2,2);
          cD1(2,2)=temp;
    end
  
  % 如果message_pad(kk) == 1, 
  elseif (message_vector(kk) == 1)
    
    % 且(2,2) > (2,3) ,交換它們
    if (cD1(2,2) >= cD1(2,3))
          temp=cD1(2,3);
          cD1(2,3)=cD1(2,2);
          cD1(2,2)=temp;
    end
  end
  
  % 檢查(2,2) , (2,3)的差是否>= k
  if cD1(2,2) > cD1(2,3)
    if cD1(2,2) - cD1(2,3) < k
        cD1(2,2)=cD1(2,2)+(k/2);
        cD1(2,3)=cD1(2,3)-(k/2);         
    end
  else 
      if cD1(2,3) - cD1(2,2) < k
        cD1(2,3)=cD1(2,3)+(k/2); 
        cD1(2,2)=cD1(2,2)-(k/2);
    end
  end
    
  %IDWT
  watermarked_image(x:x+blocksize-1,y:y+blocksize-1)= idwt2(cA1,cH1,cV1,cD1,'haar',[Mc,Nc]);


  % 移動到下一塊
  if (x+blocksize) >= Nc
    x=1;
    y=y+blocksize;
  else
    x=x+blocksize;
  end
  waitbar(kk/length(message_vector),h);
end
close(h);

% 轉換為uint8並寫入dwt_watermarked.bmp
watermarked_image_uint=uint8(watermarked_image);
imwrite(watermarked_image_uint,'dwt_watermarked.bmp','bmp');

% 計算psnr值
psnr=psnr(cover_object,watermarked_image), 

% 顯示影象
%figure(1)
%imshow(message,[]);
%title('水印');
figure(2)
subplot(1,2,1);
imshow(watermarked_image,[])
title('嵌入水印影象')
subplot(1,2,2);
imshow(cover_object,[]);
title('原圖');




%提取原始碼
clear all;

blocksize=8;   % 設定塊的大小

% 讀入嵌入水印影象
file_name='dwt_watermarked.bmp';
watermarked_image=double(imread(file_name));

% 嵌入水印影象的行數與列數
Mw=size(watermarked_image,1);         %嵌入水印影象的行數
Nw=size(watermarked_image,2);         %嵌入水印影象的列數

% 最大嵌入資訊量
max_message=Mw*Nw/(blocksize^2);

% 讀入原始水印
file_name='c.bmp';
orig_watermark=double(imread(file_name));

% 原始水印的行數與列數
Mo=size(orig_watermark,1);    %原始水印的行數
No=size(orig_watermark,2);    %原始水印的列數

% 將影象分塊提取水印
x=1;
y=1;
h=waitbar(0,'水印提取中,請等待');
for (kk = 1:max_message) 

  % 對塊進行dwt變換
  [cA1,cH1,cV1,cD1] = dwt2(watermarked_image(x:x+blocksize-1,y:y+blocksize-1),'haar');
  
  % 如果cD1(2,2) > cD1(3,3) 那麼 message_vector(kk)=0
  % 否則 message_vector(kk)=1
  if cD1(2,2)>cD1(2,3)
    message_vector(kk)=0;
  else
    message_vector(kk)=1;
  end


  % 移動到下一塊
  if (x+blocksize) >= Mw
    x=1;
    y=y+blocksize;
  else
    x=x+blocksize;
  end
  waitbar(kk/max_message,h);
end

三、執行結果






四、備註

版本:2014a

完整程式碼或代寫加QQ1564658423