KalmanMouse: Restructure a bit
This commit is contained in:
		
							parent
							
								
									f45dd535a0
								
							
						
					
					
						commit
						61896aa501
					
				
					 1 changed files with 82 additions and 48 deletions
				
			
		
							
								
								
									
										130
									
								
								KalmanMouse.cpp
									
										
									
									
									
								
							
							
						
						
									
										130
									
								
								KalmanMouse.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -1,82 +1,116 @@
 | 
				
			||||||
// http://opencvexamples.blogspot.com/2014/01/kalman-filter-implementation-tracking.html
 | 
					// http://opencvexamples.blogspot.com/2014/01/kalman-filter-implementation-tracking.html
 | 
				
			||||||
// (slightly cleaned up and patched to use opencv's gui functions)
 | 
					// (slightly cleaned up, restructured and patched to use opencv's gui functions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "opencv2/highgui/highgui.hpp"
 | 
					#include "opencv2/highgui/highgui.hpp"
 | 
				
			||||||
#include "opencv2/video/tracking.hpp"
 | 
					#include "opencv2/video/tracking.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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 )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace cv;
 | 
					using namespace cv;
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Point mousePos;
 | 
					Point mousePos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void mouseCallback(int event, int x, int y, int flags, void* userdata) {
 | 
					// save mouse position in the global mousePos.
 | 
				
			||||||
     if ( event == EVENT_MOUSEMOVE ) {
 | 
					void saveMousePosCallback(int event, int x, int y, int flags, void* userdata) {
 | 
				
			||||||
 | 
					     if (event == EVENT_MOUSEMOVE) {
 | 
				
			||||||
         mousePos.x = x;
 | 
					         mousePos.x = x;
 | 
				
			||||||
         mousePos.y = y;
 | 
					         mousePos.y = y;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					#define ADDNOISE 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    KalmanFilter KF(4, 2, 0);
 | 
					// measures the mouse position by reading from mousePos and adding some
 | 
				
			||||||
 | 
					// artificial noise.
 | 
				
			||||||
    // intialization of KF...
 | 
					Mat_<float> measure() {
 | 
				
			||||||
    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);
 | 
					    Mat_<float> measurement(2,1);
 | 
				
			||||||
 | 
					    Mat_<float> measurementNoise(2,1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    KF.statePre.at<float>(0) = mousePos.x;
 | 
					    measurement(0) = mousePos.x;
 | 
				
			||||||
    KF.statePre.at<float>(1) = mousePos.y;
 | 
					    measurement(1) = mousePos.y;
 | 
				
			||||||
    KF.statePre.at<float>(2) = 0;
 | 
					 | 
				
			||||||
    KF.statePre.at<float>(3) = 0;
 | 
					 | 
				
			||||||
    setIdentity(KF.measurementMatrix);
 | 
					 | 
				
			||||||
    setIdentity(KF.processNoiseCov, Scalar::all(1e-4));
 | 
					 | 
				
			||||||
    setIdentity(KF.measurementNoiseCov, Scalar::all(10));
 | 
					 | 
				
			||||||
    setIdentity(KF.errorCovPost, Scalar::all(.1));
 | 
					 | 
				
			||||||
    // Image to show mouse tracking
 | 
					 | 
				
			||||||
    Mat img(600, 800, CV_8UC3);
 | 
					 | 
				
			||||||
    vector<Point> mousev,kalmanv;
 | 
					 | 
				
			||||||
    mousev.clear();
 | 
					 | 
				
			||||||
    kalmanv.clear();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    namedWindow("mouse kalman", 1);
 | 
					#if ADDNOISE == 1
 | 
				
			||||||
    setMouseCallback("mouse kalman", mouseCallback, NULL);
 | 
					    Mat mean  = Mat::zeros(1,1,CV_64FC1);
 | 
				
			||||||
 | 
					    Mat sigma = Mat::ones(1,1,CV_64FC1) * 5;
 | 
				
			||||||
 | 
					    randn(measurementNoise, mean, sigma);
 | 
				
			||||||
 | 
					    measurement += measurementNoise;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while(1) {
 | 
					    return measurement;
 | 
				
			||||||
        // First predict, to update the internal statePre variable
 | 
					}
 | 
				
			||||||
        Mat prediction = KF.predict();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // The update phase
 | 
					// draw a cross
 | 
				
			||||||
        measurement(0) = mousePos.x;
 | 
					void drawCross(Mat img, Point center, Scalar color, int d) {
 | 
				
			||||||
        measurement(1) = mousePos.y;
 | 
					    line(img, Point(center.x - d, center.y - d),
 | 
				
			||||||
        Mat estimated = KF.correct(measurement);
 | 
					              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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Mat img(600, 800, CV_8UC3);
 | 
				
			||||||
 | 
					vector<Point> mousev, kalmanv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Plot
 | 
					void plot() {
 | 
				
			||||||
        img = Scalar::all(0);
 | 
					        img = Scalar::all(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Point statePt(estimated.at<float>(0),estimated.at<float>(1));
 | 
					 | 
				
			||||||
        Point measPt(measurement(0),measurement(1));
 | 
					 | 
				
			||||||
        drawCross(statePt, Scalar(255,255,255), 5);
 | 
					 | 
				
			||||||
        drawCross(measPt, Scalar(0,0,255), 5);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mousev.push_back(measPt);
 | 
					        Point statePt = kalmanv.back();
 | 
				
			||||||
        kalmanv.push_back(statePt);
 | 
					        Point measPt = mousev.back();
 | 
				
			||||||
 | 
					        drawCross(img, statePt, Scalar(255,255,255), 5);
 | 
				
			||||||
 | 
					        drawCross(img, measPt, Scalar(0,0,255), 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = 0; i < mousev.size()-1; i++)
 | 
					        for (int i = 0; i < mousev.size()-1; i++)
 | 
				
			||||||
            line(img, mousev[i], mousev[i+1], Scalar(255,255,0), 1);
 | 
					            line(img, mousev[i], mousev[i+1], Scalar(255,255,0), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = 0; i < kalmanv.size()-1; i++)
 | 
					        for (int i = 0; i < kalmanv.size()-1; i++)
 | 
				
			||||||
            line(img, kalmanv[i], kalmanv[i+1], Scalar(0,155,255), 1);
 | 
					            line(img, kalmanv[i], kalmanv[i+1], Scalar(0,155,255), 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
        imshow("mouse kalman", img);
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        waitKey(10);
 | 
					
 | 
				
			||||||
    }
 | 
					int main() {
 | 
				
			||||||
 | 
					    namedWindow("mouse kalman", 1);
 | 
				
			||||||
    return 0;
 | 
					    setMouseCallback("mouse kalman", saveMousePosCallback, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 4 state dimensions: x, y, dx, dy
 | 
				
			||||||
 | 
					    // 2 measurement dimensions: x, y
 | 
				
			||||||
 | 
					    KalmanFilter KF(4, 2, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // transition matrix models: x' = x + dx, y' = y + dy, dx' = dx, dy' = dy
 | 
				
			||||||
 | 
					    KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0,   0,1,0,1,  0,0,1,0,  0,0,0,1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setIdentity(KF.measurementMatrix);
 | 
				
			||||||
 | 
					    setIdentity(KF.processNoiseCov, Scalar::all(1e-3));
 | 
				
			||||||
 | 
					    setIdentity(KF.measurementNoiseCov, Scalar::all(10));
 | 
				
			||||||
 | 
					    setIdentity(KF.errorCovPost, Scalar::all(.1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (waitKey(10) < 0) {
 | 
				
			||||||
 | 
					        // First predict, to update the internal statePre variable
 | 
				
			||||||
 | 
					        Mat prediction = KF.predict();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Measure
 | 
				
			||||||
 | 
					        Mat_<float> measurement = measure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Update
 | 
				
			||||||
 | 
					        Mat_<float> estimated = KF.correct(measurement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Save history
 | 
				
			||||||
 | 
					        Point statePt(estimated(0),estimated(1));
 | 
				
			||||||
 | 
					        Point measPt(measurement(0),measurement(1));
 | 
				
			||||||
 | 
					        mousev.push_back(measPt);
 | 
				
			||||||
 | 
					        kalmanv.push_back(statePt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Plot
 | 
				
			||||||
 | 
					        plot();
 | 
				
			||||||
 | 
					        imshow("mouse kalman", img);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue