1. 程式人生 > >數字影象處理成長之路4: C語言與離散傅立葉變換(DFT)

數字影象處理成長之路4: C語言與離散傅立葉變換(DFT)

這幾天一直學習傅立葉變換,看了很多國內外資料,網上講原理的很多,到了程式實現這塊大多是Matlab,opencv等,這些軟體的api對於我們理解DFT在計算機中的實現並沒有多大幫助。於是想用C/C++實現DFT,經過不斷的閱讀與程式設計實驗,最終程式有了還算滿意的結果。

“關於傅立葉變換,無論是書本還是在網上可以很容易找到關於傅立葉變換的描述,但是大都是些故弄玄虛的文章,太過抽象,盡是一些讓人看了就望而生畏的公式的羅列,讓人很難能夠從感性上得到理解”—dznlong

這是在網上看到的一句話,也是我一直以來的心聲,要想弄明白一些事情,終究是要自己動手。

 for (int u = 0; u < width; u ++)
     for
(int v =0; v < height; v ++){ for (int x = 0; x < width; x++){ for (int y = 0; y < height; y++){ real += srcMat.at<Vec3b>(y, x)[0] * cos(- ((double)2 * PI * u * x / width + (double)2 * PI * v * y / height )) * 1; imaginary += srcMat.at<Vec3b>(y, x)[0
] * sin(-((double)2 * PI * u * x / width + (double)2 * PI * v * y /height)) * 1; } }

u和v是變換後的變數,從程式可以看出,每一個F(u,v)的計算都需要遍歷整副影象,確實是相當費時間,我只用了100 × 100 的影象,計算速度慢的驚人。

 real =  100 * real / (width * height);
 imaginary =100 *  imaginary / (width * height);

為什麼要乘以100呢?因為此時的real和imaginary值很小,如果顯示出來基本是黑色,所以為了顯示清楚,我們隨便乘以個值放大一下,這應該就是Opencv例子裡說的歸一化。

“`
tmpMat.at(u, v) = sqrt(real * real + imaginary * imaginary);

“`這裡寫圖片描述
上面那個小方塊視窗是原影象變換後的影象,用的是opencv的方法。
這裡寫圖片描述
這個圖是用C語言實現的DFT,為了看得清晰點,我把它放大了,相比與opencv的圖這個沒有做座標的變換。

這個程式不是完美的,只是一種嘗試,通過這個過程,對DFT有進一步瞭解,養成這種自己動手的習慣後,對學習其他的演算法有一定幫助,接下來我該轉移到其他問題學習,當知識豐富後還會在回過頭來重新審視今天這些內容,並加以完善。