轉自:http://blog.csdn.net/ahafg/article/details/48808443
DCT變換
DCT又稱離散余弦變換,是一種塊變換方式,只使用余弦函數來表達信號,與傅里葉變換緊密相關。常用于圖像數據的壓縮,通過將圖像分成大小相等(一般為8*8)的塊,利用DCT對其進行變換,得到更加簡潔的數據。因為圖像像素間存在較大的空間相關性,DCT可以大大減小這些相關性,使圖像能量集中在左上角區域,從而利于數據壓縮。變換后得到的數據稱為DCT系數。這一過程是無損的。
二維DCT變換
這里來看看二維DCT變換的公式:
c(u)和c(v)為添加的系數,主要作用為使DCT變換矩陣為正交矩陣。F(u,v)即為DCT變換系數,可以通過矩陣形式來表示:
A即為正交矩陣,通過F和A逆變換即可恢復圖像數據。
下面通過一個例子來說明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17clear;
clc;
I = [12,23,53,16;42,16,68,45;34,62,73,26;72,15,34,28]; %數據塊
A = zeros(4); %變換矩陣A,也可以通過函數dctmtx(n)求得
for i = 0:3
for j = 0:3
if i == 0
a = sqrt(1/4);
else
a = sqrt(2/4);
end
A(i+1,j+1) = a*cos((j+0.5)*pi*i/4)
end
end
D = A*I*A'; %DCT變換
D1 = dct2(I); %matlab DCT函數進行DCT變換
D2 = A'*D*A; %DCT逆變換
由結果可以看出,D,D1方式得到的DCT系數相同,說明矩陣形式的DCT變換公式是正確的,D2的數據與原數據I相同,實現了數據恢復。
另外通過運行函數dctmtx(4)可以發現得到的變換矩陣與A完全相同。
Matlab 函數實現
matlab實現離散余弦變換有兩種方法:
一種為函數dct2( ), 使用函數dct2,該函數用一個基于FFT的算法來提高當輸入較大的方陣時的計算速度。
另一種為函數dctmtx( ), 使用由dctmtx函數返回的DCT變換矩陣,這種方法較適合于較小的輸入方陣(例如8×8或16×16)。
1. 函數:dct2( )
實現圖像的二維離散余弦變換。調用格式為:? B = dct2(A)? B = dct2(A,[M N])? B = dct2(A,M,N)? 式中A表示要變換的圖像,M和N是可選參數,表示填充后的圖像矩陣大小,B表示變換后得到的圖像矩陣。其逆變換函數為idct2( );? 代碼如下:
1
2
3
4
5I = imread('1_1.jpg');%輸入灰度圖像
D = dct2(I); %DCT變換
D1 = idct2(D); %逆變換
subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(uint8(D1));
在這里可以通過函數colormap查看變換系數D。利用不同灰度值,可以發現D中主要數據都分布在左上角。
1
2
3imshow(log(abs(D)),[]);
colormap(gray(8));colorbar;
2. 函數:dctmtx( )
D = dctmtx(N)? 式中D是返回N×N的DCT變換矩陣,如果矩陣A是N×N方陣,則A的DCT變換可用D×A×D’來計算。這在有時比dct2計算快,特別是對于A很大的情況。上面有提到過。
對于圖像的DCT變換,這里還需用到一個函數blkproc( ),其功能為對圖像分塊進行DCT變換。? blkproc( )定義如下:? B = blkproc(A,[M N],Fun) ,A為輸入圖像,M*N為塊大小,Fun為處理函數? 常用的方式為:? B = blkproc(A,[8,8],’P1*x*P2’,T,T’); T為變換矩陣,P1和P2為參數,代表T*x*T’ 。
下面為應用例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40I = imread('1_1.jpg'); %輸入灰度圖像
I = im2double(I);
D = dctmtx(8);
C = blkproc(I,[8,8],'P1*x*P2',D,D'); %D'為D的轉置
mask1=[1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask2=[1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
mask3=[1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
X = blkproc(C,[8,8],'P1.*x',mask1); %保留15個系數
I1 = blkproc(X,[8,8],'P1*x*P2',D',D); %重構圖像
X2 = blkproc(C,[8,8],'P1.*x',mask2); %保留10個系數
I2 = blkproc(X2,[8,8],'P1*x*P2',D',D); %重構圖像
X3 = blkproc(C,[8,8],'P1.*x',mask3); %保留3個系數
I3 = blkproc(X3,[8,8],'P1*x*P2',D',D); %重構圖像
subplot(2,4,1);imshow(I);
subplot(2,4,2);imshow(I1);
subplot(2,4,3);imshow(I2);
subplot(2,4,4);imshow(I3);
上面代碼中,通過求得圖像DCT系數,利用mask等矩陣對其進行量化,保留左上角主要的系數值,對于右下角的值由于其為非常小的高頻系數,量化去除后對于圖像的質量影響不大,可以利用這一性質對圖像進行壓縮處理。
保留系數越多則圖像壓縮質量越好,下面比較幾幅圖像質量,從左到右分別為原圖,mask1,mask2,mask3;
可以看到系數保留越少,則圖像質量越差。
DCT變換這次就講到這了。