# iPhone - Accelerometer Peak Detection

Hi All,

I am developing an app for iPhone using OpenFrameworks.
Basically, the app tries to do gait analysis, using the accelerometer.
For this, I need to detect the peaks in the accelerometer readings. Has anyone worked on something similar to this?
Or any other pointers would help a lot…

cheers
-karan

hi karan

this is a filtering problem, and the kind of math you need to deal with it is usually in the DSP realm.

a super simple version simply remembers what the previous value was, and whether that value was rising or falling relative to the value before it. then when the new value comes in, you check to see if you’re still rising or still falling. ie, you check if the new direction is the same as the old direction. if the direction has changed, you’ve just hit a peak, or a trough:

frame n-2: input 30, prev 25: direction 1 (rising)
frame n-1: input 35, prev 30: direction 1 (rising)
frame n : input 30, prev 35: direction 0 (falling) --> frame n-1 was a peak

the tricky part with this is that the input from the accelerometer is jittery, so you need to smooth it out to smooth out the jitters. this is technically called low-pass filtering, and it has a problem which is that if you filter too much, you can smooth out some genuine peaks.

i suspect that to do decent gait analysis you’re going to have to call in some extra knowledge about walking, for example that a step is usually the same duration over time (steady rhythm) so you can predict when the next peak should be based on previous peak times, and perhaps use this knowledge to shift your low pass filter cutoff frequency (smoothing amount) over time; and also that steps are usually the same strength, so you can predict at around what kind of accelerometer reading you should get with a foot impact.

have fun
d

hey karan, ofxAccelerometer already does low-pass filtering which you can adjust with:

ofxAccelerometer.setForceSmoothing(float forceSmoothing);
(there is also setOrientationSmoothing cos I do different smoothing for orientation detection).

then ofxAccelerometer.getForce() returns the filtered results.
alternatively you can call ofxAccelerometer.getRawAcceleration() to get the raw data if you want to do your own filtering on the raw data

how ‘realtime’ does the detection need to be? The lowpass filtering done in ofxAccelerometer is done in realtime and is very basic (weighted average with previous value). For best results you could do a gaussian blur over the data taking past and future values into consideration with say anywhere between 5-30 samples, (at 30fps, that would give a half a second delay), but would be a much better filter.

Have been using kalman filtering in open cv lately, perhaps is a little overkill for the iphone but i think someone compiled the library recently.

you will need to adjust the parameters in the constructor to change the behaviour of the kalman filter.

the use is really easy, for each read of the accelerometer call kalman.correct(value) and use the return of that function instead of the real value.

ofxCvKalman.zip

Thanks everyone for their replies.

Yes, this turned out to be a filtering problem indeed.

I am taking a sample size of 50 values, and finding the maximum amongst them. As a naive implementation this works. I shall try the Low Pass Filtering and the Kalman filtering and see the difference in results.
Thanks again for all your help…

cheers

Hi! I’m new on openframeworks.cc and I found this thread googling for kalman filtering the iphone accelerometer raw data.

Sorry to resume the thread but I am interested in the kalman filter, or it’s better to say that I THINK to be interested

The question is for everyone, but especially for arturo who posted the code for kalman filtering (thank you!).

All I want to understand is if Kalman filtering can solve the problem I’m going to explain.

I need to use (x,y,z) acceleration values related only to the movement of the Phone. Just to be clear, think an environment like a car. The iPhone accelerometer is very sensitive. If I log acceleration values with a frequency of 100Hz, there are so many values related to noise, car vibrations and other acceleration vectors which are not directed like the iPhone motion (for example, dampers oscillations cause acceleration vectors directed along z-axis).

In other words, I need to filter accelerations detection in a way capable to isolate accelerations whose direction is the same (within a certain offset) of the motion direction.

Note that I am using high pass filtered values to remove gravity components.

Obviously, I could fix the iphone position so that its y axis overlaps the movement direction (in the previous car environment, this means fixing the iphone y axis parallel to the front direction). The problem is that I need to allow iphone’s relative moments. I can’t fix the iphone position.

First of all I analyzed values produced by noise and oscillations, and I figured out that their magnitude is often very higher than normal car accelerations. Filtering the magnitude is a good idea to ease the problem but it’s not a solution: on one side many unwanted noise accelerations are not filtered because their magnitude falls within the range, on the other side many wanted motion accelerations are filtered because they falls outside the range.

On the iPhone 3GS I can use the magnetometer to measure degrees heading relative to magnetic North. I could use this to find the direction of motion but the problem is still there: magneticHeading value is always measured relative to the top of the device. So the iPhone should be fixed along the front direction.

Finally the question is: will kalman filtering help to discard acceleration vectors which are not directed along the real motion direction? If yes, which property should you filter? Magnitude?

Thank you very much. I need this so much to continue a university project.

Donn.

Hi Donn

i haven’t really used the kalman filter with the iphone accelerometer (or with any accelerometer) so not really sure if it’s what you need. but from what i’ve read about it, it seems it can help with your problem.

the tipical example i’ve found when reading about kalman filtering with opencv is this:

http://dasl.mem.drexel.edu/~noahKuntz/o-…-l#Step%202

where they generate a circular path and add some noise to it just by adding some random. after some time the kalman filter is able to deduce the original circular path.

what i’ve done when using the kalman filter in my case to filter a 2d motion is to use 2 filters one for the x coordinate and one for the y. although with opencv implementation you can use one filter for several components, i tried it but never got it to work properly.

also i read in the opencv book (there’s a really good explanation of kalman, if you want to take a look) that noise with some periodic frequency is not filtered properly so perhaps some of the components of your noise is not going to be filtered correctly by a kalman filter.

also if you do any progress with this please post, i’m pretty sure i’ve used it in a really naive way, and although for me it was enough, i think it’s much more powerful than that.

arturo