這裡我只談論二維的dft變換,有關一維的dft,請檢視一下部落格,裡面有詳細介紹:
根據上面的公式,我們可以得到對應的離散傅利葉變換呃**,下面是matlab版本的**,和公式(12)是一一對應的,時間複雜度為(mn)^2,通常記成n^4,因此對於乙個512*512的來說,計算量就已經很大了,更不用說別的高解析度影象了,下面的**輸入block_struct是為了方便做blockproc,如果直接將影象的值賦給f就可以直接做dft:
function f = dft2(block_struct)
f=block_struct.data;
[m, n] = size(f);
f = zeros(m,n);
for k = 0:m-1
for l = 0:n-1
f(k+1,l+1) = dft_atomic_sum(f,k,l,m,n);
endend%% computing a core of dft2
function f_kl = dft_atomic_sum(f,k,l,m,n)
f_kl = 0;
for m=0:m-1
for n=0:n-1
f_kl = f_kl + f(m+1,n+1)*exp(-i*2*pi*( k*m/m + l*n/n) );
endend
因此,常用的方法就是先將影象劃分為8*8的塊,然後對每個塊執行dft變換:
fun_dft = @(block_struct) dft2(block_struct);
after_dft=blockproc(y,[8,8],fun_dft);
這樣的時間複雜度就降低了很多,變成了o(8*8*block_num),其中block_num就是塊的個數,因此現在常用的fft演算法,該演算法的介紹很多,本文主要介紹原始dft,對fft感興趣的可以查閱相關資料。
idft為離散傅利葉變換的逆變換,公式如下;
相應的**如下,是根據dft2改編的:
function f = idft2(block_struct)
f=block_struct.data;
[m, n] = size(f);
f = zeros(m,n);
for k = 0:m-1
for l = 0:n-1
f(k+1,l+1) = idft_atomic_sum(f,k,l,m,n);
endend%% computing a core of dft2
function f_kl = idft_atomic_sum(f,k,l,m,n)
f_kl = 0;
for m=0:m-1
for n=0:n-1
f_kl = f_kl + f(m+1,n+1)*exp(i*2*pi*(k*m/m+l*n/n));
endendf_kl = 1/n * 1/m * f_kl ;
同樣需要對影象的8*8的塊進行idft,**如下:
fun_idft=@(block_struct) idft2(block_struct);
after_idft=blockproc(after_dft,[8,8],fun_idft);
after_idft=abs(after_idft);
可以試驗一下,先進行dft,然後進行idft,可以無損的恢復回來:
img=magic(8)
block_struct.data=img
after_dft=dft2(block_struct)
after_inverse_dft=abs(idft2(after_dft))
after_inverse_dft==img
同樣的,我只對二維的dct變換做一些介紹,一維的dct以及相應理論可以檢視下面這篇**:
產生dct變換矩陣a的**如下:
n=8;
a=zeros(n);
for i=0:n-1
for j=0:n-1
if i==0
a=sqrt(1/n);
else
a=sqrt(2/n);
end
a(i+1,j+1)=a*cos(pi*(2*j+1)*i/(2*n));
endend
同理,對8*8塊進行dct變換的**如下,如果不想使用8*8分塊進行dct,那麼需要產生乙個n*n大小的dct變換矩陣a,然後使用f=afa'計算:
fun = @(block_struct) a*(block_struct.data)*a';
after_dct=blockproc(image,[8,8],fun);
離散余弦變換的逆變換,逆變換非常簡單,只需要令f=a'fa就可以了:
fun2 = @(block_struct) a'*(block_struct.data)*a;
inverse_dct=blockproc(after_zigzag,[8,8],fun2);
中間的dct結果是我使用zigzag保留前16個係數,其餘都置零得到的結果:
下面是使用dft變換之後的結果,第二幅圖是使用abs(after_dft)得到的頻譜圖,第三幅圖是使用angle(after_dft)得到的相位圖,idft是逆變換之後的得到的恢復的影象。
離散傅利葉變換DFT和離散余弦變換DCT
在文獻1的第四章中,式 4.2.5 和式 4.2.6 分別給出了 單變數的 一維離散傅利葉變換和反變換 f u 1 m x 0m 1 f x e j2 ux mu 0 1,2 m 1 f x u 0 m 1f u e j2 u x mx 0,1 2,m 1 有時候,前邊的係數1m 會發生變化,但其乘...
dct變換可以用什麼方法代替 DCT變換
dct變換的基本思路是將影象分解為8 8的子塊或16 16的子塊,並對每乙個子塊進行單獨的dct變換,然後對變換結果進行量化 編碼。隨著子塊尺寸的增加,演算法的複雜度急劇上公升,因此,實用中通常採用8 8的子塊進行變換,但採用較大的子塊可以明顯減少影象分塊效應。在影象壓縮中,一般把影象分解為8 8的...
離散余弦變換 DCT
由上面的引用可見,位元速率壓縮基於變換編碼和熵值編碼兩種演算法。前者用於降低熵值,後者將資料變為可降低位元數的有效編碼方式。在mpeg標準中,變換編碼採用的是dct,變換過程本身雖然並不產生位元速率壓縮作用,但是變換後的頻率係數卻非常有利於位元速率壓縮。jpeg影象壓縮演算法 輸入影象被分成8 8或...