Fourier Dönüşümü

Fourier Dönüşümü Jean-Baptiste Joseph Fourier` in bilim dünyasına sunduğu en güzel hediyelerden biridir. Fourier herhangi bir işaretin, farklı genlik ve frekanstaki cosinus ve sinus lerin toplamı şeklinde yazılabileceğini gösterdi. Böylece $k$ uzayında tanımlı bir işaretin Fourier Dönüşümü alınarak, işareti içerdiği frekans bileşenleri ve ağırlıkları cinsinden tanımlama imkanına sahip olduk. Böyle bir dönüşüme neden ihtiyaç duyulduğuna gelirsek bunun iki temel nedeni var. Birincisi işlem kolaylığı, ikincisi ise bulunduğumuz uzayda direk olarak görmemizin mümkün olmadığı bileşenleri dönüşüm alarak görülebilir yapmasıdır.



Örneğin; zaman domeninde konvolüsyon işlemini hatırlayalım, bu işlemin işlem yükü oldukça karışıktır. Oysa zaman domeninde konvolüsyonu alınacak işaretlerin Fourier dönüşümleri alınırsa konvolusyon işlemi cebirsel çarpma işlemine dönüşür. Bir diğer örnek diferansiyel denklemlerdir. Tanımlandığı domende çözülmesi oldukça zor olan diferansiyel denklemlerin Fourier dönüşümü alınarak lineer sistemlere dönüştürülüp kolayca çözülebilir. İkinci nedene örnek olarak bir işaretin Fourier dönüşümü alındığında içerdiği temel frekans bileşenleri ve gürültülerin kolaylıkla gözlemlenebilir olması verilebilir.

Fourier dönüşümü çift yönlü bir dönüşümdür yani bir işaretin Fourier'inin ters Fourier'i, ters Fourier'inin Fourier'ine eşittir. Sürekli zamanlı Fourier dönüşümü aşağıdaki eşitlik ile tanımlanır.

\begin{equation}
X(f) = \int_{-\infty}^{\infty} x(t) e^{-j2\pi f t}dt
\end{equation}

Burada $x(t)$ Fourier dönüşümü alınacak işaret, $X(f)$ ise Fourier dönüşümü alınmış işarettir. Bu ifadenin bir başka gösterimi $f=\dfrac{\omega}{2\pi}$ yazılarak elde edilir.

\begin{equation}
X(\omega) = \int_{-\infty}^{\infty} x(t) e^{-j\omega t}dt
\end{equation}

Bu gösterim çoğu uygulama da basitlik açısından tercih edilmektedir. Dönüşümün tersi ise şu şekilde tanımlıdır.

\begin{equation}
x(t) = \frac{1}{2\pi}\int_{-\infty}^{\infty} X(\omega) e^{j\omega t}d\omega
\end{equation}

Dönüşüm her nekadar kolay görünse de sürekli bir dönüşüm ve sonsuz uzunluklu bir integrali bilgisayar programına dönüştürmek imkansızdır. Bunun için sürekli Fourier dönüşümü ayrıklaştırılarak Ayrık Fourier Dönüşümü (DFT:Discrete Fourier Transform) geliştirilmiştir. Sürekli Fourier dönüşümünden farklı olarak burada integral yerine toplam sembolü kullanılmış ve sonsuz uzunluklu dönüşüm işaretin uzunluğu ile sınırlandırılmıştır.

\begin{equation}
X(e^{j\omega}) = \sum_{n=-\infty}^{\infty} x[n] e^{-j\omega n}
\end{equation}

Ayrık ters Fourier dönüşümünde ise iki temel farklılık bulunmaktadır. Ayrık bir işaretin Fourier dönüşümü $X(e^{j\omega})$ sürekli ve $2\pi$ ile periyodik olduğundan hesaplama $[-\pi,\pi]$ aralığında integral üzerinden yapılmıştır.

\begin{equation}
x[n] = \frac{1}{2\pi}\int_{-\pi}^{\pi} X(e^{j\omega}) e^{j\omega n}d\omega
\end{equation}

Basit birkaç örnekle dönüşümü anlamaya çalışalım. İlk örneğimize $x[n]=a^n u[n]$ fonksiyonunun dönüşümü ile başlayalım. Bu dizinin Fourier dönüşümü
$$X(e^{j\omega})=\sum_{n=0}^{\infty} a^ne^{-j\omega n}=\sum_{n=0}^{\infty} (ae^{-j\omega})^n$$
Şeklinde olacaktır. Eğer burada $|ae^{-j\omega}| < 1$ yani $|a|\cdot|e^{-j\omega}| < 1 \rightarrow |a| < 1$ şartı sağlanıyor ise $$X(e^{j\omega})=\sum_{n=0}^{\infty} (ae^{-j\omega})^n=\frac{1}{1-ae^{-j\omega}}$$ yazılabilir. Burada $|a| < 1$ şartı $x[n]$ fonksiyonunun mutlak toplamsallık koşulu olarak adlandırılır ve Fourier dönüşümünün alınması için gerek bir koşuldur.

Bir başka önemli örnek ise $x[n]=\text{rect}_N[n]$ fonksiyonudur. Bu fonksiyon zaman domeninde ideal bir alçak geçiren filtreyi göstermektedir ve $[-N,N]$ aralığında bir değerine sahip bir dikdörtgen işarettir. Bu işaretin Fourier dönüşümü

\begin{equation}
\begin{split}
X(e^{j\omega}) & = \sum_{n=-\infty}^{\infty} x[n] e^{-j\omega n} =\sum_{n=-\infty}^{\infty} \text{rect}_{N}[n] e^{-j\omega n}=\sum_{n=-N}^{N} e^{-j\omega n} = \sum_{n=-N}^{N} (e^{-j\omega })^n \\& = \frac{e^{j\omega N}-e^{-j\omega (N+1)}}{1-e^{-j\omega}}
\end{split}
\end{equation}
bulunur. Burada elde edilen ifadeyi $e^{j\omega/2}$ ile çarpıp bölersek
\begin{equation}
X(e^{j\omega}) =\frac{e^{j\omega/2}}{e^{j\omega/2}}\cdot \frac{e^{j\omega N}-e^{-j\omega (N+1)}}{1-e^{-j\omega}} = \frac{e^{j\omega (N+1/2)}-e^{-j\omega (N+1/2)}}{e^{j\omega/2}-e^{-j\omega/2}}
\end{equation}
elde edilir. Euler formülü hatırlanarak yukarıdaki ifade
\begin{equation}
X(e^{j\omega}) = \frac{\sin(\omega (N+\frac{1}{2}))}{\sin(\omega/2)}
\end{equation}
şeklinde yazılır. Aşağıda $N=3$ olan dikdörtgen dalga işareti için bulunan Fourier dönüşümü çizdirilmiştir.

Grafikte dikkate edilecek iki nokta bulunmaktadır. Bunlardan ilki ayrık bir işaret olan dikdörtgen dalganın Fourier dönüşümü süreklidir. İkincisi ise Fourier domenindeki işaretin $2\pi$ ile periyodik olduğudur.

Gelelim kodlama kısmına. Bu kısma geçmeden önce bir önceki yazıda kompleks sayılar için oluşturduğumuz fonksiyonlara bakmanızı tavsiye ederim. Burada bu fonksiyonları kullanılarak Ayrık Fourier ve Ters Fourier dönüşümü kodlarını yazacağız.

cfloat *dft(cfloat *x,int n) {
       
       cfloat *ft;
       ft=new cfloat [n];
       int i,j;
       
       for(i=0;i < n;i++) {
         ft[i].reel  = 0.0;
         ft[i].sanal = 0.0;                 
            for(j=0;j < n;j++) {
          ft[i] += x[j]*cexp(-2*pi*i*j/n); }
       } 
       return ft;
} 

Yukarıda verielen kod içerisinde geçen cexp fonksiyonu kod karmaşasını engellemek için yazılan ufak bir fonksiyon , bildiğiniz üzere Euler formülünden $e^{i\theta}=\cos(\theta)+i\sin(\theta)$ dır. Burada dönüşümü yaparken $e$ ve $i$ sayısını kullanmamak için bir alt fonksiyon olarak cexp tanımlanmıştır böylece $x=cexp(\theta)$ tanımı yapıldığında $x.reel=\cos(\theta)$ ve $x.sanal=\sin(\theta)$ olan bir kamaşık sayı dönecektir. Yukarıdaki denklemler baz alındığında ters Fourier dönüşümü ise şu şekilde kodlanabilir.
 
cfloat *idft(cfloat *x,int n) {
       
       cfloat *ft;
       ft=new cfloat [n];
       int i,j;
       
       for(i=0;i < n;i++) {
         ft[i].reel=0.0;
         ft[i].sanal=0.0;                 
            for(j=0;j < n;j++) {
          ft[i] += x[j]*cexp(-2*pi*i*j/n); }
       } 

       for(i=0;i < n;i++) {                 
         ft[i].reel  = ft[i].reel/n;
         ft[i].sanal = ft[i].sanal/n;                                   
       }                     
return ft;
}

2 yorum:

  1. belki de Fourier Dönüşümünü çoğumuz kullanırız ama niye kullanırız ya da ne işe yarar hocalar da dahil olmak üzere bilmeyiz. Çok aydınlatıcı bilgiler teşekkürler Bahri Bey

    YanıtlaSil
    Yanıtlar
    1. Bu yazıdaki amacım biraz da bu dönüşümün pek bilinmeyen mantığını anlatmaktı, yorumunuz için teşekkürler.

      Sil

Görüntü işleme ile ilgili yeni yazıları ve bu sitede yer alan yazıların güncellenmiş sürümlerini www.imlab.io veya cescript.github.io adreslerinden takip edebilirsiniz.

X