IIR滤波器(InfiniteImpulse Response Filter)是一种数字滤波器,具有无限冲激响应特性。相对于FIR(有限冲激响应)滤波器,IIR滤波器具有更高的灵活性和更小的计算复杂度。本文将介绍IIR滤波器的原理、特点以及常见的设计方法。
(资料图)
一、IIR滤波器原理
IIR滤波器的原理基于差分方程,其中当前输出值取决于当前输入值和过去输出值的线性组合。这种递归结构导致IIR滤波器具有无限的冲激响应,因此可以对输入信号进行更复杂的频率响应调整。
IIR滤波器的差分方程一般形式如下:
y[n] = b0 * x[n] + b1 * x[n-1] + ... + bm * x[n-m] - a1 * y[n-1] - ... - an * y[n-n]
其中, x[n]是当前输入信号值, y[n]是当前输出信号值,b0, b1, ..., bm是输入系数,a1, ..., an是输出系数,m和n分别表示滤波器的输入和输出阶数。
IIR滤波器可以分为两类:无零点IIR滤波器和有零点IIR滤波器。无零点IIR滤波器的输出仅由过去的输出值和当前输入值决定,而有零点IIR滤波器的输出还受到过去的输入值的影响。
二、IIR滤波器特点
IIR滤波器具有以下特点:
递归结构:IIR滤波器通过反馈将输出连接到输入,形成递归结构。这种结构可以实现更高阶的滤波器,使得在相同滤波器阶数的情况下,与FIR滤波器相比,IIR滤波器具有更小的延迟和更高的频率选择能力。
宽带特性:相对于FIR滤波器,IIR滤波器可以实现更宽的带通和带阻特性,可以更好地适应频率选择要求。
计算效率:IIR滤波器通常比FIR滤波器具有更高的计算效率,因为它们不需要存储大量的前期样本,而是通过递归运算实现滤波过程。
频率选择:IIR滤波器可以实现更复杂的频率选择,例如椭圆滤波器和Chebyshev滤波器等,这些滤波器在某些应用中具有更好的频率响应特性。
时域响应:IIR滤波器的时域响应通常具有较长的尾部,这意味着它们对输入信号的变化有较慢的响应。这可以在一些应用中产生特殊的效果,如音频音效处理和混响效果。
稳定性:IIR滤波器的稳定性与极点的位置有关。为了确保滤波器的稳定性,极点必须位于单位圆内的稳定区域。因此,在IIR滤波器设计中,需要采取措施来控制极点的位置,以确保滤波器的稳定性。
三、IIR滤波器种类和设计
经典的IIR滤波器类型,包括Butterworth滤波器、Chebyshev I类和II类滤波器、椭圆滤波器和Bessel滤波器,都是为了逼近理想的矩形滤波器而设计的。
理想的矩形滤波器是在频率域中具有矩形形状的滤波器,它可以完全通过在通带内传递所需的频率分量,同时在阻带内完全抑制不需要的频率分量。然而,实际上很难实现理想的矩形滤波器,因为它要求在频率域中产生无限宽的截止带和无限陡的过渡带。
经典的IIR滤波器类型采用不同的设计策略来逼近理想的矩形滤波器:
(1)Butterworth滤波器:通过在通带和阻带之间均匀分布的幅度衰减来逼近理想矩形滤波器的幅频响应特性。它在通带内具有平坦的幅度响应,但在阻带中的衰减率相对较低。
(2)Chebyshev I类和II类滤波器:通过引入波纹来实现更陡峭的过渡带和更高的阻带衰减,从而更接近理想的矩形滤波器。Chebyshev I类滤波器在通带内具有最小的波纹,而Chebyshev II类滤波器在阻带内具有最小的波纹。
(3)椭圆滤波器:使用Cauer函数来设计,通过在通带和阻带内都具有波纹来实现更 steepend 的过渡带和更高的阻带衰减。椭圆滤波器在通带和阻带内都能够实现较小的幅度波纹。
(4)Bessel滤波器:通过在频率域中具有线性相位特性来逼近理想的矩形滤波器的相位响应。它对信号的相位不会引入额外的失真,但在幅度响应方面具有相对平滑的特性。
每种IIR滤波器类型都有其特定的设计方法和特点,适用于不同的应用场景和设计要求。选择适当的IIR滤波器类型取决于所需的频率响应特性、相位特性和设计复杂度。
3.1 Butterworth滤波器:
原理:Butterworth滤波器是一种最常见的IIR滤波器,其设计目标是在通带内具有尽可能平坦的幅度响应,同时保持最小的相位失真。它的特点是具有光滑的频率响应曲线,没有幅度波纹。
设计:Butterworth滤波器的设计通过控制滤波器的阶数和截止频率来实现。阶数越高,滤波器的频率选择能力越强。
import numpy as npfrom scipy.signal import butter, filtfiltimport matplotlib.pyplot as plt# 生成示例数据fs = 1000 # 采样频率t = np.arange(0, 1, 1/fs) # 时间序列x = np.sin(2 * np.pi* 5 * t) + np.sin(2 * np.pi * 50 * t) + np.random.randn(len(t)) * 0.2 # 混合信号# 定义Butterworth滤波器函数def butterworth_filter(data, cutoff_freq, filter_type, order, fs): nyquist_freq = 0.5 * fs cutoff = cutoff_freq / nyquist_freq # 设计Butterworth滤波器系数 b, a = butter(order, cutoff, btype=filter_type, analog=False, output="ba") # 将滤波器应用于数据 filtered_data = filtfilt(b, a, data) return filtered_data# 设计并应用低通滤波器cutoff_freq = 30 # 截止频率order = 4 # 阶数filter_type = "lowpass" # 滤波器类型lowpass_data = butterworth_filter(x, cutoff_freq, filter_type, order, fs)# 设计并应用带通滤波器cutoff_freqs = [20, 80] # 截止频率范围order = 4 # 阶数filter_type = "bandpass" # 滤波器类型bandpass_data = butterworth_filter(x, cutoff_freqs, filter_type, order, fs)# 设计并应用高通滤波器cutoff_freq = 50 # 截止频率order = 4 # 阶数filter_type = "highpass" # 滤波器类型highpass_data = butterworth_filter(x, cutoff_freq, filter_type, order, fs)# 设计并应用带阻滤波器cutoff_freqs = [40, 60] # 截止频率范围order = 4 # 阶数filter_type = "bandstop" # 滤波器类型bandstop_data = butterworth_filter(x, cutoff_freqs, filter_type, order, fs)# 绘制原始信号和滤波后的信号plt.figure(figsize=(10, 6))plt.subplot(5, 1, 1)plt.plot(t, x)plt.title("Original Signal")plt.subplot(5, 1, 2)plt.plot(t, lowpass_data)plt.title("Lowpass Filtered Signal")plt.subplot(5, 1, 3)plt.plot(t, bandpass_data)plt.title("Bandpass Filtered Signal")plt.subplot(5, 1, 4)plt.plot(t, highpass_data)plt.title("Highpass Filtered Signal")plt.subplot(5, 1, 5)plt.plot(t, bandstop_data)plt.title("Bandstop Filtered Signal")plt.tight_layout()plt.show()
上述代码中,我们首先生成了一个示例数据 x
,然后定义了一个名为 butterworth_filter
的函数,用于设计和应用 Butterworth 滤波器。接下来,我们分别使用不同的截止频率和滤波器类型调用该函数来实现低通、带通、高通和带阻滤波。最后,我们使用 Matplotlib 库绘制了原始信号和滤波后的信号。 请注意,以上示例仅用于演示如何使用 Butterworth 滤波器进行低通、带通、高通和带阻滤波,实际应用中需要根据具体需求调整截止频率、阶数和滤波器类型等参数。
3.2 Chebyshev滤波器:
原理:Chebyshev滤波器是一种具有优良频率选择特性的IIR滤波器。它可以分为两种类型:Chebyshev Type I和Chebyshev Type II。Chebyshev Type I滤波器在通带内具有最小的幅度波纹,而Chebyshev Type II滤波器在阻带内具有最小的幅度波纹。
设计:Chebyshev滤波器的设计需要指定滤波器的阶数、截止频率和幅度波纹。幅度波纹越小,阻带衰减越大,滤波器的设计复杂度也相应增加。
import numpy as npfrom scipy.signal import cheby1, cheby2, filtfiltimport matplotlib.pyplot as plt# 生成示例数据fs = 1000 # 采样频率t = np.arange(0, 1, 1/fs) # 时间序列x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 50 * t) + np.random.randn(len(t)) * 0.2 # 混合信号# 定义Chebyshev滤波器函数def chebyshev_filter(data, cutoff_freq, filter_type, order, rs, fs): nyquist_freq = 0.5 * fs cutoff = cutoff_freq / nyquist_freq if filter_type == "lowpass": b, a = cheby1(order, rs, cutoff, btype="low", analog=False, output="ba") elif filter_type == "highpass": b, a = cheby1(order, rs, cutoff, btype="high", analog=False, output="ba") elif filter_type == "bandpass": b, a = cheby2(order, rs, cutoff, btype="bandpass", analog=False, output="ba") elif filter_type == "bandstop": b, a = cheby2(order, rs, cutoff, btype="bandstop", analog=False, output="ba") else: raise ValueError("Invalid filter type") filtered_data = filtfilt(b, a, data) return filtered_data# 设计并应用低通滤波器cutoff_freq = 30 # 截止频率order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)lowpass_data = chebyshev_filter(x, cutoff_freq, "lowpass", order, rs, fs)# 设计并应用带通滤波器cutoff_freqs = [20, 80] # 截止频率范围order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)bandpass_data = chebyshev_filter(x, cutoff_freqs, "bandpass", order, rs, fs)# 设计并应用高通滤波器cutoff_freq = 50 # 截止频率order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)highpass_data = chebyshev_filter(x, cutoff_freq, "highpass", order, rs, fs)# 设计并应用带阻滤波器cutoff_freqs = [40, 60] # 截止频率范围order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)bandstop_data = chebyshev_filter(x, cutoff_freqs, "bandstop", order, rs, fs)# 绘制原始信号和滤波后的信号plt.figure(figsize=(10, 6))plt.subplot(5, 1, 1)plt.plot(t, x)plt.title("Original Signal")plt.subplot(5, 1, 2)plt.plot(t, lowpass_data)plt.title("Lowpass Filtered Signal")plt.subplot(5, 1, 3)plt.plot(t, bandpass_data)plt.title("Bandpass Filtered Signal")plt.subplot(5, 1, 4)plt.plot(t, highpass_data)plt.title("Highpass Filtered Signal")plt.subplot(5, 1, 5)plt.plot(t, bandstop_data)plt.title("Bandstop Filtered Signal")plt.tight_layout()plt.show()
在上述代码中,我们首先生成了一个示例数据 x,然后定义了一个名为 chebyshev_filter 的函数,用于设计和应用Chebyshev滤波器。根据滤波器类型,我们使用 cheby1 或 cheby2 函数来设计Chebyshev I类或II类滤波器系数。接下来,我们分别使用不同的截止频率、阶数和阻带衰减调用该函数来实现低通、带通、高通和带阻滤波。最后,我们使用Matplotlib库绘制了原始信号和滤波后的信号。
3.3 椭圆滤波器:
原理:椭圆滤波器是一种具有最 steepend 的衰减率和最小幅度波纹的IIR滤波器。它在通带和阻带内都具有较小的幅度波纹,但在过渡带中会有较宽的波纹。
设计:椭圆滤波器的设计需要指定滤波器的阶数、截止频率、幅度波纹和过渡带宽度。椭圆滤波器的设计较复杂,需要进行频域优化,以实现所需的频率响应。
import numpy as npfrom scipy.signal import ellip, filtfiltimport matplotlib.pyplot as plt# 生成示例数据fs = 1000 # 采样频率t = np.arange(0, 1, 1/fs) # 时间序列x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 50 * t) + np.random.randn(len(t)) * 0.2 # 混合信号# 定义椭圆滤波器函数def ellip_filter(data, cutoff_freq, filter_type, order, rs, rp, fs): nyquist_freq = 0.5 * fs cutoff = cutoff_freq / nyquist_freq if filter_type == "lowpass": b, a = ellip(order, rp, rs, cutoff, btype="low", analog=False, output="ba") elif filter_type == "highpass": b, a = ellip(order, rp, rs, cutoff, btype="high", analog=False, output="ba") elif filter_type == "bandpass": lower_cutoff = cutoff[0] upper_cutoff = cutoff[1] b, a = ellip(order, rp, rs, [lower_cutoff, upper_cutoff], btype="bandpass", analog=False, output="ba") elif filter_type == "bandstop": lower_cutoff = cutoff[0] upper_cutoff = cutoff[1] b, a = ellip(order, rp, rs, [lower_cutoff, upper_cutoff], btype="bandstop", analog=False, output="ba") else: raise ValueError("Invalid filter type") filtered_data = filtfilt(b, a, data) return filtered_data# 设计并应用低通滤波器cutoff_freq = 30 # 截止频率order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)rp = 1 # 通带最大衰减(单位:dB)lowpass_data = ellip_filter(x, cutoff_freq, "lowpass", order, rs, rp, fs)# 设计并应用带通滤波器cutoff_freqs = [20, 80] # 截止频率范围order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)rp = 1 # 通带最大衰减(单位:dB)bandpass_data = ellip_filter(x, cutoff_freqs, "bandpass", order, rs, rp, fs)# 设计并应用高通滤波器cutoff_freq = 50 # 截止频率order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)rp = 1 # 通带最大衰减(单位:dB)highpass_data = ellip_filter(x, cutoff_freq, "highpass", order, rs, rp, fs)# 设计并应用# 设计并应用带阻滤波器cutoff_freqs = [40, 60] # 截止频率范围order = 4 # 阶数rs = 60 # 阻带衰减(单位:dB)rp = 1 # 通带最大衰减(单位:dB)bandstop_data = ellip_filter(x, cutoff_freqs, "bandstop", order, rs, rp, fs)# 绘制原始信号和滤波后的信号plt.figure(figsize=(10, 6))plt.subplot(5, 1, 1)plt.plot(t, x)plt.title("Original Signal")plt.subplot(5, 1, 2)plt.plot(t, lowpass_data)plt.title("Lowpass Filtered Signal")plt.subplot(5, 1, 3)plt.plot(t, bandpass_data)plt.title("Bandpass Filtered Signal")plt.subplot(5, 1, 4)plt.plot(t, highpass_data)plt.title("Highpass Filtered Signal")plt.subplot(5, 1, 5)plt.plot(t, bandstop_data)plt.title("Bandstop Filtered Signal")plt.tight_layout()plt.show()
在上述代码中,我们首先生成了一个示例数据 x,然后定义了一个名为 ellip_filter 的函数,用于设计和应用椭圆滤波器。根据滤波器类型,我们使用 ellip 函数来设计椭圆滤波器系数。接下来,我们分别使用不同的截止频率、阶数、阻带衰减和通带最大衰减调用该函数来实现低通、带通、高通和带阻滤波。最后,我们使用Matplotlib库绘制了原始信号和滤波后的信号。
3.4 Bessel滤波器:
原理:Bessel滤波器是一种具有线性相位特性的IIR滤波器。它具有平滑的幅度响应和最小的相位失真,能够保持信号的波形形状。Bessel滤波器对于保持信号的相位一致是非常有效的选择。
设计:Bessel滤波器的设计相对简单,主要需要指定滤波器的阶数和截止频率。
import numpy as npfrom scipy.signal import bessel, filtfiltimport matplotlib.pyplot as plt# 生成示例数据fs = 1000 # 采样频率t = np.arange(0, 1, 1/fs) # 时间序列x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 50 * t) + np.random.randn(len(t)) * 0.2 # 混合信号# 定义Bessel滤波器函数def bessel_filter(data, cutoff_freq, filter_type, order, fs): nyquist_freq = 0.5 * fs cutoff = cutoff_freq / nyquist_freq if filter_type == "lowpass": b, a = bessel(order, cutoff, btype="low", analog=False, output="ba") elif filter_type == "highpass": b, a = bessel(order, cutoff, btype="high", analog=False, output="ba") elif filter_type == "bandpass": lower_cutoff = cutoff[0] upper_cutoff = cutoff[1] b, a = bessel(order, [lower_cutoff, upper_cutoff], btype="bandpass", analog=False, output="ba") elif filter_type == "bandstop": lower_cutoff = cutoff[0] upper_cutoff = cutoff[1] b, a = bessel(order, [lower_cutoff, upper_cutoff], btype="bandstop", analog=False, output="ba") else: raise ValueError("Invalid filter type") filtered_data = filtfilt(b, a, data) return filtered_data# 设计并应用低通滤波器cutoff_freq = 30 # 截止频率order = 4 # 阶数lowpass_data = bessel_filter(x, cutoff_freq, "lowpass", order, fs)# 设计并应用带通滤波器cutoff_freqs = [20, 80] # 截止频率范围order = 4 # 阶数bandpass_data = bessel_filter(x, cutoff_freqs, "bandpass", order, fs)# 设计并应用高通滤波器cutoff_freq = 50 # 截止频率order = 4 # 阶数highpass_data = bessel_filter(x, cutoff_freq, "highpass", order, fs)# 设计并应用带阻滤波器cutoff_freqs = [40, 60] # 截止频率范围order = 4 # 阶数bandstop_data = bessel_filter(x, cutoff_freqs, "bandstop", order, fs)# 绘制原始信号和滤波后的信号plt.figure(figsize=(10, 6))plt.subplot(5, 1, 1)plt.plot(t, x)plt.title("Original Signal")plt.subplot(5, 1, 2)plt.plot(t, lowpass_data)plt.title("Lowpass Filtered Signal")plt.subplot(5, 1, 3)plt.plot(t, bandpass_data)plt.title("Bandpass Filtered Signal")plt.subplot(5, 1, 4)plt.plot(t, highpass_data)plt.title("Highpass Filtered Signal")plt.subplot(5, 1, 5)plt.plot(t, bandstop_data)plt.title("Bandstop Filtered Signal")plt.tight_layout()plt.show()
在上述代码中,我们首先生成了一个示例数据 x,然后定义了一个名为 bessel_filter 的函数,用于设计和应用Bessel滤波器。根据滤波器类型,我们使用 bessel 函数来设计Bessel滤波器系数。接下来,我们分别使用不同的截止频率、阶数调用该函数来实现低通、带通、高通和带阻滤波。最后,我们使用Matplotlib库绘制了原始信号和滤波后的信号。
选择适当的IIR滤波器类型取决于应用需求。例如,如果需要平滑的频率响应和线性相位特性,则Bessel滤波器是一个不错的选择。如果需要在通带或阻带内具有更小的幅度波纹,则可以考虑Chebyshev滤波器。而如果需要最大的衰减率和最小的幅度波纹,则椭圆滤波器可能是更合适的选择。