一、定義
FIR(Finite Impulse Response,有限脈沖響應)濾波器是一種數(shù)字濾波器,其輸出信號僅由輸入信號和濾波器的沖激響應決定。FIR濾波器的名稱源于其沖激響應是一個有限長度的序列。
FIR濾波器的特點是具有穩(wěn)定性、線性相位特性和精確控制頻率響應的能力。它通過將輸入信號與濾波器的沖激響應進行卷積運算來實現(xiàn)信號的濾波效果。FIR濾波器在實際應用中廣泛用于濾除噪聲、提取信號特征、平滑數(shù)據(jù)等。
FIR濾波器的設計涉及選擇濾波器的階數(shù)(即沖激響應的長度)和確定濾波器的系數(shù)。常見的FIR濾波器設計方法包括窗函數(shù)法、頻率采樣法、最小最大法等。設計濾波器的目標是在滿足特定頻率響應需求的同時,盡可能減小濾波器的階數(shù)和降低誤差。
FIR濾波器具有一些優(yōu)點,例如相對較簡單的實現(xiàn)、穩(wěn)定性和可控的頻率響應。然而,較高階數(shù)的FIR濾波器可能需要更多的計算資源,并且在實時應用中可能引入一定的延遲。
二、原理
FIR(Finite Impulse Response,有限脈沖響應)濾波器是一種數(shù)字濾波器,其原理可以從時域和頻域兩個方面進行解釋。
2.1時域原理
FIR濾波器的輸出是通過將輸入信號與濾波器的沖激響應進行卷積得到的。沖激響應是濾波器對單位脈沖輸入信號的響應,它描述了濾波器在時域上的特性。FIR濾波器的沖激響應是一個有限長度的序列,因此稱為有限脈沖響應濾波器。
FIR濾波器的輸出可以用以下公式表示:
y[n] = b[0]*x[n] + b[1]*x[n-1] + b[2]*x[n-2] + ... + b[N]*x[n-N]
其中,y[n]是輸出信號的樣本值,x[n]是輸入信號的樣本值,b[0], b[1], ..., b[N]是濾波器的沖激響應系數(shù),N是濾波器的階數(shù)。
2.2頻域原理
在頻域上,F(xiàn)IR濾波器可以通過濾波器的頻率響應來解釋。濾波器的頻率響應是指濾波器對不同頻率信號的響應特性。FIR濾波器的頻率響應是由濾波器的沖激響應確定的。
FIR濾波器的頻率響應可以用以下公式表示:
H(f) = b[0]e^(-j2pif0) + b[1]e^(-j2pif1) + ... + b[N]e^(-j2pif*N)
其中,H(f)是濾波器的頻率響應,b[0], b[1], ..., b[N]是濾波器的沖激響應系數(shù),f是頻率,j是虛數(shù)單位。
FIR濾波器的頻率響應可以通過選擇合適的沖激響應系數(shù)來控制,從而實現(xiàn)對不同頻率信號的濾波效果。不同的沖激響應系數(shù)會導致不同的頻率響應特性,例如低通、高通、中通或帶阻等濾波器類型。
三、標準頻帶 FIR 濾波器設計
fir1/firwin使用最小二乘逼近計算濾波器系數(shù),然后通過加窗對脈沖響應進行平滑處理。標準頻帶FIR濾波器是一種常見的設計方法,用于滿足特定的頻率響應需求。該設計方法旨在設計一個FIR濾波器,使其在指定的頻率范圍內具有預期的增益或衰減特性。下面是標準頻帶FIR濾波器的設計步驟:
(1)確定設計規(guī)格:
確定濾波器類型:低通、高通、中通或帶阻濾波器。
確定截止頻率:指定濾波器在頻率響應中的截止頻率。
確定通帶增益或衰減:指定濾波器在通帶內的增益或衰減要求。
確定阻帶衰減:如果是帶阻濾波器,指定濾波器在阻帶內的衰減要求。
(2)選擇窗函數(shù):
常用的窗函數(shù)包括矩形窗、漢寧窗、漢明窗、布萊克曼窗等。
根據(jù)設計規(guī)格選擇合適的窗函數(shù),不同的窗函數(shù)會對頻率響應產生不同的影響。
(3)確定濾波器的長度:
根據(jù)設計規(guī)格和選擇的窗函數(shù),確定濾波器的長度(階數(shù))。
濾波器的長度越長,頻率響應越精確,但計算復雜度也增加。
(4)設計濾波器:
使用窗函數(shù)法計算濾波器的沖激響應。
根據(jù)設計規(guī)格和選擇的窗函數(shù),計算濾波器的系數(shù)。
(5)可選的優(yōu)化步驟:
可以通過調整窗函數(shù)的參數(shù)、調整濾波器長度或使用其他設計方法來進一步優(yōu)化濾波器的性能。
(6)應用濾波器:
將設計好的濾波器系數(shù)應用于輸入信號,通過卷積運算獲得濾波后的輸出信號。
Python中的SciPy庫提供了fir1/firwin函數(shù),可以方便地進行標準頻帶FIR濾波器的設計。
firwin函數(shù):
firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True, scale=True, fs=2.0)
numtaps :濾波器的長度(階數(shù))。
cutoff :截止頻率或截止頻率數(shù)組。對于低通和高通濾波器,可以是一個標量值;對于帶通和帶阻濾波器,可以是包含兩個截止頻率的列表或數(shù)組。
width :僅在帶通和帶阻濾波器中使用,表示過渡帶(transition band)的寬度。
window :窗函數(shù)的類型,默認為漢明窗('hamming')。
pass_zero :確定濾波器是否通過零頻率點。對于低通和帶通濾波器,為True表示通過零頻率;對于高通和帶阻濾波器,為False表示不通過零頻率。
scale :指定是否對濾波器系數(shù)進行縮放。
fs :采樣頻率。
fir1函數(shù):
fir1(numtaps, cutoff, window='hamming', pass_zero=True, scale=True, fs=2.0)
參數(shù)與firwin函數(shù)類似,但沒有width參數(shù)。
fir1函數(shù)返回濾波器的沖激響應系數(shù),可以使用這些系數(shù)應用于輸入信號。
使用firwin函數(shù)設計一個低通FIR濾波器
from scipy.signal import firwin, lfilter
import numpy as np
import matplotlib.pyplot as plt
# 設計規(guī)格
numtaps = 101 # 濾波器長度
cutoff = 0.4 # 截止頻率
fs = 1.0 # 采樣頻率
# 使用firwin函數(shù)設計低通FIR濾波器
filter_coeff = firwin(numtaps, cutoff, fs=fs)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 應用濾波器
input_signal = np.random.randn(1000) # 輸入信號為隨機噪聲
output_signal = lfilter(filter_coeff, 1, input_signal)
# 繪制輸入信號和輸出信號的時域波形
time = np.arange(0, len(input_signal)) / fs
plt.figure()
plt.plot(time, input_signal, label='Input Signal')
plt.plot(time, output_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Time Domain Waveform')
plt.legend()
plt.grid(True)
plt.show()
使用firwin函數(shù)設計一個中通FIR濾波器
from scipy.signal import firwin, lfilter
import numpy as np
import matplotlib.pyplot as plt
# 設計規(guī)格
numtaps = 101 # 濾波器長度
cutoff = [0.2, 0.6] # 截止頻率范圍
fs = 1.0 # 采樣頻率
# 使用firwin函數(shù)設計中通FIR濾波器
filter_coeff = firwin(numtaps, cutoff, fs=fs, pass_zero=False)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 應用濾波器
input_signal = np.random.randn(1000) # 輸入信號為隨機噪聲
output_signal = lfilter(filter_coeff, 1, input_signal)
# 繪制輸入信號和輸出信號的時域波形
time = np.arange(0, len(input_signal)) / fs
plt.figure(figsize=(10, 4))
plt.plot(time, input_signal, label='Input Signal')
plt.plot(time, output_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Time Domain Waveform')
plt.legend()
plt.grid(True)
plt.show()
使用firwin函數(shù)設計一個高通FIR濾波器
firwin函數(shù)在設計高通(highpass)和低通(lowpass)FIR濾波器時具有一些差異:
高通FIR濾波器:
對于高通濾波器,你需要將cutoff參數(shù)設置為截止頻率,并將pass_zero參數(shù)設置為False,表示濾波器不通過零頻率點。
高通濾波器將保留高于截止頻率的信號成分,而抑制低于截止頻率的信號成分。
低通FIR濾波器:
對于低通濾波器,你需要將cutoff參數(shù)設置為截止頻率,并將pass_zero參數(shù)設置為True,表示濾波器通過零頻率點。
低通濾波器將保留低于截止頻率的信號成分,而抑制高于截止頻率的信號成分。
from scipy.signal import firwin, lfilter
import numpy as np
import matplotlib.pyplot as plt
# 設計規(guī)格
numtaps = 101 # 濾波器長度
cutoff = 0.4 # 截止頻率
fs = 1.0 # 采樣頻率
# 使用firwin函數(shù)設計高通FIR濾波器
filter_coeff = firwin(numtaps, cutoff, fs=fs, pass_zero=False)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 應用濾波器
input_signal = np.random.randn(1000) # 輸入信號為隨機噪聲
output_signal = lfilter(filter_coeff, 1, input_signal)
# 繪制輸入信號和輸出信號的時域波形
time = np.arange(0, len(input_signal)) / fs
plt.figure(figsize=(10, 4))
plt.plot(time, input_signal, label='Input Signal')
plt.plot(time, output_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Time Domain Waveform')
plt.legend()
plt.grid(True)
plt.show()
使用firwin函數(shù)設計一個帶阻FIR濾波器
firwin函數(shù)在設計帶通(bandpass)和帶阻(bandstop)FIR濾波器時具有一些差異:
帶通FIR濾波器:
對于帶通濾波器,你需要將包含兩個截止頻率的列表或數(shù)組作為cutoff參數(shù),并將pass_zero參數(shù)設置為True。
帶通濾波器將保留位于截止頻率范圍內的信號成分,而抑制位于截止頻率范圍外的信號成分。
帶阻FIR濾波器:
對于帶阻濾波器,你需要將包含兩個截止頻率的列表或數(shù)組作為cutoff參數(shù),并將pass_zero參數(shù)設置為False。
帶阻濾波器將抑制位于截止頻率范圍內的信號成分,而保留位于截止頻率范圍外的信號成分。
from scipy.signal import firwin, lfilter
import numpy as np
import matplotlib.pyplot as plt
# 設計規(guī)格
numtaps = 101 # 濾波器長度
cutoff = [0.4, 0.6] # 截止頻率范圍
fs = 1.0 # 采樣頻率
# 使用firwin函數(shù)設計帶阻FIR濾波器
filter_coeff = firwin(numtaps, cutoff, fs=fs, pass_zero=True)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 應用濾波器
input_signal = np.random.randn(1000) # 輸入信號為隨機噪聲
output_signal = lfilter(filter_coeff, 1, input_signal)
# 繪制輸入信號和輸出信號的時域波形
time = np.arange(0, len(input_signal)) / fs
plt.figure(figsize=(10, 4))
plt.plot(time, input_signal, label='Input Signal')
plt.plot(time, output_signal, label='Filtered Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('Time Domain Waveform')
plt.legend()
plt.grid(True)
plt.show()
四、Kaiser 窗階估計
Kaiser窗法(Kaiser window method)是一種用于FIR濾波器設計的方法,它利用Kaiser窗函數(shù)來估計濾波器的階數(shù)(即濾波器長度)。Kaiser窗函數(shù)是一種基于貝塞爾函數(shù)的調制函數(shù),具有可調節(jié)的參數(shù)β,可以控制窗函數(shù)的主瓣寬度和副瓣衰減。
Kaiser窗階估計的步驟如下:
(1)確定設計規(guī)格:包括濾波器的截止頻率、過渡帶寬、最大衰減和窗函數(shù)的形狀參數(shù)β。
(2)計算濾波器的階數(shù):根據(jù)設計規(guī)格和窗函數(shù)的參數(shù)β,使用公式或表格來計算濾波器的階數(shù)。一種常用的計算公式是根據(jù)貝塞爾函數(shù)的零階近似計算:
scssCopy codeN = (A - 8) / (2.285 * 2π * Δf) + 1
其中,N是濾波器的階數(shù),A是最大衰減(以分貝為單位),Δf是過渡帶寬。
(3)生成Kaiser窗函數(shù):使用計算得到的階數(shù)N和參數(shù)β,生成Kaiser窗函數(shù)。Kaiser窗函數(shù)可以通過NumPy中的kaiser函數(shù)來生成。
(4)設計FIR濾波器:使用firwin函數(shù),將生成的Kaiser窗函數(shù)作為窗函數(shù)參數(shù),指定其他設計規(guī)格(如截止頻率、過渡帶寬等),生成最終的FIR濾波器系數(shù)。
下面是一個示例代碼,展示了如何使用Kaiser窗階估計方法設計一個FIR濾波器:
from scipy.signal import firwin, kaiser
import numpy as np
import matplotlib.pyplot as plt
# 設計規(guī)格
cutoff = 0.2 # 截止頻率
transition_width = 0.1 # 過渡帶寬
attenuation = 60 # 最大衰減(單位:分貝)
sampling_freq = 1000 # 采樣頻率
# 計算濾波器的階數(shù)
delta_freq = transition_width * 0.5
N = int((attenuation - 7.95) / (2.285 * 2 * np.pi * delta_freq) + 1)
# 生成Kaiser窗函數(shù)
beta = kaiser_beta = np.kaiser_beta(attenuation)
window = kaiser(N, beta)
# 設計FIR濾波器
filter_coeff = firwin(N, cutoff, window=window, fs=sampling_freq)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 繪制濾波器的頻率響應
freq, response = scipy.signal.freqz(filter_coeff)
magnitude = np.abs(response)
magnitude_db =
五、多頻帶FIR濾波器設計
fir2/firwin2函數(shù)還可用于設計加窗的FIR濾波器,但具有任意形狀的分段線性頻率響應。這與fir1/firwin不同,后者僅設計具有標準低通、高通、帶通和帶阻配置的濾波器。
scipy.signal.fir2(numtaps, freq, gain, fs=2.0, window='hamming', nyq=None, antisymmetric=False)
參數(shù):
numtaps(整數(shù)) :濾波器的長度(階數(shù)),決定了濾波器的頻率響應的分辨率和計算復雜度。
freq(數(shù)組): 包含頻率點的序列,用于定義濾波器的頻率響應。頻率范圍為0到0.5(歸一化頻率),其中0.5對應采樣頻率的一半。
gain(數(shù)組): 與頻率點相對應的增益值,用于定義濾波器的目標頻率響應。
fs(標量): 采樣頻率,用于指定頻率的單位。默認為2.0,表示采樣頻率的一半。如果nyq參數(shù)也提供了,則fs參數(shù)會被忽略。
window(字符串或數(shù)組) : 指定窗函數(shù)的類型或窗函數(shù)自身??梢允褂米址付藴蚀昂瘮?shù),如'hamming'、'hann'、'blackman'等。也可以直接傳遞一個窗函數(shù)數(shù)組,長度為numtaps,用于自定義窗函數(shù)。
nyq(標量): 采樣頻率的一半,用于指定頻率的單位。如果未提供,則默認為fs/2.0。
antisymmetric(布爾值): 指定濾波器是否為反對稱濾波器。默認為False,表示濾波器為一般的線性相位濾波器。
返回值:
h(一維數(shù)組): FIR濾波器的系數(shù)。
scipy.signal.firwin2(numtaps, freq, gain, fs=2.0, window='hamming', nyq=None)
參數(shù):
numtaps(整數(shù)): 濾波器的長度(階數(shù)),決定了濾波器的頻率響應的分辨率和計算復雜度。
freq(一維數(shù)組): 頻率段邊界點的列表或數(shù)組,用于定義濾波器的頻率響應。頻率段邊界點應在0到fs/2之間,其中fs為采樣頻率。
gain(一維數(shù)組): 與頻率段相應的增益值的列表或數(shù)組,用于定義濾波器的目標頻率響應。
fs(標量): 采樣頻率,用于指定頻率的單位。默認為2.0,表示采樣頻率的一半。
window(字符串或數(shù)組): 指定窗函數(shù)的類型或窗函數(shù)自身??梢允褂米址付藴蚀昂瘮?shù),如'hamming'、'hann'、'blackman'等。也可以直接傳遞一個窗函數(shù)數(shù)組,長度為numtaps,用于自定義窗函數(shù)。
nyq(標量): 采樣頻率的一半,用于指定頻率的單位。如果未提供,則默認為fs/2.0。
返回值:
h(一維數(shù)組): FIR濾波器的系數(shù)。
下面是一個使用firwin2函數(shù)設計多頻帶FIR濾波器的示例代碼:
from scipy.signal import firwin2, freqz
import matplotlib.pyplot as plt
# 定義頻率點
freq = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5]
# 定義增益值
gain = [1.0, 1.0, 0.0, 0.0, 1.0, 1.0]
# 設計多頻帶FIR濾波器
filter_coeff = firwin2(101, freq, gain)
# 打印濾波器系數(shù)
print("Filter Coefficients:", filter_coeff)
# 繪制濾波器的頻率響應
w, h = freqz(filter_coeff)
plt.plot(w, abs(h))
plt.xlabel('Frequency')
plt.ylabel('Magnitude')
plt.title('Frequency Response')
plt.grid(True)
plt.show()
-
數(shù)字濾波器
+關注
關注
4文章
270瀏覽量
47026 -
衰減器
+關注
關注
4文章
640瀏覽量
34346 -
模擬器
+關注
關注
2文章
875瀏覽量
43223 -
fir濾波器
+關注
關注
1文章
95瀏覽量
19042 -
python
+關注
關注
56文章
4797瀏覽量
84689
發(fā)布評論請先 登錄
相關推薦
評論