前面介紹的影像處理方法,大多都是直接操作圖片本身。
例如:
它們都是直接修改 Pixel 的數值。
但其實在影像處理中,還有另一種完全不同的分析方式。
它是先把圖片轉換成另一種表示方式,再進行分析。
這就是今天要介紹的 Fourier Transform(傅立葉轉換)。
第一次看到「傅立葉轉換」這個名詞,也是在工程數學。
當時看到數學公式真的會暈頭轉向。

但同樣的,如果先不看公式,先看傅立葉在幹嘛的話,會發現它其實是在回答一個很有趣的問題:
這張圖片,是由哪些不同快慢的變化組成的?
在影像中,頻率是指亮度變化的快慢。
例如:
一張天空的照片。
大部分區域都是藍色,亮度變化很小,它就是低頻資訊。
相反,如果是一張報紙,文字、邊緣和細線很多,亮度會一直快速改變,這就是高頻資訊。
所以,Frequency 其實就是在描述:
圖片中的亮度改變得有多快。
那既然圖片本來就看得到。
為什麼還要分析頻率?
原因是,有些資訊,在頻域裡反而更容易處理。
例如:
如果今天想保留圖片的大致輪廓,就可以保留低頻。
如果想強調文字、紋理或邊緣,高頻資訊就會變得很重要。
很多影像處理的方法其實就是利用這個特性完成的。
Fourier Transform 可以把圖片從原本的表示方式。
轉換到另一個叫做頻域 (Frequency Domain)的空間。
原本的圖片,每一個 Pixel 代表的是亮度。
轉換之後,每一個位置代表的,則是某一種頻率。
也就是說,傅立葉轉換並沒有改變圖片,只是換了一種方式描述它。
就像同一首歌可以用五線譜表示,也可以用簡譜表示。
歌曲沒有變,只是表示方法不同。
圖片也是一樣的意思。
NumPy 提供了傅立葉轉換的函式。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("dog.jpeg", cv2.IMREAD_GRAYSCALE)
# Fourier Transform
f = np.fft.fft2(img)
# 把低頻移到中心
fshift = np.fft.fftshift(f)
# 計算頻譜
magnitude = np.log(np.abs(fshift) + 1)
接著把結果畫出來。
plt.figure(figsize=(10,4))
plt.subplot(1,2,1)
plt.imshow(img, cmap="gray")
plt.title("Original")
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(magnitude, cmap="gray")
plt.title("Magnitude Spectrum")
plt.axis("off")
plt.tight_layout()
plt.show()
結果如下:

這不是程式寫錯。
你可能會問,為什麼這兩張圖長得完全不一樣卻不是寫錯。
這是因為它顯示的不是物體,而是圖片中的頻率分布。
通常會看到中央最亮,代表圖片中大部分都是低頻資訊。
越靠近四周,則代表越高的頻率。
今天介紹了 Fourier Transform。
和前面直接修改 Pixel 的方法不同,傅立葉轉換並不是改變圖片,而是把圖片換一種方式表示。
在空間域中,我們觀察的是每個 Pixel 的亮度,而在頻域中,我們分析的是圖片中不同頻率的組成。
不過,到目前為止,我們只是成功把圖片轉換到頻域。
那麼問題來了:
如果圖片很大,每次都直接做傅立葉轉換,速度會變得非常慢。
有沒有方法,可以在得到相同結果的前提下,大幅減少計算時間?
下一篇,我們就來介紹 Fast Fourier Transform(FFT),看看它是如何讓傅立葉轉換變得更有效率。