【影象隱寫】基於matlab DCT數字水印嵌入+檢測+攻擊(測試魯棒性)【含Matlab原始碼 1133期】
阿新 • • 發佈:2021-07-11
一、簡介
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