Opencv de kalman le filtre de prédiction sans nouvelles observtion
Je wan à utiliser Opencv la mise en œuvre du filtre de Kalman pour lisser un peu de bruit de points. J'ai donc essayé de coder un test simple pour elle.
Disons que j'ai une observation (un point). Chaque image que je reçois une nouvelle observation, j'appelle de Kalman prédire et Kalman correcte. L'état vient après opencv filtre de Kalman correcte est "suivant le point", c'est ok.
Alors disons que j'ai un manque d'observation, je veux de toute façon le filtre de Kalman d'être mis à jour et de prédire le nouvel état. Voici mon code est un échec: si je l'appelle de kalman.predict() la valeur n'est plus mis à jour.
Voici mon code:
#include <iostream>
#include <vector>
#include <sys/time.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/tracking.hpp>
using namespace cv;
using namespace std;
//------------------------------------------------ convenience method for
// using kalman filter with
// Point objects
cv::KalmanFilter KF;
cv::Mat_<float> measurement(2,1);
Mat_<float> state(4, 1); //(x, y, Vx, Vy)
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>(0, 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;
setIdentity(KF.transitionMatrix);
setIdentity(KF.measurementMatrix);
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));
return predictPt;
}
Point kalmanCorrect(float x, float y)
{
measurement(0) = x;
measurement(1) = y;
Mat estimated = KF.correct(measurement);
Point statePt(estimated.at<float>(0),estimated.at<float>(1));
return statePt;
}
//------------------------------------------------ main
int main (int argc, char * const argv[])
{
Point s, p;
initKalman(0, 0);
p = kalmanPredict();
cout << "kalman prediction: " << p.x << " " << p.y << endl;
/*
* output is: kalman prediction: 0 0
*
* note 1:
* ok, the initial value, not yet new observations
*/
s = kalmanCorrect(10, 10);
cout << "kalman corrected state: " << s.x << " " << s.y << endl;
/*
* output is: kalman corrected state: 5 5
*
* note 2:
* ok, kalman filter is smoothing the noisy observation and
* slowly "following the point"
* .. how faster the kalman filter follow the point is
* processNoiseCov parameter
*/
p = kalmanPredict();
cout << "kalman prediction: " << p.x << " " << p.y << endl;
/*
* output is: kalman prediction: 5 5
*
* note 3:
* mhmmm, same as the last correction, probabilly there are so few data that
* the filter is not predicting anything..
*/
s = kalmanCorrect(20, 20);
cout << "kalman corrected state: " << s.x << " " << s.y << endl;
/*
* output is: kalman corrected state: 10 10
*
* note 3:
* ok, same as note 2
*/
p = kalmanPredict();
cout << "kalman prediction: " << p.x << " " << p.y << endl;
s = kalmanCorrect(30, 30);
cout << "kalman corrected state: " << s.x << " " << s.y << endl;
/*
* output is: kalman prediction: 10 10
* kalman corrected state: 16 16
*
* note 4:
* ok, same as note 2 and 3
*/
/*
* now let's say I don't received observation for few frames,
* I want anyway to update the kalman filter to predict
* the future states of my system
*
*/
for(int i=0; i<5; i++) {
p = kalmanPredict();
cout << "kalman prediction: " << p.x << " " << p.y << endl;
}
/*
* output is: kalman prediction: 16 16
* kalman prediction: 16 16
* kalman prediction: 16 16
* kalman prediction: 16 16
* kalman prediction: 16 16
*
* !!! kalman filter is still on 16, 16..
* no future prediction here..
* I'm exprecting the point to go further..
* why???
*
*/
return 0;
}
Je pense que ce code est assez illustratif de ce que je ne comprends pas. J'ai essayé de suivre un peu de théorie et certains exemple pratique mais n'a pas encore unserstand comment obtenir une nouvelle prédiction de la position future..
Quelqu'un peut m'aider à comprendre ce que je fais mal?
OriginalL'auteur nkint | 2013-08-23
Vous devez vous connecter pour publier un commentaire.
Pour ceux qui ont encore un problème en utilisant OpenCV filtrage de Kalman
Ci-dessus posté le code fonctionne bien, après une petite modification. Au lieu de configurer la matrice de transition d'Identité, vous pouvez définir comme suit.
Modification
Sortie
OriginalL'auteur Ghimire
Je n'ai pas mis la transition et de la mesure matricielle.
J'ai trouvé, état standard les valeurs de l'espace pour ceux de la matrice dans cette excellente page de documentation MATLAB.
OriginalL'auteur nkint
Après chaque prédiction, vous devez copier l'état prédit (statePre) dans le corrigé de l'état (statePost). Cela devrait également être fait pour l'état de covariance (errorCovPre -> errorCovPost). Cela empêche le filtre de devenir coincé dans un état si aucune correction n'est exécutée. La raison en est que predict() rend l'utilisation de l'état des valeurs stockées dans statePost, qui ne changent pas si aucune correction n'est appelé.
Votre kalmanPredict fonction est alors la suivante:
cv::KalmanFilter::correct
c'est pour.En regardant la source pour 2,4 et après, la copie de la prédite à posteriori de l'état est déjà fait. Voir github.com/opencv/opencv/blob/master/modules/video/src/... ou github.com/opencv/opencv/blob/2.4/modules/video/src/... Il est possible que, lorsque cette question a été demandé à l'origine, la source n'a pas à faire cela. Je suis vraiment en ajoutant cette ici comme un pointeur pour toute personne qui est venu à travers la même question que moi.
OriginalL'auteur Xisco