来自黄油过滤器和FFT的衍生结果不会随时间而变化

时间:2016-09-08 13:23:15

标签: python signals fft sensor

我是信号处理的新手,遇到了一种我不确定它是否正确的情况。请更正我,然后我会更新更多细节。

我的数据是here

我从我的手机上获得了一个加速度计信号(三星Galaxy Note 2,采样率$ \约99 Hz $)。我想分析频率从$ 0.3 Hz $到$ 5.0 Hz $

我的程序如下:

  1. 组合:假设传感器产生3个通道$ x $,$ y $,$ z $。组合是产生一个新的渠道$ v = \ sqrt {(x * x + y * y + z * z)} $
  2. 执行中值滤波器:顺利制作信号
  3. Butter-worth filter:我的截止频率是从$ 0.3 Hz $到$ 5.0 Hz $
  4. FFT

    下面的图片是我的120个时间点的分段,包含4个步骤:(可以在我video探索更多内容) a segment of 120 time-points

  5. 我观察到,当信号随时间变化时,步骤3和4的结果不会改变

    我的问题是,如果有什么我可以确保这个结果是否正确?提前致谢

    以下是我的代码用于应用过滤器

    FS = 99

    更新1 另一个下载数据https://1drv.ms/u/s!At6qHz_a5mXhgp1KcAYpvsiJeTXsmg

    的链接 代码router.get('/weeks/:week', auth, function (req, res, next) { Game.find({ 'Week': req.params.week }, function(err, games) { if (err) { return next(err); } res.json(games); }); });

    中的

    更新2 更新采样率

    更新3 再次将块大小增加到512,plotted数据。制作了结果without bandpass

    的视频

2 个答案:

答案 0 :(得分:1)

问题在于,每次在循环中处理新的数据块时,都会使用默认状态初始化过滤(如果所有先前的样本都为零,则对应于过滤器的状态)。结果,过滤器几乎没有时间在初始瞬态之后稳定(由从那些"之前的" 0到实际数据样本值的步骤引起),然后为下一个块再次做同样的事情。数据。

解决此问题的一种方法是在使用FFT处理数据块之前一次性过滤整个数据集:

_v = _accel['v'].values
_v = medfilt(_v, 7)
_v = butter_bandpass_filter1(_v, LOW_CUT, HIGH_CUT, FS, order=4)
for k in np.arange(1,len(_accel)//chunk):
     v = _v[chunk*k:chunk*(k+1)]
     v = 1 / chunk * absolute(rfft(v))
     plt.stem(freqs, v)

或者,您也可以跟踪过滤器状态(zi下方):

def butter_bandpass_filter(data, lowcut, highcut, fs, zi, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    if (zi == None):
        zi = lfilter_zi(b,a)
    y,zf = lfilter(b, a, data, zi=zi)
    return y,zf

zi = None
for k, g in _accel.groupby(np.arange(len(_accel)) // chunk):
    _v = g['v'].values
    _v = medfilt(_v, 7)
    _v,zi = butter_bandpass_filter(_v, LOW_CUT, HIGH_CUT, FS, zi, order=4)
    v = 1 / chunk * absolute(rfft(_v))
    plt.stem(freqs, v)

答案 1 :(得分:0)

我快速尝试这个问题,下面是我的代码段

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的窗口长度显然是不够的。< / p>