如何使用Scipy.signal.butter实现带通Butterworth滤波器

时间:2012-08-23 14:09:52

标签: python scipy signal-processing digital-filter

更新:

我找到了一个基于这个问题的Scipy Recipe!因此,对于任何有兴趣的人,请直接访问:Contents » Signal processing » Butterworth Bandpass


我很难实现最初为一维numpy数组(时间序列)实现Butterworth带通滤波器的简单任务。

我必须包括的参数是sample_rate,截止频率IN HERTZ和可能的顺序(其他参数,如衰减,固有频率等对我来说更加模糊,因此任何“默认”值都可以)。

我现在拥有的是这个,它似乎可以作为一个高通滤波器,但我不确定我是否做得对:

def butter_highpass(interval, sampling_rate, cutoff, order=5):
    nyq = sampling_rate * 0.5

    stopfreq = float(cutoff)
    cornerfreq = 0.4 * stopfreq  # (?)

    ws = cornerfreq/nyq
    wp = stopfreq/nyq

    # for bandpass:
    # wp = [0.2, 0.5], ws = [0.1, 0.6]

    N, wn = scipy.signal.buttord(wp, ws, 3, 16)   # (?)

    # for hardcoded order:
    # N = order

    b, a = scipy.signal.butter(N, wn, btype='high')   # should 'high' be here for bandpass?
    sf = scipy.signal.lfilter(b, a, interval)
    return sf

enter image description here

文档和示例令人困惑和模糊,但我希望实现标记为“for bandpass”的表述中的表单。评论中的问号显示我只是在不了解正在发生的事情的情况下复制粘贴了一些示例。

我不是电气工程师或科学家,只是一名医疗设备设计师需要对EMG信号执行一些相当简单的带通滤波。

3 个答案:

答案 0 :(得分:91)

您可以跳过使用按钮,而只是选择过滤器的订单,看看它是否符合您的过滤条件。要为带通滤波器生成滤波器系数,请给出butter()滤波器阶数,截止频率Wn=[low, high](表示为奈奎斯特频率的分数,即采样频率的一半)和频带类型{{1 }}

这是一个脚本,它定义了一些用于处理Butterworth带通滤波器的便利功能。当作为脚本运行时,它会生成两个图。一个显示了相同采样率和截止频率的几个滤波器阶数的频率响应。另一个图表演示了过滤器(顺序= 6)对样本时间序列的影响。

btype="band"

以下是此脚本生成的图表:

Frequency response for several filter orders

enter image description here

答案 1 :(得分:18)

accepted answer中的过滤器设计方法是正确的,但它有一个缺陷。使用b,a设计的SciPy带通滤波器为unstable,可能会在{strong> erroneous filters 处产生higher filter orders

相反,使用过滤器设计的sos(二阶段)输出。

from scipy.signal import butter, sosfilt, sosfreqz

def butter_bandpass(lowcut, highcut, fs, order=5):
        nyq = 0.5 * fs
        low = lowcut / nyq
        high = highcut / nyq
        sos = butter(order, [low, high], analog=False, btype='band', output='sos')
        return sos

def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
        sos = butter_bandpass(lowcut, highcut, fs, order=order)
        y = sosfilt(sos, data)
        return y

此外,您可以通过更改

来绘制频率响应
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
w, h = freqz(b, a, worN=2000)

sos = butter_bandpass(lowcut, highcut, fs, order=order)
w, h = sosfreqz(sos, worN=2000)

答案 2 :(得分:4)

对于带通滤波器,ws是包含下角和上角频率的元组。这些代表数字频率,滤波器响应比通带小3 dB。

wp是一个包含阻带数字频率的元组。它们代表最大衰减开始的位置。

gpass是通带中的最大值,以dB为单位,而gstop是阻带中的值。

例如,假设您想设计一个滤波器,采样率为8000个样本/秒,转角频率为300和3100 Hz。奈奎斯特频率是采样率除以2,或者在本例中为4000 Hz。等效数字频率为1.0。两个转角频率为300/4000和3100/4000。

现在假设您希望阻带从转角频率下降30 dB +/- 100 Hz。因此,您的阻带将从200和3200 Hz开始,导致数字频率为200/4000和3200/4000。

要创建过滤器,请将按钮称为

fs = 8000.0
fso2 = fs/2
N,wn = scipy.signal.buttord(ws=[300/fso2,3100/fso2], wp=[200/fs02,3200/fs02],
   gpass=0.0, gstop=30.0)

结果滤波器的长度取决于阻带的深度和响应曲线的陡度,它由转角频率和阻带频率之差决定。