1. 程式人生 > 其它 >【影象隱寫】基於matlab DCT數字水印嵌入+檢測+攻擊(測試魯棒性)【含Matlab原始碼 1133期】

【影象隱寫】基於matlab DCT數字水印嵌入+檢測+攻擊(測試魯棒性)【含Matlab原始碼 1133期】

一、簡介

DCT變換的全稱是離散餘弦變換(Discrete Cosine Transform),主要用於將資料或影象的壓縮,能夠將空域的訊號轉換到頻域上,具有良好的去相關性的效能。DCT變換本身是無損的,但是在影象編碼等領域給接下來的量化、哈弗曼編碼等創造了很好的條件,同時,由於DCT變換時對稱的,所以,我們可以在量化編碼後利用DCT反變換,在接收端恢復原始的影象資訊。DCT變換在當前的影象分析已經壓縮領域有著極為廣大的用途,我們常見的JPEG靜態影象編碼以及MJPEG、MPEG動態編碼等標準中都使用了DCT變換。

1 一維DCT變換
一維DCT變換時二維DCT變換的基礎,所以我們先來討論下一維DCT變換。一維DCT變換共有8種形式,其中最常用的是第二種形式,由於其運算簡單、適用範圍廣。我們在這裡只討論這種形式,其表示式如下:

其中,f(i)為原始的訊號,F(u)是DCT變換後的係數,N為原始訊號的點數,c(u)可以認為是一個補償係數,可以使DCT變換矩陣為正交矩陣。

2 二維DCT變換
二維DCT變換其實是在一維DCT變換的基礎上在做了一次DCT變換,其公式如下:

由公式我們可以看出,上面只討論了二維影象資料為方陣的情況,在實際應用中,如果不是方陣的資料一般都是補齊之後再做變換的,重構之後可以去掉補齊的部分,得到原始的影象資訊,這個嘗試一下,應該比較容易理解。
另外,由於DCT變換高度的對稱性,在使用Matlab進行相關的運算時,我們可以使用更簡單的矩陣處理方式:

二、原始碼

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% 數字水印嵌入、攻擊、檢測             %%%
%%%%    %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; 
clc;
start_time=cputime;
%%%%%%%%%%%% 讀取水印影象 %%%%%%%% 
I=imread('mark.bmp');
I=rgb2gray(I);
I=double(I)/255; 
I=ceil(I);
%%%%%%%%%%顯示水印影象%%%%%%%%%%%%%
figure(1);
subplot(2,3,1);
imshow(I),title('水印影象')
dimI=size(I);
rm=dimI(1);cm=dimI(2);
%%%%%%%%%%%%%%%5  以下生成水印資訊 %%
mark=I;
alpha=50,

a0=imread('lena.bmp');
psnr_cover=double(a0);
subplot(2,3,2),imshow(a0,[]),title('載體影象');
[r,c]=size(a0);
cda0=blkproc(a0,[8,8],'dct2');
%%%%%%%%%%%%%%%%%%%%% 嵌入 %%%%%%%%%%
cda1=cda0;   % cda1 = 256_256
for i=1:rm  % i=1:32
    for j=1:cm  % j=1:32
        x=(i-1)*8;y=(j-1)*8;
        if mark(i,j)==1
        k=k1;
        else
        k=k2; 
        end
    cda1(x+1,y+8)=cda0(x+1,y+8)+alpha*k(1);
    cda1(x+2,y+7)=cda0(x+2,y+7)+alpha*k(2);
    cda1(x+3,y+6)=cda0(x+3,y+6)+alpha*k(3);
    cda1(x+4,y+5)=cda0(x+4,y+5)+alpha*k(4);
    cda1(x+5,y+4)=cda0(x+5,y+4)+alpha*k(5);
    cda1(x+6,y+3)=cda0(x+6,y+3)+alpha*k(6);
    cda1(x+7,y+2)=cda0(x+7,y+2)+alpha*k(7);
    cda1(x+8,y+1)=cda0(x+8,y+1)+alpha*k(8);
   
    end
end

%%%%%% 攻擊實驗 測試魯棒性 %%%%%%%%%%%
disp('對嵌入水印的影象的攻擊實驗,請輸入選擇項:');
disp('1--新增白噪聲');
disp('2--高斯低通濾波');
disp('3--JPEG 壓縮');
disp('4--影象剪下');
disp('5--旋轉10度');
disp('6--直接檢測水印');
disp('其他--不攻擊');
d=input('請輸入選擇(1-6):');
start_time=cputime;

    figure(1);
            switch d
                case 6
            subplot(2,3,4);
            imshow(a1,[]);
            title('未受攻擊的含水印影象');
            M1=a1;                      
                case 1
             WImage2=a1;
             noise0=20*randn(size(WImage2));
             WImage2=WImage2+noise0;
             subplot(2,3,4);
             imshow(WImage2,[]);
             title('加入白噪聲後圖像');
             M1=WImage2;
             M_1=uint8(M1);
             imwrite(M_1,'whitenoise.bmp','bmp');
                
                case 2
             WImage3=a1;
             H=fspecial('gaussian',[4,4],0.2);
             WImage3=imfilter(WImage3,H);
             subplot(2,3,4);
             imshow(WImage3,[]);
             title('高斯低通濾波後圖像');
             M1=WImage3;
             M_1=uint8(M1);
             imwrite(M_1,'gaussian.bmp','bmp');
             
                case 4
             WImage4=a1;
             WImage4(1:64,1:512)=512;
             %WImage4(224:256,1:256)=256;
             %WImage4(1:256,224:256)=256;
             %WImage4(1:256,1:32)=256;
             WImage4cl=mat2gray(WImage4);
             figure(2);
             subplot(1,1,1);
             %subplot(2,3,4);
             imshow(WImage4cl);
             title('部分剪下後圖像');
             figure(1);
             M1=WImage4cl;
             %M_1=uint8(M1);
             %imwrite(M_1,'cutpart.bmp','bmp');
             function N=nc(mark_get,mark_prime)
mark_get=double(mark_get);
mark_prime=double(mark_prime);
if size(mark_get)~=size(mark_prime)
    error('Input vectors must  be the same size!')
else
    [m,n]=size(mark_get);
    fenzi=0;
    fenmu=0;
    for i=1:m
        for j=1:n
            fenzi=fenzi+mark_get(i,j)*mark_prime(i,j);
            fenmu=fenmu+mark_prime(i,j)*mark_prime(i,j);
        end
    end

三、執行結果


四、備註

版本:2014a

完整程式碼或代寫加QQ1564658423