如何在 Python 中实现 FIR 高通滤波器?

How to implement a FIR high pass filter in Python?

首先,我在 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 的衰减,但我没有得到。我做错了什么?

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时的情节: