透過二維的傅立葉轉換與逆轉換,我們可以針對圖像來實現高通濾波、低通濾波等操作,這對於圖像的模糊、邊緣等各種處理方式之認識,也會有所助益!

二維傅立葉轉換

上一篇專欄文章〈傅立葉轉換與影像處理(中)〉談到,我們可從一維Perlin雜訊來理解圖像頻率的意義,但影像實際上是二維的,亦即訊號是二維形式,需使用〈二維傅立葉轉換〉,也就是將函式f(p1,p2)函式,轉換為函式F(w1,w2),w1、w2是二維的頻率,分別代表兩個方向的頻率變化,只不過在圖像上,f(p1,p2)並不是代表時域,而是空間域(Spatial domain)。

空間域?這就更令許多開發者困惑了,傅立葉轉換不就是處理訊號,而訊號不就是從時域到頻域?哪來的空間域至頻域?其實,我們可以想像有個水中的震動源,在不斷振動下產生漣漪,那麼p1、p2可以是指什麼呢?時間嗎?如果以時域f(t1,t2)描述訊號,兩個時間的方向代表什麼?這令人難以想像,然而若想成用相機對水波照像後,查看照片中漣漪在某位置的水平面高低關係,就容易理解了。

也就是說,可以使用f(x,y)函式,來表示漣漪在位置(x,y)與水平面的高低關係,這就是從空間域轉換至頻域,而不是從時域轉換至頻域了;既然有二維傅立葉轉換,相對地也有二維傅立葉級數,可以看成水波是由許多的小漣漪疊加而成,二維傅立葉轉換後的結果,就是這些小漣漪的頻域表示。

水中有個單一振動源時,會產生一圈圈的漣漪,若是有多個振動源,就會構成波光粼粼,某些程度在視覺上,就會像是以二維Pelin雜訊建立的灰階圖,也就是說,這時的二維傅立葉轉換,是個從空間中某位置的訊號到訊號頻率的轉換。

將以上的概念應用在灰階圖片上,空間域f(x,y)表示在位置(x,y)的灰階值,二維傅立葉轉換後的結果,我們可以看到它是由哪些灰階度週期變化組成,此時,可以想像許多不同的灰階圖,各個灰階圖視覺上像個小漣漪,這些小漣漪會疊加成最後的灰階圖片,將此灰階圖進行二維傅立葉轉換,可以得到這些小漣漪的頻率,也就是所謂的圖像頻率。

圖像頻域分析

對於一維的訊號,NumPy的fft函式轉換後,是由複數組成的一維陣列,對於二維的訊號,NumPy的二維傅立葉轉換實作函式fft2,轉換後是含複數的二維陣列,如果取振幅絕對值並標準化為0至255的值,作為圖片顯示時,會是個越接近圖片原點(左上角)為低頻,越外圍表示越高頻的圖像。

由於圖像座標是以左上為原點,往右往下各為座標軸正方向,預設看到的頻域圖像就只有正頻率的部份,然而我在〈傅立葉轉換與影像處理(中)〉談到,一維傅立葉轉換會有負頻率,二維傅立葉轉換也會有負頻率的部份,若要觀察負頻率,通常會將轉換結果位移,這可以透過NumPy的fftshift函式來達成,頻域圖像通常位移後,會以圖像中心為低頻,外圍為高頻;NumPy也提供二維傅立葉逆轉換ifft2,轉換後可得到原始圖片。

〈二維傅立葉轉換與逆轉換〉這個gist中,示範了如何使用fft2與fftshift進行二維傅立葉轉換與位移,從執行結果來看,我們可以發現頻域顯示圖的中心很亮,代表原始圖片有很大的低頻成份。

許多開發者經常使用OpenCV處理圖像,而OpenCV也提供傅立葉轉換的相關實作,cv2.dft函式接受影像資料,必須是float32型態,flags參數指定cv2.DFT_COMPLEX_OUTPUT 表示轉換為複數輸出,不過輸出會分為實數與虛數,而不是直接使用Python的複數表示,若f是輸出結果,可以透過f[:,:,0]取得實數,f[:,:,1]取得虛數。

在取得實數與虛數部份後,雖然我們可以自行實作標準化,然而也可以透過cv2.magnitude指定實數與虛數部份取得振幅大小,再透過cv2.normalize標準化為0到255,程式實作可參考gist〈OpenCV傅立葉轉換與逆轉換〉

我在先前專欄文章〈淺談圖片雜訊處理〉也談過,椒鹽雜訊是高頻雜訊,如果在圖像上產生椒鹽雜訊,比較原圖像的頻域與產生雜訊後的頻域,我們可以發現原圖像在外圍本來沒什麼訊號,而在加上椒鹽雜訊後,會觀察到增加了大量高頻訊號。關於程式碼實作部份,可以參考〈傅立葉轉換與雜訊分析〉這個gist。

傅立葉轉換與圖像濾波

〈傅立葉轉換與影像處理(中)〉我曾提到,透過一維的傅立葉轉換,將特定頻率的值設為0,逆轉換後可實現濾波功能,二維圖像也可以濾波,例如,圖像的高頻訊號就視覺上來看,會讓界線較為明顯,如果可以去除低頻訊號,保留高頻訊號,就有機會保留較多的圖像邊緣。

要針對二維的傅立葉轉換結果去除低頻訊號,最簡單的方式是,將頻域圖像位移至中心,然後指定四邊形的範圍設為0,至於低頻範圍要設多大,就看我們想要什麼效果。因為,頻域中被設為0的訊號,就是振幅被設為0,就視覺上來看,就像是將頻域圖像以黑色四邊形遮蓋。

接著我們將被遮蓋的頻域圖像,中心位移回左上角,執行傅立葉逆轉換,頻域中被設為0的部份,逆轉換後的結果灰階度就是0,會呈現黑色,其餘灰階度保留,大多數是邊緣的部份,有興趣看程式實作的話,可參考gist〈傅立葉轉換尋找圖像邊緣〉

這就構成了圖像上的高通濾波器(High pass filter),只不過高頻部份不一定是邊緣,也有可能是高頻雜訊等其他來源,在沒有透過模糊等處理來抑制雜訊的情況下,檢視圖像濾波的結果時,若提高亮度,仍然可以看到一些非邊緣的紋路。

當然,濾波時不一定要指定四邊形範圍,也不一定是遮蓋低頻,如gist〈傅立葉轉換圓形濾波〉,以圓形範圍保留低頻,亦即實作了低通濾波器(Low pass filter),由於低頻部份對應圖像中的平滑區域,執行後只會保留這些區域,變化大的邊緣被去除,因而產生模糊效果。

模糊、邊緣處理與傅立葉轉換

你可以回顧先前〈淺談圖片雜訊處理〉談過的抑制雜訊方式,無論是均值濾波、中值濾波等,基本上就是模糊處理,雖然不見得要理解傅立葉轉換,也能理解均值濾波、中值濾波的原理,但它們本質上就是低通濾波,若有興趣,也可看看各種模糊處理後的頻域圖像,基本上都會是高頻部份一片黑。

相對地,可以尋找邊緣的圖像處理方式,雖然不見得是透過傅立葉轉換,例如基於二階偏微分的Laplacian運算子Sobel運算子等,然而基本上可以歸類於高通濾波。

如Laplacian運算子處理的圖片,其頻域圖像的低頻範圍會是黑的;有趣的是Sobel運算子,因為可以個別處理垂直或水平方向,頻域圖像的黑色範圍也就各會有水平或垂直方向的黑色帶狀,有興趣看看程式實作與圖樣,可參考OpenCV官方的〈Fourier Transform〉介紹。

在圖像處理與分析上,傅立葉轉換是個非常有用的工具,除了能認識圖像頻率的意義之外,對於模糊、邊緣等各種處理方式,也會因此而融會貫通,搞懂傅立葉轉換,絕對是不吃虧的投資。

專欄作者

熱門新聞

Advertisement