使用 `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:
谷歌搜索 'low pass filter critical frequency' 得到很多关于 截止频率 和 角频率 的结果,这确实与我最初对 'cutoff point'.
的想法相似
我也找到了一些根据滤波器的'transfer function'计算截止频率的公式,但显然低通滤波器有很多种,每一种都可能有不同的传递函数。
这个related question讲的是用来计算Wn
的奈奎斯特频率。我知道奈奎斯特采样率是多少,这显然是不同的。维基百科文章完全避免谈论什么是概念上的奈奎斯特频率。
我的问题:
显然,除了我正在学习的内容外,我对信号处理几乎一无所知。请像我 5 岁一样解释:
signal.butter()
的前两个参数是什么
- 改变这些参数如何在功能上改变过滤器?
- 如何计算它们?
临界频率参数(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.sosfreqz
和 pyplot
:
绘制它的频率响应
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 开始增加,直到获得所需的衰减。
上下文:
我正在尝试创建一个低通滤波器来截除声音文件中 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:
谷歌搜索 'low pass filter critical frequency' 得到很多关于 截止频率 和 角频率 的结果,这确实与我最初对 'cutoff point'.
的想法相似我也找到了一些根据滤波器的'transfer function'计算截止频率的公式,但显然低通滤波器有很多种,每一种都可能有不同的传递函数。
这个related question讲的是用来计算
Wn
的奈奎斯特频率。我知道奈奎斯特采样率是多少,这显然是不同的。维基百科文章完全避免谈论什么是概念上的奈奎斯特频率。
我的问题:
显然,除了我正在学习的内容外,我对信号处理几乎一无所知。请像我 5 岁一样解释:
signal.butter()
的前两个参数是什么
- 改变这些参数如何在功能上改变过滤器?
- 如何计算它们?
临界频率参数(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.sosfreqz
和 pyplot
:
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 开始增加,直到获得所需的衰减。