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);
精彩评论