DCT變換和DFT變換

2021-09-03 05:15:03 字數 3076 閱讀 1834

這裡我只談論二維的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或...