使用 `scipy.signal.butter()` 创建低通滤波器时,'order' 和 'critical frequency' 是什么

What are 'order' and 'critical frequency' when creating a low pass filter using `scipy.signal.butter()`

上下文:

我正在尝试创建一个低通滤波器来截除声音文件中 10khz 以上的频率。

import librosa
import scipy.signal as sig
import numpy as np
import matplotlib.pyplot as plt

filename = librosa.example('nutcracker')
y, sr = librosa.load(filename)

# modeled after example in scipy.signal docs:
sos = sig.butter(10, 11, btype='lowpass', analog=False, output='sos')
filtered = sig.sosfilt(sos, y)

现在,我知道低通滤波器的作用,但不知道它是如何工作的,也不知道它背后的数学原理。所以 scipy.signal.butter(N, Wn, ... ) 的前两个参数对我来说有点神秘:

N : int

The order of the filter.

Wn : array_like

The critical frequency or frequencies. For lowpass and highpass filters, Wn is a scalar; for bandpass and bandstop filters, Wn is a length-2 sequence.

起初我以为 Wn,被描述为“临界频率”是滤波器的 cutoff/threshold。但是,将其设置为超过 1 会导致错误,告诉我该值必须介于 0 和 1 之间。

这是我的 work/research:

  1. 谷歌搜索 'low pass filter critical frequency' 得到很多关于 截止频率 角频率 的结果,这确实与我最初对 'cutoff point'.

    的想法相似
  2. 我也找到了一些根据滤波器的'transfer function'计算截止频率的公式,但显然低通滤波器有很多种,每一种都可能有不同的传递函数。

  3. 这个related question讲的是用来计算Wn的奈奎斯特频率。我知道奈奎斯特采样率是多少,这显然是不同的。维基百科文章完全避免谈论什么是概念上的奈奎斯特频率。

我的问题:

显然,除了我正在学习的内容外,我对信号处理几乎一无所知。请像我 5 岁一样解释:

  1. signal.butter()
  2. 的前两个参数是什么
  3. 改变这些参数如何在功能上改变过滤器?
  4. 如何计算它们?

临界频率参数(Wn)

您认为 Wn 对应截止频率的印象是正确的。但是单位很重要,如文档中所示:

For digital filters, Wn are in the same units as fs. By default, fs is 2 half-cycles/sample, so these are normalized from 0 to 1, where 1 is the Nyquist frequency. (Wn is thus in half-cycles / sample.)

因此,处理指定 Wn 的最简单方法是同时指定采样率 fs。在您的情况下,您可以从 librosa.load.

返回的变量 sr 中获得此采样率
sos = sig.butter(10, 11, fs=sr, btype='lowpass', analog=False, output='sos')

要验证您的滤波器,您可以使用 scipy.signal.sosfreqzpyplot:

绘制它的频率响应
import scipy.signal as sig
import matplotlib.pyplot as plt

sos = sig.butter(10, 11, fs=sr, btype='lowpass', analog=False, output='sos')    
w,H = sig.sosfreqz(sos, fs=sr)
plt.plot(w, 20*np.log10(np.maximum(1e-10, np.abs(H))))

为了更好地可视化参数 Wn 的效果,我绘制了 Wn 的各种值(对于任意 sr=8000)的响应:

过滤顺序参数(N)

此参数控制过滤器的复杂性。更复杂的滤波器可以具有更尖锐的频率响应,这在尝试分离彼此接近的频率时非常有用。 另一方面,它也需要更多的处理能力(在软件中实现时需要更多的 CPU 周期,或者在硬件中实现时需要更大的电路)。

再次可视化参数 N 的效果,我绘制了 N 的各种值(对于任意 sr=8000)的响应:

如何计算这些参数

既然你提到你想要你的滤波器截断 10kHz 以上的频率,你应该设置 Wn=10000。如果您的采样率 sr 至少为 20kHz,这将起作用。 就 N 而言,您要选择满足您要求的最小值。如果你知道你想要达到多少,计算所需过滤器阶数的便捷函数是 scipy.signal.buttord。例如,如果您希望滤波器在 10kHz 以下衰减不超过 3dB,在 12kHz 以上衰减至少 60dB,您可以使用:

N,Wn = sig.buttord(10000, 12000, gpass=3, gstop=60, fs=sr)

否则您也可以通过实验获得符合您要求的过滤顺序。您可以从 1 开始增加,直到获得所需的衰减。