0

I implemented kalman filter for face tracking with OpenCV. But the effect do not meet my expectation: the tracking box delay very much (the tracking box moving to my face very slowly). The following is my code. Am I implement it the right way?

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


int main()
{
    // detect face
    CascadeClassifier cc("model/haarcascade_frontalface_alt2.xml");
    VideoCapture vc(0);
    Mat frame;

    Rect face;

    // intialization of KF...
    KalmanFilter KF(4, 2, 0);
    KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0,   0,1,0,1,  0,0,1,0,  0,0,0,1);
    Mat_<float> measurement(2,1); measurement.setTo(Scalar(0));


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

    for(; ;) {
        vc >> frame;

        vector<Rect> faces;
        cc.detectMultiScale(frame, faces, 1.2, 3, CASCADE_DO_ROUGH_SEARCH, Size(80, 80));
        if (faces.size() > 0) {
            face = faces[0];
            KF.statePre.at<float>(0) = face.x;
            KF.statePre.at<float>(1) = face.y;
            KF.statePre.at<float>(2) = 0;
            KF.statePre.at<float>(3) = 0;
        }


        // First predict, to update the internal statePre variable
        Mat prediction = KF.predict();
        Rect predictFace((int)prediction.at<float>(0), (int)prediction.at<float>(1), face.width, face.height);

        // The update phase 
        measurement(0) = face.x;
        measurement(1) = face.y;

        Mat estimated = KF.correct(measurement);

        Rect estFace((int)estimated.at<float>(0), (int)estimated.at<float>(1), face.width, face.height);
        rectangle(frame, predictFace, Scalar(0, 255, 0));
        rectangle(frame, estFace, Scalar(0, 0, 255));

        imshow("", frame);
        waitKey(50);
    }

    return 0;
}
anatol
  • 791
  • 9
  • 16
tidy
  • 4,747
  • 9
  • 49
  • 89
  • Kalman filter was used to track airplanes with radars. it is supposed to remember past errors. that's why it's "slow" for you. try to use it in a combinatorial way with the detector (in parallel and not in cascade). e.g. use kalman when detector doesnt work or use both kalman and detector for the localization. – LovaBill Dec 22 '14 at 08:49
  • 3
    setIdentity(KF.measurementNoiseCov, Scalar::all(10)); // <-- try a much smaller value here, like 0.02 – berak Dec 22 '14 at 08:50
  • I found set `KF.processNoiseCov` bigger (such as: `setIdentity(KF.processNoiseCov, Scalar::all(10));`) also work. – tidy Dec 23 '14 at 01:38
  • Another question: am I implement the right way for face tracking, especially the `predict`, the `correct` part?. – tidy Dec 23 '14 at 01:51

0 Answers0