我在信号处理领域还很陌生,遇到了我不确定它是否正确的情况。请更正我,然后我将更新更多详细信息。
我的数据是here
我获得了从手机上获取的加速度计信号(三星Galaxy Note 2,采样率$ \大约99 Hz $)。我想分析从$ 0.3 Hz $到$ 5.0 Hz $的频率
我的步骤如下:
组合:假设传感器产生3个通道$ x $,$ y $,$ z $。组合将产生一个新通道$ v = \ sqrt {(x * x + y * y + z * z)} $
执行中值滤波:使信号平滑
黄油型滤波器:我的截止频率是从0.3 Hz $到5.0 Hz $
快速傅立叶变换
下图是我演示的120个时间点的片段,分为4个步骤:(可以在video上进行更多探索)
我观察到步骤3和步骤4的结果没有变化,但是信号随时间变化
我的问题是,是否可以确保此结果正确无误?提前致谢
下面是我的代码用于应用过滤器
from __future__ import division
import numpy as np
from numpy.fft import rfft, rfftfreq
from numpy import absolute
import matplotlib.pyplot as plt
from scipy.signal import medfilt, hilbert
import pandas as pd
chunk = 120
LOW_CUT = 0.3
HIGH_CUT = 5.0
FS = 99
freqs = rfftfreq(chunk, 1 / FS)
_accel = pd.read_csv('data.csv')
for k, g in _accel.groupby(np.arange(len(_accel)) // chunk):
_v = g['v'].values
_v = medfilt(_v, 7)
_v = butter_bandpass_filter(_v, LOW_CUT, HIGH_CUT, FS, order=4)
v = 1 / chunk * absolute(rfft(_v))
plt.stem(freqs, v)
更新1个其他链接以下载数据https://1drv.ms/u/s!At6qHz_a5mXhgp1KcAYpvsiJeTXsmg
用代码
FS = 99
更新2个更新的采样率再次将3增加的块大小更新为512,plotted数据。制作了一个结果为without bandpass的视频
最佳答案
我快速尝试解决该问题,以下是我的摘录
data = _accel['v'].tolist()
Fs = 99
# remove the DC part, to help the plotting later
data = data - np.mean(data)
# Perform FFT for real data, on the whole 6000 samples,
# using 4096 discrete frequencies, which is dense enough to capture
# the frequency information within 0.3-5 Hz.
fdata = rfft(data,4096)
# the frequencies we are looking at in the FFT
freqs = map(lambda x: float(x)*Fs/4096, range(0,4097))
# Plot
plt.plot(freqs[0:2049],fdata)
plt.xlabel('Frequency')
plt.show()
生成的图确实包含您感兴趣的波段中的信息。
Plot of frequency magnitude
我猜你的问题在于选择的块太小。
频域中的分辨率为Fs / N,其中N是执行FFT的点数(通常是时域中信号矢量的长度)。因此,如果您想捕获0.3-5Hz范围内的信息,我假设您需要约0.2Hz的分辨率,这意味着N应该至少为500。您为窗口长度选择120显然是不够的。
关于python - Butter滤波器和FFT的推导结果不会随时间变化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39392173/