在 Python 中应用低通巴特沃斯滤波器

信息处理 fft 过滤器 Python 低通滤波器
2021-12-23 14:58:59

我想对我的数据使用低通巴特沃斯滤波器,但在应用滤波器时我没有得到预期的信号。这是虚拟代码:

信号 A:

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
a = np.linspace(0,1,1000)
signala = np.sin(2*np.pi*100*a) # with frequency of 100
plt.plot(signala)

信号 B:

signalb = np.sin(2*np.pi*20*a) # frequency 20
plt.plot(signalb)

现在让我们结合信号 A 和 B 来获得信号 C

signalc = signala + signalb
plt.plot(signalc)

结果信号 C 看起来像这样

在此处输入图像描述

现在让我们应用过滤器:

b, a = signal.butter(5, 30, 'low', analog = True) #first parameter is signal order and the second one refers to frequenc limit. I set limit 30 so that I can see only below 30 frequency signal component
output = signal.filtfilt(b, a, signalc)
plt.plot(output)

在应用上述黄油过滤器时,我得到一个空图

在此处输入图像描述

我不明白我在哪里做错了?任何帮助将不胜感激。

3个回答

您不应该使用analog过滤器 - 请改用数字过滤器。您希望在 Z 域而不是 S 域中定义过滤器。此外,您应该定义具有已知采样频率的时间向量以避免任何混淆。

数字滤波器的设计要求将截止频率归一化fs/2

这是一个工作示例:

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

fs = 1000  # Sampling frequency
# Generate the time vector properly
t = np.arange(1000) / fs
signala = np.sin(2*np.pi*100*t) # with frequency of 100
plt.plot(t, signala, label='a')

signalb = np.sin(2*np.pi*20*t) # frequency 20
plt.plot(t, signalb, label='b')

signalc = signala + signalb
plt.plot(t, signalc, label='c')

fc = 30  # Cut-off frequency of the filter
w = fc / (fs / 2) # Normalize the frequency
b, a = signal.butter(5, w, 'low')
output = signal.filtfilt(b, a, signalc)
plt.plot(t, output, label='filtered')
plt.legend()
plt.show()

在此处输入图像描述

如 jojek 所述,需要通过 Nyquist 频率 ( f = f / (fs/2) ) 对频率值进行归一化,以及 signal.butter 函数中的“analog = False”选项。IE

b, a = signal.butter(5, 30/(fs/2), 'low', analog = False) 

以下是我在 Python 中应用低通巴特沃斯滤波器的方法,但形成第一个信号,然后提供截止频率和阶数(阶数在某种程度上类似于截止“锐度”):

def butter_lowpass(cutoff, nyq_freq, order=4):
    normal_cutoff = float(cutoff) / nyq_freq
    b, a = signal.butter(order, normal_cutoff, btype='lowpass')
    return b, a

def butter_lowpass_filter(data, cutoff_freq, nyq_freq, order=4):
    # Source: https://github.com/guillaume-chevalier/filtering-stft-and-laplace-transform
    b, a = butter_lowpass(cutoff_freq, nyq_freq, order=order)
    y = signal.filtfilt(b, a, data)
    return y

来源:https ://github.com/guillaume-chevalier/filtering-stft-and-laplace-transform