过滤连续数据,如何消除瞬态? [英] Filtering continuous data, how to get rid of transients?

查看:222
本文介绍了过滤连续数据,如何消除瞬态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个C#应用程序,该程序从Wii遥控器以〜100Hz的速率连续获取加速度计数据.到达时,此数据存储在一个列表中(每个轴一个列表). 我有一个计时器,它每秒钟触发一次((因此,当它触发列表包含约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之后.有限是100,是采样率,1是截止频率,30是滤波器阶数.

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

解决方案

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

问题是,每次触发计时器时都会创建一个新的筛选器,我通过创建一个全局筛选器对象并在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();

I'm writing a C# application which gets accelerometer data continuously at a rate of ~100Hz from a Wii remote. This data is stored in a list (one list for each axis) as it arrives. I have a Timer, which fires every one second,(so by the time it fires the list contains~100 elements), it then applies a low pass filter to the list (using the Signal Processing Math.NET Neodym library), and writes the data to a file, and clears all the list for the next batch of data.

Now the problem is, the outputted filter data has large swings at the start, this happens EACH time the filter is applied, so every one second later, I have some false values in the data, which render it completely useless.

How do I go about fixing this so that the filter is STILL applied only every one second, but the transients can be avoided. I have a suspicion this can be done using overlapping windows, but am not quite sure how?

Here is the code for my filter, this code executes each second:

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

In the arguments, right after the ImpulseResponse.Finite, 100 is the sampling rate, 1 is the cutoff frequency, and 30 is the filter order.

Here is screenshot showing what my I/O looks like. the input data is the first graph, and the second one shows the filter output:

解决方案

Ok, problem solved, leaving this here for anyone else facing similar trouble, as hotpaw2 mentioned, this could have been done by overlapping windows, but I found that I was simply not using the Filter in the Math.NET Neodym library the right way.

The problem was that a new filter was being created each time the timer was being fired, I resolved this by creating a global filter object, and calling it's ProcessSamples method each time within the Timer tick event.

So now , a filter object is created at the start of the program:

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

and only a method of the filter is called in the Timer Tick event:

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

这篇关于过滤连续数据,如何消除瞬态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆