# Why Kalman Filter keeps returning the same prediction?

I'm trying to track pedestrians on a video using Kalman Filter. First, I initialize Kalman with the top-left coordinate (x0,y0) of a pedestrian's bounding box, which is stored within a sample. Next, I call kalmanPredict(), but it keeps returning the same (x0,y0) coordinate I passed.

for (int i = 0; i < samples->size(); i++) {

// retrieves person
sample = samples->at(i);

// Gets the bounding box of a person
Rect rectSample = sample->GetWindow();

// x0 and y0 coordinates of the bounding box
Point2f aux(rectSample.x0,rectSample.y0);

// initializes Kalman with this coordinate
initKalman(aux.x,aux.y);

// predicts for 10 frames, for example
for (int j = 0; j < 10; j++) {

//Predict
p = kalmanPredict();
s = kalmanCorrect(p.x,p.y);

//crop image and send for shared memory
SSFRect ret(p.x,p.y,rectSample.w,rectSample.h);

Point pt1, pt2, pt3;
pt1.x = p.x;
pt1.y = p.y;
pt2.x = p.x + rectSample.w;
pt2.y = p.y + rectSample.h;
pt3.x = s.x;
pt3.y = s.y;

rectangle(data, pt1, pt2, cv::Scalar(0,255,0), 5);
rectangle(data, pt3, pt2, cv::Scalar(255,0,0), 1);

// show result
imshow("janela", data);
waitKey(30);
aux = pt1;
cout<<i;
}

}


The following code is the setup of Kalman I'm using and contains the functions kalmanPredict() and kalmanCorrect(). I have tried different values for KF.transitionMatrix and KF.measurementMatrix, but it didn't make difference.

void initKalman(float x, float y)
{
// Instantate Kalman Filter with
// 4 dynamic parameters and 2 measurement parameters,
// where my measurement is: 2D location of object,
// and dynamic is: 2D location and 2D velocity.
KF.init(4, 2, 0);

measurement = Mat_<float>::zeros(2,1);
measurement.at<float>(0, 0) = x;
measurement.at<float>(1, 0) = y;

KF.statePre.setTo(0);

KF.statePre.at<float>(0, 0) = x;
KF.statePre.at<float>(1, 0) = y;

KF.statePost.setTo(0);
KF.statePost.at<float>(0, 0) = x;
KF.statePost.at<float>(1, 0) = y;

KF.transitionMatrix = (Mat_<float>(4, 4) << 1,0,1,0,   0,1,0,1,  0,0,1,0,  0,0,0,1); // Including velocity
KF.measurementMatrix = (Mat_<float>(2, 4) << 1,0,0,0, 0,1,0,0);
setIdentity(KF.processNoiseCov, Scalar::all(.005)); //adjust this for faster convergence - but higher noise
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
setIdentity(KF.errorCovPost, Scalar::all(.1));
}

Point kalmanPredict()
{
Mat prediction = KF.predict();
Point predictPt(prediction.at<float>(0),prediction.at<float>(1));

/*This prevents the filter from getting stuck in a state when no corrections are executed.*/
KF.statePre.copyTo(KF.statePost);
KF.errorCovPre.copyTo(KF.errorCovPost);

return predictPt;
}
Point2f kalmanCorrect(float x, float y)
{
measurement(0) = x;
measurement(1) = y;
Mat estimated = KF.correct(measurement);
Point2f statePt(estimated.at<float>(0),estimated.at<float>(1));
return statePt;
}


What am I missing? Why Kalman keeps returning the same prediction value to me?

edit retag close merge delete

Sort by » oldest newest most voted

Hi, I think your problem is the wrong usage of Point2f kalmanCorrect(float x, float y). You use the predicted state of the Kalman Filter to correct the filter.

p = kalmanPredict();
s = kalmanCorrect(p.x,p.y);


The state vector contains the 2D position and 2D velocity. In void initKalman(float x, float y) the position is set to x0 and y0 and the velocity in x and y direction is set to 0. If you then run kalmanPredict() the Kalman filter state will not change, since the velocity is 0. So you have after the kalmanPredict() still the state vector [x0, y0, 0, 0]. Then you run the correction step with the predicted position of the person (s = kalmanCorrect(p.x, p.y)). Since the predicted position of the person is still x0,y0 and the measurements are also x0,y0 the values in the state vector will also not change.

The solution should be, to use in the correction step of the Kalman filter the position where the person was detected in the current frame.

more

What happens if I track without new observations? If I set a non-zero velocity and give the initial position of a pedestrian, then I can track this person without new observations, assuming that the velocity is constant. If I feed Kalman with new observations given by the pedestrian detector, hence I'm using tracking by detection, which is more accurate because it can correct Kalman if a pedestrian changes its direction. Is this correct?

( 2013-12-14 16:52:50 -0500 )edit

@Siegfried, I think my question has changed. But, instead of updating my question, I'll accept your answer because it solves this problem and ask my new question (the one from the comment above) in another post. What do you think?

( 2013-12-19 07:43:57 -0500 )edit

Yes, if your question has changed you should start a new post to ask this new question.

( 2013-12-23 02:52:04 -0500 )edit

@Siegfried I am facing exactly the same problem, howevever I could not quite understand the first answer you gave, where should we place the correction step? I mean, the person is detected on the above loop, if I place the correction there then the below loop for 10 frames (as seen above code) will be running only for prediction?

#: 1
Detected at: [247, 264]
Corrected: [247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]
Predicted Point:[247, 264]

( 2015-05-15 04:30:12 -0500 )edit

Hi, My case is also similar to use kalman predict() without new observation. I want to use kalman when there is detection lost (In my case, when object is detected in previous frame but not detected in the current frame, then I want to use kalman). Please let me know how to use kalman filter when detection lost and there is no actual object detected location,only we have last detected location. Thanks in advance.

( 2019-12-10 23:49:01 -0500 )edit

Official site

GitHub

Wiki

Documentation