【问题标题】:Filtering continuous data, how to get rid of transients?过滤连续数据,如何摆脱瞬态?
【发布时间】:2012-12-20 12:02:40
【问题描述】:

我正在编写一个 C# 应用程序,它以 ~100Hz 的速率从 Wii 遥控器连续获取加速度计数据。此数据在到达时存储在一个列表中(每个轴一个列表)。 我有一个计时器,它每隔一秒触发一次,(所以当它触发时列表包含~100 个元素),然后它对列表应用一个低通滤波器(使用信号处理 Math.NET Neodym 库),并写入将数据保存到文件中,并清除下一批数据的所有列表。

现在的问题是,输出的过滤器数据在开始时波动很大,每次应用过滤器时都会发生这种情况,所以每隔一秒,我的数据中就会出现一些错误值,这使得它完全没用。

我该如何解决这个问题,以便过滤器仍然仅每隔一秒应用一次,但可以避免瞬变。我怀疑这可以使用重叠窗口来完成,但不太确定如何?

这是我的过滤器的代码,此代码每秒执行一次:

 listXLow = MathNet.SignalProcessing.Filter.OnlineFilter.CreateLowpass(MathNet.SignalProcessing.Filter.ImpulseResponse.Finite, 100, 1, 30).ProcessSamples(listX.ToArray()).ToList();

在参数中,紧跟在 ImpulseResponse.Finite 之后,100 是采样率,1 是截止频率,30 是滤波器阶数。

这是显示我的 I/O 外观的屏幕截图。输入数据是第一个图,第二个显示过滤器输出:

【问题讨论】:

  • 听起来您使用过滤器 API 错误 - 给我们看一些代码!
  • 这是您从过滤器中获得的工件,从零开始,需要多个样本才能达到最终值。您需要一个移动平均样式的过滤器或更好的方法来维护过滤器的状态。所以你肯定不想每秒都调用 CreateLowpass()。
  • 那么重叠窗口方法(使一个数据的最后 30 个元素“块”另一个数据的前 30 个)是否有效?
  • 很好地包含了图表。确实使问题显而易见。

标签: c# filtering signal-processing


【解决方案1】:

FIR 滤波器具有瞬态阶的长度。对于 30 的瞬态长度,您可以保存前 100 个样本中的最后 30 个样本并将它们附加到当前数据中,然后在过滤后丢弃该瞬态(130 个过滤样本中的前 30 个)。

【讨论】:

    【解决方案2】:

    好的,问题解决了,把这个留给其他面临类似问题的人,正如 hotpaw2 所提到的,这可以通过重叠窗口来完成,但我发现我根本没有使用 Math.NET Neodym 库中的过滤器正确的方式。

    问题是每次触发计时器时都会创建一个新过滤器,我通过创建一个全局过滤器对象解决了这个问题,并在每次计时器滴答事件中调用它的 ProcessSamples 方法。

    现在,在程序开始时创建了一个过滤器对象:

      MathNet.SignalProcessing.Filter.OnlineFilter XlowFilter = MathNet.SignalProcessing.Filter.FIR.OnlineFirFilter.CreateLowpass(MathNet.SignalProcessing.Filter.ImpulseResponse.Finite, 100, 1.5, 30);
    

    并且在Timer Tick事件中只调用了过滤器的一个方法:

     listXLow = XlowFilter.ProcessSamples(listX.ToArray()).ToList();
    

    【讨论】:

      猜你喜欢
      • 2016-10-15
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多