scipy.signal.

kaiserord#

scipy.signal.kaiserord(ripple, width)[source]#

決定 Kaiser 視窗法的濾波器視窗參數。

此函數傳回的參數通常用於使用視窗法建立有限脈衝響應濾波器,可搭配 firwinfirwin2 使用。

參數:
ripplefloat

濾波器頻率響應的幅度與所需濾波器(不包括任何過渡區間中的頻率)的偏差(以 dB 為單位)上限。也就是說,如果 w 是表示為奈奎斯特頻率的分數的頻率,A(w) 是濾波器的實際頻率響應,而 D(w) 是所需的頻率響應,則設計要求為:

abs(A(w) - D(w))) < 10**(-ripple/20)

對於 0 <= w <= 1 且 w 不在過渡區間內。

widthfloat

過渡區域的寬度,已標準化,因此 1 對應於 pi 弧度 / 樣本。也就是說,頻率表示為奈奎斯特頻率的分數。

回傳值:
numtapsint

Kaiser 視窗的長度。

betafloat

Kaiser 視窗的 beta 參數。

另請參閱

kaiser_beta, kaiser_atten

註解

有幾種方法可以取得 Kaiser 視窗

  • signal.windows.kaiser(numtaps, beta, sym=True)

  • signal.get_window(beta, numtaps)

  • signal.get_window(('kaiser', beta), numtaps)

使用 Kaiser 發現的經驗方程式。

參考文獻

Oppenheim, Schafer, “Discrete-Time Signal Processing”, pp.475-476.

範例

我們將使用 Kaiser 視窗法設計一個低通 FIR 濾波器,用於以 1000 Hz 採樣的訊號。

我們希望在阻帶中至少有 65 dB 的抑制,並且在通帶中增益變化不應超過 0.5%。

我們希望截止頻率為 175 Hz,通帶和阻帶之間的過渡頻寬為 24 Hz。也就是說,在 [0, 163] 頻帶中,增益變化不超過 0.5%,在 [187, 500] 頻帶中,訊號衰減至少 65 dB。

>>> import numpy as np
>>> from scipy.signal import kaiserord, firwin, freqz
>>> import matplotlib.pyplot as plt
>>> fs = 1000.0
>>> cutoff = 175
>>> width = 24

Kaiser 方法僅接受單一參數來控制通帶漣波和阻帶抑制,因此我們使用兩者中較嚴格的一個。在本例中,通帶漣波為 0.005 或 46.02 dB,因此我們將使用 65 dB 作為設計參數。

使用 kaiserord 來決定濾波器的長度和 Kaiser 視窗的參數。

>>> numtaps, beta = kaiserord(65, width/(0.5*fs))
>>> numtaps
167
>>> beta
6.20426

使用 firwin 來建立 FIR 濾波器。

>>> taps = firwin(numtaps, cutoff, window=('kaiser', beta),
...               scale=False, fs=fs)

計算濾波器的頻率響應。w 是頻率陣列,而 h 是對應的頻率響應複數陣列。

>>> w, h = freqz(taps, worN=8000)
>>> w *= 0.5*fs/np.pi  # Convert w to Hz.

計算濾波器響應幅度與理想低通濾波器響應幅度的偏差。過渡區域中的值設定為 nan,因此它們不會出現在圖表中。

>>> ideal = w < cutoff  # The "ideal" frequency response.
>>> deviation = np.abs(np.abs(h) - ideal)
>>> deviation[(w > cutoff - 0.5*width) & (w < cutoff + 0.5*width)] = np.nan

繪製偏差圖。仔細觀察阻帶的左端,會發現第一個旁瓣中違反了 65 dB 衰減的要求約 0.125 dB。這對於 Kaiser 視窗法來說並不罕見。

>>> plt.plot(w, 20*np.log10(np.abs(deviation)))
>>> plt.xlim(0, 0.5*fs)
>>> plt.ylim(-90, -60)
>>> plt.grid(alpha=0.25)
>>> plt.axhline(-65, color='r', ls='--', alpha=0.3)
>>> plt.xlabel('Frequency (Hz)')
>>> plt.ylabel('Deviation from ideal (dB)')
>>> plt.title('Lowpass Filter Frequency Response')
>>> plt.show()
../../_images/scipy-signal-kaiserord-1.png