卡尔曼滤波器 - 空预测点

时间:2017-05-23 11:00:23

标签: c++ opencv kalman-filter

我正在尝试使用OpenCV在C ++中应用卡尔曼滤波器来过滤某些音轨。使它适用于我的第一步是使用Points2f向量的滤波器预测点。

我的代码如下:

cv::KalmanFilter kalmanFilter(4,2,0, CV_32F); 
kalmanFilter.transitionMatrix = transitionMat;
for(int i = 0 ; i < oldTrackeables.size() ; i++)
    for(int j = 0 ; j < oldTrackeables[i].getTrack().size() ; j++)
              {
                  cv::Size msmtSize(2,1);
                  cv::Mat measurementMat(msmtSize, CV_32F);
                  measurementMat.setTo(cv::Scalar(0));
                  measurementMat.at<float>(0) = oldTrackeables[i].getTrack()[j].x;
                  measurementMat.at<float>(1) = oldTrackeables[i].getTrack()[j].y;

                  //Initialisation of the Kalman filter
                  kalmanFilter.statePre.at<float>(0) = (float) oldTrackeables[i].getTrack()[j].x;
                  kalmanFilter.statePre.at<float>(1) = (float) oldTrackeables[i].getTrack()[j].y;
                  kalmanFilter.statePre.at<float>(2) = (float) 2;
                  kalmanFilter.statePre.at<float>(3) = (float) 3;


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

                 //Prediction
                 cv::Mat prediction = kalmanFilter.predict();

                 kalmanFilter.statePre.copyTo(kalmanFilter.statePost);
                 kalmanFilter.errorCovPre.copyTo(kalmanFilter.errorCovPost);

                 cv::Point predictPt(prediction.at<float>(0), prediction.at<float>(1));
                 cv::Point Mc = oldTrackeables[i].getMassCenter();          

                 cv::circle(kalmat, predictPt, 16, cv::Scalar(0,255,0), 3, 2, 1);


                 std::cout<<"prediction : x = " << predictPt.x << " - y = " << predictPt.y <<std::endl;
                 std::cout<<"position captée : x = " << oldTrackeables[i].getTrack()[j].x << " - y = " << oldTrackeables[i].getTrack()[j].y << std::endl;
                 std::cout<<"size of frame : rows = " << frame.rows << " - width = " << frame.cols <<std::endl;
                 std::cout<<"size of kalmat : rows = " << kalmat.rows << " - width = " << kalmat.cols <<std::endl;
                 cv::imshow("kalmat", kalmat);

oldTrackeables [i] .getTrack()[j]只是向量中的一些Points2f。

跟踪是正确的,但卡尔曼滤波器没有为预测提供“正确”值 - 例如,程序显示:     预测:x = 0 - y = 0 -     位置captée:x = 138.29 - y = 161.078(原点的位置)。

我一直在寻找很多答案,并尝试了许多不同的方法来做到这一点,但我找不到真正帮助我的任何东西......我找到的更接近的是这一个:http://answers.opencv.org/question/24865/why-kalman-filter-keeps-returning-the-same-prediction/但是它没有帮助我解决我的问题...

如果你们中的任何一个人有回答的元素可以帮助我理解这个问题,我将非常感激。 谢谢。

2 个答案:

答案 0 :(得分:1)

首先,我会将所有初始化内容移到循环之外,否则你将覆盖过滤器中的内部状态。同时将statePre更改为statPost

  //Initialisation of the Kalman filter
  kalmanFilter.statePost.at<float>(0) = (float) 0;   
  kalmanFilter.statePost.at<float>(1) = (float) 0;
  kalmanFilter.statePost.at<float>(2) = (float) 2;
  kalmanFilter.statePost.at<float>(3) = (float) 3;

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

部分:

 kalmanFilter.statePre.copyTo(kalmanFilter.statePost);                     
 kalmanFilter.errorCovPre.copyTo(kalmanFilter.errorCovPost);
应该删除

,因为这是在predict阶段内部完成的。

最后,正如@Mozfox所说,correct阶段不存在于您提供的循环代码中。添加:

kalmanFilter.predict(measurementMat);

答案 1 :(得分:0)

我认为您缺少测量计算的校正阶段。