2013-08-23 6 views
11

मैं कुछ शोर बिंदुओं को सुचारू बनाने के लिए ओपनसीवी कलामैन फ़िल्टर कार्यान्वयन का उपयोग करना चाहता हूं। तो मैंने इसके लिए एक सरल परीक्षण कोड करने की कोशिश की है।ओपनसीवी कलमैन फ़िल्टर भविष्यवाणी बिना नए अवलोकन

मान लें कि मेरे पास एक अवलोकन (एक बिंदु) है। प्रत्येक फ्रेम को मैं नया अवलोकन प्राप्त कर रहा हूं, मैं कलमान भविष्यवाणी और कलमान को सही कहता हूं। Opencv Kalman फ़िल्टर सही के बाद आने वाला राज्य "बिंदु का पालन" है, यह ठीक है।

तो मान लें कि मेरे पास एक लापता अवलोकन है, मैं चाहता हूं कि कलमैन फ़िल्टर को अपडेट किया जाए और नए राज्य की भविष्यवाणी की जाए। यहां मेरा कोड विफल हो रहा है: अगर मैं kalman.predict() को कॉल करता हूं तो मान अब अपडेट नहीं होता है।

#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; 
} 

मुझे लगता है कि इस कोड को मैं क्या समझ में नहीं आता की काफी निदर्शी है:

यहाँ मेरी कोड है। मैंने some theory और कुछ practical example का पालन करने का प्रयास किया है, लेकिन अभी भी यह सुनिश्चित नहीं है कि भविष्य की स्थिति की नई भविष्यवाणी कैसे प्राप्त करें ..

कोई भी मुझे यह समझने में सहायता कर सकता है कि मैं क्या गलत कर रहा हूं?

उत्तर

2

मैंने संक्रमण और माप मैट्रिक्स सेट नहीं किया है।

मुझे इस excellent MATLAB documentation page में उन मैट्रिक्स के लिए मानक राज्य-स्थान मान मिले हैं।

1

प्रत्येक भविष्यवाणी के बाद, आपको भविष्यवाणी की गई स्थिति (राज्यप्रे) को सही स्थिति (राज्यपोस्ट) में प्रतिलिपि बनाना चाहिए। यह राज्य covariance (errorCovPre -> errorCovPost) के लिए भी किया जाना चाहिए। यह फिल्टर को किसी राज्य में फंसने से रोकता है जब कोई सुधार निष्पादित नहीं होता है। कारण यह है कि भविष्यवाणी() राज्यपोस्ट में संग्रहीत राज्य मूल्यों का उपयोग करती है, जो कोई सुधार नहीं होने पर बदलती नहीं है।

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

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

    return predictPt; 
} 
+2

उम, कि क्या [ 'सीवी :: KalmanFilter :: correct'] (http://docs.opencv.org /master/dd/d6a/classcv_1_1KalmanFilter.html#a60eb7feb569222ad0657ef1875884b5e) के लिए है। – chappjc

+1

@Xisco 2.4 और बाद के स्रोत के लिए देख रहे हैं, पोस्टरियोरी राज्य की भविष्यवाणी की नकल पहले ही हो चुकी है। Https://github.com/opencv/opencv/blob/master/modules/video/src/kalman.cpp#L97 या https://github.com/opencv/opencv/blob/2.4/modules/video/src देखें /kalman.cpp#L267 यह संभव है कि जब यह प्रश्न मूल रूप से पूछा गया, तो स्रोत ने ऐसा नहीं किया। मैं वास्तव में इसे यहां किसी भी प्रश्न के लिए एक सूचक के रूप में जोड़ रहा हूं जो आई के समान प्रश्न में आया था। –

8

उन लोगों को जो अभी भी OpenCV Kalman छानने

ऊपर तैनात कोड छोटा सा संशोधन के बाद अच्छी तरह से काम करता है का उपयोग करने में समस्या है के लिए:

आपका kalmanPredict समारोह तो इस प्रकार होगी। संक्रमण मैट्रिक्स को पहचान में सेट करने के बजाय, आप निम्नानुसार सेट कर सकते हैं।

संशोधन

KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0, 0,1,0,1, 0,0,1,0, 0,0,0,1); 

आउटपुट

enter image description here

संबंधित मुद्दे