【问题标题】:How to implement a FIR high pass filter in Python?如何在 Python 中实现 FIR 高通滤波器?
【发布时间】:2019-12-08 23:55:44
【问题描述】:

首先,我在 Stack Exchange 中提出了这个问题,我得到的只是与概念相关的答案,而不是面向实现的。所以,我的问题是我正在尝试创建高通滤波器并使用 Python 实现。

from numpy import cos, sin, pi, absolute, arange
from scipy.signal import kaiserord, lfilter, firwin, freqz, firwin2
from pylab import figure, clf, plot, xlabel, ylabel, xlim, ylim, title, grid, axes, show

# Nyquist rate.
nyq_rate = 48000 / 2
# Width of the roll-off region.
width = 500 / nyq_rate
# Attenuation in the stop band.
ripple_db = 12.0
num_of_taps, beta = kaiserord(ripple_db, width)
# Cut-off frequency.
cutoff_hz = 5000.0
# Estimate the filter coefficients.
if num_of_taps % 2 == 0:
    num_of_taps = num_of_taps + 1
taps = firwin(num_of_taps, cutoff_hz/nyq_rate, window=('kaiser', beta), pass_zero='highpass')
w, h = freqz(taps, worN=1024)
plot((w/pi)*nyq_rate, absolute(h), linewidth=2)
xlabel('Frequency (Hz)')
ylabel('Gain')
title('Frequency Response')
ylim(-0.05, 1.05)
grid(True)
show()

通过查看频率响应,我没有得到预期的阻带衰减。我想要 12dB 的衰减,但我没有得到。我做错了什么?

【问题讨论】:

    标签: scipy filtering signal-processing audio-processing


    【解决方案1】:

    firwinpass_zero 参数更改为False。该参数必须是布尔值(即 True 或 False)。通过将其设置为 False,您将滤波器的行为选择为高通滤波器(即滤波器通过信号的 0 频率)。

    这是您的脚本的一个变体。我添加了水平虚线,显示阻带(青色)中所需的衰减和通带(红色)中所需的纹波边界,由您选择的ripple_db 确定。我还绘制了垂直虚线(绿色)来表示从阻带到通带的过渡区域。

    import numpy as np
    from scipy.signal import kaiserord, lfilter, firwin, freqz, firwin2
    import matplotlib.pyplot as plt
    
    # Nyquist rate.
    nyq_rate = 48000 / 2
    
    # Width of the roll-off region.
    width = 500 / nyq_rate
    
    # Attenuation in the stop band.
    ripple_db = 12.0
    
    num_of_taps, beta = kaiserord(ripple_db, width)
    if num_of_taps % 2 == 0:
        num_of_taps = num_of_taps + 1
    
    # Cut-off frequency.
    cutoff_hz = 5000.0
    
    # Estimate the filter coefficients.
    taps = firwin(num_of_taps, cutoff_hz/nyq_rate, window=('kaiser', beta), pass_zero=False)
    
    w, h = freqz(taps, worN=4000)
    
    plt.plot((w/np.pi)*nyq_rate, 20*np.log10(np.abs(h)), linewidth=2)
    
    plt.axvline(cutoff_hz + width*nyq_rate, linestyle='--', linewidth=1, color='g')
    plt.axvline(cutoff_hz - width*nyq_rate, linestyle='--', linewidth=1, color='g')
    plt.axhline(-ripple_db, linestyle='--', linewidth=1, color='c')
    delta = 10**(-ripple_db/20)
    plt.axhline(20*np.log10(1 + delta), linestyle='--', linewidth=1, color='r')
    plt.axhline(20*np.log10(1 - delta), linestyle='--', linewidth=1, color='r')
    
    plt.xlabel('Frequency (Hz)')
    plt.ylabel('Gain (dB)')
    plt.title('Frequency Response')
    plt.ylim(-40, 5)
    plt.grid(True)
    plt.show()
    

    这是它生成的情节。 如果您仔细观察,您会发现频率响应接近定义滤波器所需行为的区域的拐角。

    这是ripple_db 更改为 21 时的情节:

    【讨论】:

    • 阻带中的衰减看起来超过12dB?
    • @Dennis.M,您必须考虑从阻带到通带的过渡区域的宽度。请参阅我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    相关资源
    最近更新 更多