开发者

How to filter accelerometer data from noise

开发者 https://www.devze.com 2023-01-17 10:22 出处:网络
Att开发者_StackOverflow社区ached is a plot of accelerometer data with 3 axis. The sudden bumps in the plot are the noise. I would like to get rid of them. So what filter should be used in this case

How to filter accelerometer data from noise

Att开发者_StackOverflow社区ached is a plot of accelerometer data with 3 axis. The sudden bumps in the plot are the noise. I would like to get rid of them. So what filter should be used in this case ? If it is possible provide some pseudo code for it and explanation.


For measurement data where you can make an approximate model of what's physically going on, or what's physically likely, I'd suggest a Kalman filter. It's somewhat more complex than the other methods, but potentially gives cleaner output and/or better responsiveness.


It looks like you just want a low pass filter.


Looking at the data, you do not want any peeks that change the value by a certain amount (around 200, let us call this max_y_delta) in a certain time (5-15 perhaps, max_x_delta).

So as I'm not sure which structure your data has, I'll just assume it's 3 arrays data_array of floating point values that have a data point at every integer position. The solution I present is meant to be as simple as possible and you should try different values of max_x/y_delta to get good results. Even with the right values I'm sure there are much better solutions, but perhaps this one is good enough for you as a start.

max_x_delta = 10
max_y_delta = 200
for each of the 3 arrays
  for x = -1000...1000
    points_above_delta = 0
    average_value = 0
    for deltax = -max_x_delta/2...max_x_delta/2
      average_value += data_array[deltax]
      if abs(data_array[deltax] - data_array[x]) > max_y_delta
        points_above_delta++
      endif
    end for deltax
    average_value = average_value / max_x_delta
    if points_above_delta > max_x_delta/4
      for deltax = -max_x_delta/2...max_x_delta/2
        data_array[deltax] = average_value
      end for deltax
    end if  
  end for x

Note that this code has two downsides you might not want:

  • The detection is very simple, there are also some peeks in your data that are meant to be there, so you might lose some of those.
  • After detecting a peak, every value in the max_x_delta region around the peak is set to the average value in that region which will give you a straight line.


Here is how I've done it http://levonp.blogspot.com/2010/10/how-to-filter-accelerometer-data-from.html


Try median filter: http://en.wikipedia.org/wiki/Median_filter, it can remove peaks, but not edges


Median filters are used to remove salt and pepper noise in two dimensional data. In this one dimensional data that you have the peaks you want to remove are high intensity points analogous to salt and pepper in 2D. I would recommend a median filter as well, it will help get rid of those spikes and change very little else. The only downside is that it is a nonlinear filter. It should be efficient to implement as long as you carefully update your neighborhoods.


You can have a good result with this code:

float smoothing=1.5F;
float Current_val_x= sensorEvent.values[0];
float Current_val_y= sensorEvent.values[1];
float Current_val_z= sensorEvent.values[2];      //you can change with your input
              
x_without_noise += (Current_val_x - x_without_noise) / smoothing;
sensorEvent.values[0] = x_without_noise;

y_without_noise += (Current_val_y - y_without_noise) / smoothing;
sensorEvent.values[1] = y_without_noise;

z_without_noise += (Current_val_z - z_without_noise) / smoothing;
sensorEvent.values[2] = z_without_noise;

System.out.print(x_without_noise);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号