Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

asked 2015-09-30 10:50:54 -0600

Nbb gravatar image

Kalman Filter Question

Hello forum,

I am trying to understand the theory behind kalman filter and I have a question to ask. I am following the tutorial shown here. http://opencvexamples.blogspot.com/2014/01/kalman-filter-implementation-tracking.html

The predicted position of the cursor is always "lagging behind" no matter how high the velocity of the transition matrix is at. I even tried setting it to 100. What values should I change such that the filter predicts the position of my cursor way ahead ? In other words, I would like the prediction to not lag behind, just like the particle filter for tracking.

Kalman Filter Question

Hello forum,

I am trying to understand the theory behind kalman filter and I have a question to ask. I am following the tutorial shown here. http://opencvexamples.blogspot.com/2014/01/kalman-filter-implementation-tracking.html

The predicted position of the cursor is always "lagging behind" no matter how high the velocity of the transition matrix is at. I even tried setting it to 100. What values should I change such that the filter predicts the position of my cursor way ahead ? In other words, I would like the prediction to not lag behind, just like the particle filter for tracking.

#include <iostream>
#include <vector>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/tracking.hpp>

using namespace cv;
using namespace std;


struct mouse_info_struct { int x, y; };
struct mouse_info_struct mouse_info = { -1, -1 }, last_mouse;


// plot points
#define drawCross( center, color, d )                                 \
line( img, Point( center.x - d, center.y - d ),                \
Point( center.x + d, center.y + d ), color, 2, CV_AA, 0); \
line( img, Point( center.x + d, center.y - d ),                \
Point( center.x - d, center.y + d ), color, 2, CV_AA, 0 )


vector<Point> mousev, kalmanv, predictv;

void on_mouse(int event, int x, int y, int flags, void* param) {
    {
        last_mouse = mouse_info;
        mouse_info.x = x;
        mouse_info.y = y;

        cout << "got mouse " << x << "," << y << endl;
    }
}


int main(int argc, char * const argv[])
{
    Mat img(500, 500, CV_8UC3);
    KalmanFilter KF(6, 2, 0);
    Mat_<float> state(6, 1);
    Mat processNoise(6, 1, CV_32F);
    Mat_<float> measurement(2, 1); measurement.setTo(Scalar(0));
    char code = (char)-1;

    namedWindow("mouse kalman");
    setMouseCallback("mouse kalman", on_mouse, 0);

    for (;;)
    {
        if (mouse_info.x < 0 || mouse_info.y < 0)
        {
            imshow("mouse kalman", img);
            waitKey(30);
            continue;
        }
        else
            break;
    }
    KF.statePre.at<float>(0) = mouse_info.x;
    KF.statePre.at<float>(1) = mouse_info.y;
    KF.statePre.at<float>(2) = 0;
    KF.statePre.at<float>(3) = 0;
    KF.statePre.at<float>(4) = 0;
    KF.statePre.at<float>(5) = 0;

    int dt_x = 0;
    int dt_y = 0;

    KF.transitionMatrix = (Mat_<float>(6, 6) << 1, 0, dt_x, 0, 0.5, 0, 
                                                0, 1, 0, dt_y, 0, 0.5, 
                                                0, 0, 1, 0, 1, 0,
                                                0, 0, 0, 1, 0, 1, 
                                                0, 0, 0, 0, 1, 0, 
                                                0, 0, 0, 0, 0, 1);


    KF.measurementMatrix = (Mat_<float>(2, 6) << 1, 0, 1, 0, 0.5, 0, 0, 1, 0, 1, 0, 0.5);

    setIdentity(KF.measurementMatrix);
    setIdentity(KF.processNoiseCov, Scalar::all(1e-4));
    setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
    setIdentity(KF.errorCovPost, Scalar::all(.1));

    mousev.clear();
    kalmanv.clear();
    while (1 == 1)
    {

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

        if (predictv.size() > 1)
            for (int i = 0; i < predictv.size() - 1; i++)
        {
            line(img, predictv[i], predictv[i + 1], Scalar(255, 255, 255), 2);
        }

        measurement(0) = mouse_info.x;
        measurement(1) = mouse_info.y;

        Point measPt(measurement(0), measurement(1));
        mousev.push_back(measPt);

        Mat estimated = KF.correct(measurement);
        Point statePt(estimated.at<float>(0), estimated.at<float>(1));
        kalmanv.push_back(statePt);

        if (kalmanv.size() > 1)
        {
            dt_x = kalmanv.end()[-1].x - kalmanv.end()[-2].x;
            dt_y = kalmanv.end()[-1].y - kalmanv.end()[-2].y;
        }

        img = Scalar::all(0);
        drawCross(statePt, Scalar(255, 255, 255), 5);
        drawCross(measPt, Scalar(0, 0, 255), 5);

        for (int i = 0; i < mousev.size() - 1; i++)
        {
            line(img, mousev[i], mousev[i + 1], Scalar(255, 255, 0), 1);
        }

        imshow("mouse kalman", img);
        code = (char)waitKey(10);

        if (code > 0)
            break;
    }

    return 0;
}