kalman.cpp

Example program that causes the segmentation fault - Vito Macchia, 2010-07-09 02:09 pm

Download (3.7 kB)

 
1
/*
2
   Tracking of rotating point.
3
   Rotation speed is constant.
4
   Both state and measurements vectors are 1D (a point angle),
5
   Measurement is the real point angle + gaussian noise.
6
   The real and the estimated points are connected with yellow line segment,
7
   the real and the measured points are connected with red line segment.
8
   (if Kalman filter works correctly,
9
    the yellow segment should be shorter than the red one).
10
   Pressing any key (except ESC) will reset the tracking with a different speed.
11
   Pressing ESC will stop the program.
12
*/
13
14
15
#include <cv.h>
16
#include <highgui.h>
17
#include <cmath>
18
19
using namespace std;
20
using namespace cv;
21
22
int main(int argc, char** argv)
23
{
24
    const float A[] = { 1, 1, 0, 1 };
25
26
    Mat img = Mat( Size(500,500), CV_8UC3 );
27
    KalmanFilter kalman = KalmanFilter( 2, 1, 0 );
28
    Mat state = Mat( 2, 1, CV_32FC1 ); /* (phi, delta_phi) */
29
    Mat process_noise = Mat( 2, 1, CV_32FC1 );
30
    Mat measurement = Mat::zeros( 1, 1, CV_32FC1 );
31
    RNG rng = RNG(-1);
32
    char code = -1;
33
34
35
    namedWindow( "Kalman", 1 );
36
37
    for(;;)
38
    {
39
        rng.fill(state,RNG::NORMAL,Scalar(0),Scalar(0.1));
40
41
        memcpy( kalman.transitionMatrix.data, A, sizeof(float)*sizeof(A));
42
        setIdentity( kalman.measurementMatrix, Scalar(1.0) );
43
        setIdentity( kalman.processNoiseCov, Scalar(1e-5) );
44
        setIdentity( kalman.measurementNoiseCov, Scalar(1e-1) );
45
        setIdentity( kalman.errorCovPost, Scalar(1));
46
        rng.fill(kalman.statePost, RNG::NORMAL, Scalar(0.0), Scalar(0.1) );
47
48
        for(;;)
49
        {
50
            #define calc_point(angle)                                      \
51
                Point( cvRound(img.cols/2 + img.cols/3*cos(angle)),  \
52
                         cvRound(img.cols/2 - img.cols/3*sin(angle)))
53
54
            float state_angle = state.ptr<float>(0)[0];
55
            Point state_pt = calc_point(state_angle);
56
57
            const Mat prediction = kalman.predict();
58
            float predict_angle = prediction.ptr<float>(0)[0];
59
            Point predict_pt = calc_point(predict_angle);
60
            float measurement_angle;
61
            Point measurement_pt;
62
63
            rng.fill(measurement, RNG::NORMAL, Scalar(0),
64
                       Scalar(sqrt(kalman.measurementNoiseCov.ptr<float>(0)[0])) );
65
66
            /* generate measurement */
67
            measurement=kalman.measurementMatrix*state+measurement;
68
69
            measurement_angle = measurement.ptr<float>(0)[0];
70
            measurement_pt = calc_point(measurement_angle);
71
72
            /* plot points */
73
            #define draw_cross( center, color, d )                                 \
74
                line( img, Point( center.x - d, center.y - d ),                \
75
                             Point( center.x + d, center.y + d ), color, 1, CV_AA, 0); \
76
                line( img, Point( center.x + d, center.y - d ),                \
77
                             Point( center.x - d, center.y + d ), color, 1, CV_AA, 0 )
78
79
            img.setTo(Scalar(0));
80
            draw_cross( state_pt, Scalar(255,255,255), 3 );
81
            draw_cross( measurement_pt, Scalar(255,0,0), 3 );
82
            draw_cross( predict_pt, CV_RGB(0,255,0), 3 );
83
            line( img, state_pt, measurement_pt, CV_RGB(255,0,0), 3, CV_AA, 0 );
84
            line( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, CV_AA, 0 );
85
86
            kalman.correct( measurement );
87
88
            rng.fill(process_noise, RNG::NORMAL, Scalar(0),
89
                       Scalar(sqrt(kalman.processNoiseCov.ptr<float>(0)[0])));
90
            state=kalman.transitionMatrix*state+process_noise;
91
92
            imshow( "Kalman", img );
93
            code = (char) waitKey( 100 );
94
95
            if( code > 0 )
96
                break;
97
98
        }
99
        if( code == 27 || code == 'q' || code == 'Q' )
100
            break;
101
102
    }
103
104
105
    return 0;
106
}
107