既然前面談雜訊處理時,談到了濾波(Filter)(影像處理軟體上,好像比較偏好翻譯為濾鏡?),那就來進一步認識傅立葉轉換(Fourier transform),因為透過它,可以進一步達到提取影像邊緣輪廓之目的。
只不過一開始先不走得太遠,來畫個正弦波好了:
import numpy as np
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
y = np.sin(freq * 2 * np.pi * x)
plt.plot(x, y)
plt.show()
這沒什麼困難,就是個正弦波,只不過在這邊要注意的是,sin 波是個連續函式,只不過在電腦的世界是離散的,只能每隔一段距離取樣,程式中的 sample_rate
就是用來設定取樣率:
如果你在這個正弦波上,疊加上一個頻率稍高、振幅稍低的正弦波會如何呢?
import numpy as np
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
y1 = np.sin(freq * 2 * np.pi * x)
y2 = np.sin(3 * freq * 2 * np.pi * x) / 3
plt.plot(x, y1)
plt.plot(x, y2)
plt.plot(x, y1 + y2)
plt.show()
plt.plot(x, y)
plt.show()
在下圖中,藍色是方才的正弦波,橘色是頻率稍高、振幅稍低的正弦波,綠色是兩者疊加後的結果:
綠色看來有點像是某種訊號的波形,如果進一步,將上圖的綠色波,再疊加上一個頻率更高、振幅更低的正弦波會如何呢?
import numpy as np
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
y1 = np.sin(freq * 2 * np.pi * x)
y2 = np.sin(3 * freq * 2 * np.pi * x) / 3
y3 = np.sin(5 * freq * 2 * np.pi * x) / 5
plt.plot(x, y1 + y2 + y3)
plt.show()
這次只畫出疊加後的波形,看來更像是某種神秘訊號波形了:
在方才每一次的波疊加過程中,1、3、5…這樣的頻率提高、振幅降低是特意選取的,因為想導向一個結果,若不斷地重複以上過程,例如重複個 1000 次,會形成什麼波呢?
import numpy as np
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
n = 1000 # 疊加的波數
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
i = np.arange(1, 2 * n, 2).reshape((n, 1))
y = (np.sin(i * freq * 2 * np.pi * x) / i).sum(axis = 0)
plt.plot(x, y)
plt.show()
結果幾乎是個方波:
呃?正弦波竟然可以構成方波?嚴格來說,是近似於方波,因為若將圖形的顯示放大,還是可以看到曲線的波形起伏,只是很微小,小到以上圖尺寸來看,幾乎看不出來了。
方波是個極端的例子,透過一大堆正弦波的疊加,近似到方波,既然方波都可能近似出來了,其他的週期波,是不是也有可能透過正弦波的疊加來構成?傅立葉(Joseph Fourier)告訴我們,這是可行的,在數學上,將類似波的函數表示成簡單正弦波後的形式,稱為傅立葉級數(Fourier series)。
這代表著,我們可以將不同頻率的訊號混合在一起,不同的頻率代表想要傳遞不同的意義,混合後的波也許像是:
這個波傳送出去後,接收端若能將之轉換為傅立葉級數,就可以取得特定頻率,解讀其中的資訊,上圖其實是四種波組成:
import numpy as np
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
z1 = np.sin(freq * 2 * np.pi * x) # 頻率 10
z2 = np.sin(3 * freq * 2 * np.pi * x) / 2 # 頻率 30
z3 = np.sin(4 * freq * 2 * np.pi * x) / 5 # 頻率 40
z4 = np.sin(8 * freq * 2 * np.pi * x) / 3 # 頻率 80
zero = np.zeros(z1.size)
ax = plt.axes(projection='3d')
ax.plot(x, zero, z1 + z2 + z3 + z4)
ax.plot(x, (zero + freq), z1)
ax.plot(x, (zero + 3 * freq), z2)
ax.plot(x, (zero + 4 * freq), z3)
ax.plot(x, (zero + 8 * freq), z4)
plt.show()
聲波也是類似的道理,如果你試著使用錄音程式,有些錄音程式會顯示你的聲音波形,基本上代表著隨著時間記錄的音量,這個波形也可以分解為許多弦波的組合,例如上圖的藍色波,若代表某個聲音波形,你就可以分解為四種正弦波。
若 x
代表著時間,一段時間內的聲音波形,是隨著時間而變化的,然而就分解後的弦波來看,有四種頻率的波,無論時間再怎麼變化,這四個頻率的值是不變的,若這四個波以頻率為 x 軸,振幅為 y 軸,畫出來的圖會是:
也就是說,這給了我們從不同觀點來觀察的機會,從時域(Time domain)的觀點來看,波是不斷地在變化,然而從頻域(Frequency domain)的觀點來看,頻率始終不變。
可以想像一下,在風琴按下四個鍵,發出的聲音在波形上是四個頻率的波疊加而成,雖然隨著時間過去,波形會有變化,然而聽到的,始終是四個鍵的音組而成,也就是始終是四個頻率的波組合而成。
對於波的疊加有了以上的基本認識,後續來看看,就影像處理而言,知道這些意謂著什麼….