scipy.signal.

remez#

scipy.signal.remez(numtaps, bands, desired, *, weight=None, type='bandpass', maxiter=25, grid_density=16, fs=None)[源代码]#

使用 Remez 交换算法计算极小极大最优滤波器。

计算有限脉冲响应 (FIR) 滤波器的滤波器系数,其传递函数使用 Remez 交换算法最大程度减小指定频带中所需增益与实际增益之间最大的误差。

参数:
numtapsint

滤波器中所需抽头的数量。抽头的数量是滤波器中项的数量,或滤波器阶数加一。

bandsarray_like

包含频带边缘的单调序列。所有元素都必须为非负数并且小于由 fs 给出的采样频率的一半。

desired类数组

一个序列,是频带大小的一半,其中包含每个指定频带内的期望增益。

weight类数组,可选

指定给每个频带区域的相对权重。分量 weight 的长度必须为 分量 bands 的一半长度。

type{'bandpass', 'differentiator', 'hilbert'}, 可选

滤波器的类型

  • 'bandpass':在频带内有平坦响应。这是默认值。

  • 'differentiator':在频带内有频率比例响应。

  • 'hilbert'具有奇对称性的滤波器,即 III 型滤波器

    (对于偶数阶滤波器)或 IV 型(对于奇数阶滤波器)线性相位滤波器。

maxiterint, 可选

算法的最大迭代次数。缺省值为 25。

grid_densityint, 可选

网格密度。在 remez 中使用的密集网格大小为 (numtaps + 1) * grid_density。缺省值为 16。

fsfloat, 可选

信号的采样频率。缺省值为 1。

返回值 :
outndarray

一个包含最优(最小极大值意义上的)滤波器系数的 1 级数组。

参考文献

[1]

J. H. McClellan 和 T. W. Parks,“设计最优 FIR 线性相位数字滤波器的统一方法”,IEEE 电路理论学报,第 CT-20 卷,第 697-701 页,1973 年。

[2]

J. H. McClellan、T. W. Parks 和 L. R. Rabiner,“设计最优 FIR 线性相位数字滤波器的计算机程序”,IEEE 音频电子声学学报,第 AU-21 卷,第 506-525 页,1973 年。

示例

在这些示例中,remez 用于设计低通、高通、带通和带阻滤波器。定义每个滤波器的参数包括滤波器阶数、频带边界、边界的过渡宽度、每个频带内的期望增益和采样频率。

在所有示例中,我们将使用 22050 Hz 的采样频率。在每个示例中,每个频带内的期望增益均为 0(对于阻带)或 1(对于通带)。

freqz 用于计算每个滤波器的频率响应,并且下面定义的实用函数 plot_response 用于绘制该响应。

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> fs = 22050   # Sample rate, Hz
>>> def plot_response(w, h, title):
...     "Utility function to plot response functions"
...     fig = plt.figure()
...     ax = fig.add_subplot(111)
...     ax.plot(w, 20*np.log10(np.abs(h)))
...     ax.set_ylim(-40, 5)
...     ax.grid(True)
...     ax.set_xlabel('Frequency (Hz)')
...     ax.set_ylabel('Gain (dB)')
...     ax.set_title(title)

第一个例子是低通滤波器,截止频率为 8 kHz。滤波器长度为 325,从通带到阻带的转换宽度为 100 Hz。

>>> cutoff = 8000.0    # Desired cutoff frequency, Hz
>>> trans_width = 100  # Width of transition from pass to stop, Hz
>>> numtaps = 325      # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff, cutoff + trans_width, 0.5*fs],
...                     [1, 0], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Low-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_00_00.png

此示例显示了高通滤波器

>>> cutoff = 2000.0    # Desired cutoff frequency, Hz
>>> trans_width = 250  # Width of transition from pass to stop, Hz
>>> numtaps = 125      # Size of the FIR filter.
>>> taps = signal.remez(numtaps, [0, cutoff - trans_width, cutoff, 0.5*fs],
...                     [0, 1], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "High-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_01_00.png

此示例显示了通带为 2 kHz 至 5 kHz 的带通滤波器。转换宽度为 260 Hz,滤波器长度为 63,小于其他示例中的长度

>>> band = [2000, 5000]  # Desired pass band, Hz
>>> trans_width = 260    # Width of transition from pass to stop, Hz
>>> numtaps = 63         # Size of the FIR filter.
>>> edges = [0, band[0] - trans_width, band[0], band[1],
...          band[1] + trans_width, 0.5*fs]
>>> taps = signal.remez(numtaps, edges, [0, 1, 0], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Band-pass Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_02_00.png

低阶导致更高的波纹和不太陡峭的转换。

下一个示例显示了带阻滤波器。

>>> band = [6000, 8000]  # Desired stop band, Hz
>>> trans_width = 200    # Width of transition from pass to stop, Hz
>>> numtaps = 175        # Size of the FIR filter.
>>> edges = [0, band[0] - trans_width, band[0], band[1],
...          band[1] + trans_width, 0.5*fs]
>>> taps = signal.remez(numtaps, edges, [1, 0, 1], fs=fs)
>>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
>>> plot_response(w, h, "Band-stop Filter")
>>> plt.show()
../../_images/scipy-signal-remez-1_03_00.png