Object Tracking: Kalman Filter with Ease






4.89/5 (32 votes)
Discrete Kalman Filter brief tutorial with samples in C#
Contents
Introduction
![]() |
|
One of the primary computer vision tasks is object tracking. Object tracking is used in the vast majority of applications such as: video surveillance, car tracking (distance estimation), human detection and tracking, etc. The object trackers usually need some initialization steps such as the initial object location which can be provided manually or automatically by using an object detector such as a Viola and Jones detector or fast template matching. There are several major problems related to tracking:
- occlusion
- multiple objects tracking
- scale, illumination and change of appearance
- difficult and rapid motions
- ...
Even though object tracking has been a problem for many years, it is still not solved despite the fact that there are many object trackers, even the ones built for special purposes, and those which want to solve the problem in general.
Kalman filters, although they can be used for many other purposes, are often used for object tracking. They are especially convenient for objects which motion model is known, plus they incorporate some extra information in order to estimate the next object position more robustly. They can be used for general purpose single object tracking assuming some constraints. This article will explain the main idea behind Kalman filters and will focus on their practical usage for object tracking along with samples.
Kalman Filter - Main Idea
Let's assume that we have some kind of detector and that our detector is imperfect: it is prone to false positives, does not always detect objects, detects them imperfectly (does not provide exact position and scale) and its execution is costly. Let us also assume that we are tracking a single football player. After we detect the object, we want to leverage our information about the object in order to track it as robustly as we can. Our detector will give us just the location of the object so we have to use it as best as possible. In order to predict the next position of the player, we will need an object motion model (e.g. constant velocity motion, constant acceleration motion). Our detector is imperfect so there is noise in object locations, generally called measurement noise. Also, a selected motion model will not describe our player motion perfectly, so we also have noise regarding the model, called process noise. We want to estimate the next player position incorporating only the three parameters:
- Object motion model
- Measurement noise
- Process noise
So, we could efficiently re-detect it and hopefully cope with object occlusion. These next sections will show you how to do it.
![]() |
The cycle of a Kalman filter. Much of what the Kalman filter does can be reduced to propagating and updating Gaussians and updating their covariances. First the filter predicts the next state from the provided state transition (e.g. motion model), then if applicable, the noisy measurement information is incorporated in the correction phase. The cycle is repeated. |
Initial State
We are going to first introduce the initial state and what we are trying to accomplish. The following figures show the initial state and in the same time introduce most relevant terms.
Reading this section bear in mind:
- x(t) - state vector
- z(t) - measurement
- P(t|t-1) - process covariance matrix
Predict
Prediction is the first step which includes the next state (position and velocity) prediction as well as updating our uncertainty about the object state (increasing the uncertainty).
Reading this section, bear in mind:
- F - state transition matrix
- Q(t) - process noise covariance
Correct
After the noisy measurement has been obtained, the correction step begins. It incorporates a Kalman filter update which includes a state update and uncertainty update (decreasing the uncertainty).
Reading this section, you should know what is:
- R(t) - measurement noise
Now, when you know the basics, it is time for real samples, but first the brief introduction to the implementation.
Implementation
The provided implementation is generic: DiscreteKalmanFilter<TState, TMeasurement>
. The generic parameters are the state type (TState
) and the measurement type (TMeasurement
). This kind of implementation adds one abstraction layer which enables:
- easier code handling
- much easier debugging
- extensibility
The class diagram below shows the implementation outline:
![]() |
Class diagram. The implementation of the Kalman filter consists of two classes - one abstract and concrete which implements discrete Kalman filter. The common motion models are also implemented. |
Assume we want to use constant velocity model and the measurement model is an object's location (just as in figures above). The usage sample for this sample is shown below.
Initialization
The most complex step is the initialization. We have to set: process and measurement noise (Q and R), process covariance matrix (P), state transition matrix (F) and model selection matrix (H). The built-in models greatly simplify this task. The initialization step is a bit longer due to flexibility. For example, the Extended Kalman Filter needs transition matrix which is changed in each step. Also, the process and measurement noise (Q and R) may not be constant so they could also be changed in each step.
using ModelState = Accord.Extensions.Statistics.Filters.ConstantVelocity2DModel;
KalmanFilter<ModelState, PointF> kalman = null;
var measurementDimension = 2; //just coordinates
var initialState = new ModelState { Position = new PointF(0,0), Velocity = new PointF(0.5f, -2f)};
var initialStateError = ModelState.GetProcessNoise(accelerationNoise: 10); //process cov. mat. - P(0|0)
//create Kalman filter
kalman = new DiscreteKalmanFilter<ModelState, PointF>(
initialState, initialStateError, //x(0) and P(0|0)
measurementDimension /*(position)*/, 0 /*no control*/,
//state and measurement <=> array conversion
x => ModelState.ToArray(x), x => ModelState.FromArray(x), x => new double[] { x.X, x.Y });
kalman.ProcessNoise = ModelState.GetProcessNoise(accelerationNoise: 10.0); //process noise - Q
kalman.MeasurementNoise = Matrix.Diagonal<double>(kalman.MeasurementVectorDimension, 1.3); //measurement noise - R
kalman.MeasurementMatrix = ModelState.GetPositionMeasurementMatrix(); //measurement selection mat. - H
kalman.TransitionMatrix = ModelState.GetTransitionMatrix(); //state transition matrix - F
Predict
The prediction step consists of only one method, which if there are no measurements is executed repetitively without correction method.
kalman.Predict(); //predict next state
Correct
The correction method receives noisy measurement (obtained from e.g. detector).
PointF objectPosition = .... //the position obtained by detector
kalman.Correct(objeectPosition); //correct predicted state by measurement
Console.WriteLine(kalman.State.Position.X + " " + kalman.State.Position.Y);
Conclusion
The discrete Kalman Filter is described for the purpose of the object tracking problem along with its implementation in C#. If we have a linear motion model, and process and measurement noise are Gaussian-like, then the Kalman filter represents the optimal solution for the state update (in our case tracking problem). Those conditions are satisfied for a vast majority of applications.
The source and sample code are the part of Accord.NET Extensions Framework, a framework that brings many advanced algorithms primarily for image processing, object detection and tracking, all packed as fluent extensions and simple and intuitive generics, so do not forget to take a peek :).
References
[1] | Smith K. "Selected Topics in Computer Vision - 2D Tracking 1/2 IJACI" by far the best tutorial for object tracking - some slides are used in this article |
[2] | Kantor G. "Kalman’s Beautiful Filter" |
[3] | Kalman, R. E. (1960). "A New Approach to Linear Filtering and Prediction Problems". Journal of Basic Engineering 82 (1): 35–45 |
History
- 16th January, 2015 - First version released