在SciPy中创建低通滤波器-了解方法和单位

我试图用python过滤嘈杂的心率信号。因为心率不应该超过每分钟220次,所以我想过滤掉所有超过220次/分钟的噪音。我将220/分钟转换为3.6666赫兹,然后将该赫兹转换为拉德/秒,得到23.0383461拉德/秒

采集数据的芯片的采样频率是30Hz,所以我将其转换为rad/s,得到188.495559 rad/s

在网上查了一些资料后,我找到了一些带通滤波器的函数,我想把它做成低通滤波器。这是带通代码的链接,因此我将其转换为:

来自scipy.signal导入黄油,lfilter的


从scipy.signal导入频率
def黄油_低通(截止,fs,顺序=5):
nyq=0.5*fs
正常截止=截止/nyq
b、 a=黄油(订单,正常切断,b类型为低,模拟为真)
返回b,a
低通滤波器(数据、截止、fs、顺序=4):
b、 a=低通(截止、fs、顺序=顺序)
y=L过滤器(b、a、数据)
返回y
截止频率=23.1#以rad/s为单位的截止频率
fs=188.495559#采样频率,单位为rad/s
阶数=20#滤波器阶数
#打印标签\u data.ps1\u dxdt2
y=低通滤波器(数据、截止、fs、顺序)
plt.绘图(y)

我对此感到非常困惑,因为我非常确定butter函数采用了rad/s的截止频率和采样频率,但我似乎得到了一个奇怪的输出。实际上是赫兹吗

第二,这两条线的目的是什么:

nyq=0.5*fs
正常截止=截止/nyq

我知道这是关于标准化的,但我认为奈奎斯特是采样频率的2倍,而不是一半。你为什么要用奈奎斯特作为标准化器

有人能解释一下如何用这些函数创建过滤器吗

我使用以下方法绘制了过滤器:

w,h=信号频率(b,a)
平面图(w,20*np.log10(abs(h)))
plt.xscale('log')
plt.title(‘巴特沃斯滤波器频率响应’)
plt.xlabel('频率[弧度/秒])
plt.ylabel('振幅[dB]”)
利润率(0,0.1)
plt.grid(其中的轴为'both',轴为'both')
plt.axvline(100,颜色为绿色)#截止频率
plt.show()

得到的结果显然不能在23 rad/s时切断:

几点意见:

  • 奈奎斯特频率是采样率的一半
  • 您使用的是定期采样的数据,因此您需要的是数字滤波器,而不是模拟滤波器。这意味着您不应该在调用butter时使用analog=True,而应该使用scipy.signal.freqz(而不是freqs)来生成频率响应
  • 这些简短实用功能的一个目标是允许您保留所有以Hz表示的频率。你不应该转换成rad/sec。只要你用一致的单位来表达你的频率,效用函数中的缩放就可以为你实现标准化

这是我修改过的脚本,后面是它生成的情节

将numpy导入为np
来自scipy.signal进口黄油、lfilter、FREKZ
将matplotlib.pyplot作为plt导入
def黄油_低通(截止,fs,顺序=5):
nyq=0.5*fs
正常截止值=截止值/nyq
b、 a=黄油(订单,正常切断,b类型='low',模拟=False)
返回b,a
低通滤波器(数据、截止、fs、顺序=5):
b、 a=低通(截止、fs、顺序=顺序)
y=L过滤器(b、a、数据)
返回y
#过滤要求。
订单=6
fs=30.0#采样率,Hz
截止=3.667#滤波器的期望截止频率,Hz
#获得滤波器系数,以便检查其频率响应。
b、 a=低通(截止、fs、顺序)
#绘制频率响应图。
w、 h=频率Z(b,a,磨损=8000)
plt.子地块(2,1,1)
平面图(0.5*fs*w/np.pi,np.abs(h),‘b’)
平面图(截止点,0.5*np.sqrt(2),‘ko’)
plt.axvline(截止,颜色为'k')
plt.xlim(0,0.5*fs)
plt.标题(“低通滤波器频率响应”)
plt.xlabel(“频率[Hz]”)
plt.grid()
#演示过滤器的使用。
#首先制作一些要过滤的数据。
T=5.0秒
n=int(T*fs)#样本总数
t=np.linspace(0,t,n,endpoint=False)
#“嘈杂”的数据。我们想从中恢复1.2赫兹的信号。
数据=np.sin(1.2*2*np.pi*t)+1.5*np.cos(9*2*np.pi*t)+0.5*np.sin(12.0*2*np.pi*t)
#过滤数据,并绘制原始信号和过滤后的信号。
y=低通滤波器(数据、截止、fs、顺序)
plt.子地块(2,1,2)
plt.plot(t,数据,'b-',label='data')
plt.plot(t,y,'g-',线宽=2,label='filtereddata')
plt.xlabel('时间[秒])
plt.grid()
plt.legend()
plt子批次调整(hspace=0.35)
plt.show()

发表评论