Search code examples
pythonscipyfrequencylowpass-filter

Python low-pass filter on list of Time/Position


Let me first explain my goal and my problem. I have an object moving in circle inside of a bocal (a mice to be precise), and I need to know how many rotation it does in one minute. The movement isn't a perfect circle, and can be chaotic. It can stopped for several seconds, and start again moving.

But what I know, is that I have between 3 and 20 rotation per minute => Low frequency (between 0.05 Hz and 0.33 Hz).

I'm filming this object with a 30 fps camera during 30 minutes. With Python and OpenCV, I manage to extract the (X,Y) coordinates. Since 30 fps is a bit high for the frequency I'm looking for, I selected one frame on 15 in order to have a sampling frequency of 2 Hz.

The first problem, is that sometimes, I'm missing a point because OpenCV couldn't find the object. This is a problem I can't solve, since the point I'm tracking with an HSV color mask is sometimes hidden.

In fact, the data I have to filter are :

  • Frame, a list of the frame number. At the indice [i], I have the frame number corresponding to the X[i] and Y[i]
  • X, a list of the X coordinates
  • Y, a list of the Y coordinates

For instance, I have this kind of list :

  • Frame = [15, 90, 165, 180, 195, 210, 225, 300, 315, 375 ,405]
  • X = [395, 487, 389, 389, 358, 382, 373, 389, 397, 403, 446]
  • Y = [167, 211, 166, 173, 180, 185, 191, 223, 241, 231, 238]

This is the king of movement I get, as you can see, I need to filter the high frequency.

And now my problem : Even if I have some basics in filtering and coding, I don't know how to do it, and which library to use. I've read that scipy should have all the required function, but I don't know which one to use, and how.

I'm not sure, but I think I should do something like this :

  • Fourrier transformation
  • lowpass filtering
  • Inverse transformation

Could you please tell me if I'm right, and point me in the right direction for the coding part ?

Thanks for the help,

Mathieu


Solution

  • Before you delve into Fourier transforms, you could just apply a first or second order low-pass filter. You could first linearly interpolate your data, so that you can have a constant 2Hz frequency. Then you can apply a first order low pass filter to the data points.

    y_k = a * x_k + (1-a) * y_km1, a in [0,1]
    

    x_k are your observations, and y_k is your filtered estimate.

    Then if this first prototype yields some useful results, you might be able to use some physical model to get a better estimator. A Kalman filter could make better use of your underlying physical reality. But for this you'd first need an idea how to model physical reality.

    https://en.wikipedia.org/wiki/Kalman_filter

    Here you can maybe also find a more close example in terms of tracking movements in computer vision: http://www.diss.fu-berlin.de/docs/servlets/MCRFileNodeServlet/FUDOCS_derivate_000000000473/2005_12.pdf