Ask Your Question
2

Why Kalman Filter keeps returning the same prediction?

asked 2013-12-02 09:26:29 -0600

Yamaneko gravatar image

updated 2013-12-02 09:45:30 -0600

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 flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-12-03 01:50:13 -0600

Siegfried gravatar image

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.

edit flag offensive delete link more

Comments

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?

Yamaneko gravatar imageYamaneko ( 2013-12-14 16:52:50 -0600 )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?

Yamaneko gravatar imageYamaneko ( 2013-12-19 07:43:57 -0600 )edit

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

Siegfried gravatar imageSiegfried ( 2013-12-23 02:52:04 -0600 )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]
karmaDet gravatar imagekarmaDet ( 2015-05-15 04:30:12 -0600 )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.

eLtronicsvilla gravatar imageeLtronicsvilla ( 2019-12-10 23:49:01 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-12-02 09:26:29 -0600

Seen: 4,078 times

Last updated: Dec 03 '13