过滤连续数据,如何摆脱瞬态?

时间:2013-01-06 16:56:13

标签: c# filtering signal-processing

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

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

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

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

 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外观的屏幕截图。输入数据是第一个图形,第二个图形显示过滤器输出: Graphs showing input and output data

2 个答案:

答案 0 :(得分:4)

FIR滤波器具有瞬态长度的顺序。对于30的瞬态长度,您可以保存前100个样本中的最后30个样本,并将它们预先挂起到当前数据,然后在过滤掉掉那个瞬态(130个过滤样本中的前30个)。

答案 1 :(得分:4)

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

问题是每次启动计时器时都会创建一个新的过滤器,我通过创建一个全局过滤器对象来解决这个问题,并且每次在Timer tick事件中调用它的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();