1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | #include "cv.h"
|
14 | #include "highgui.h"
|
15 |
|
16 | using namespace cv;
|
17 |
|
18 |
|
19 | Point calc_point(Mat& img, double angle) {
|
20 | int x = round(img.cols/2 + img.rows/3*cos(angle));
|
21 | int y = round(img.cols/2 - img.rows/3*sin(angle));
|
22 | return Point(x, y);
|
23 | };
|
24 |
|
25 |
|
26 | void draw_cross(Mat& img, Point center, Scalar color, int d) {
|
27 | line(img, Point(center.x - d, center.y - d),
|
28 | Point(center.x + d, center.y + d), color, 1, CV_AA, 0);
|
29 | line(img, Point(center.x + d, center.y - d),
|
30 | Point(center.x - d, center.y + d), color, 1, CV_AA, 0);
|
31 | };
|
32 |
|
33 |
|
34 | int main (int argc, char * const argv[]) {
|
35 | Mat img = Mat(500, 500, CV_8UC3);
|
36 | KalmanFilter kalman = KalmanFilter(2, 1, 0);
|
37 | Mat state = Mat(2, 1, CV_32FC1);
|
38 | Mat process_noise = Mat(2, 1, CV_32FC1);
|
39 | Mat measurement = Mat(1, 1, CV_32FC1);
|
40 | Mat measurement_noise = Mat(1, 1, CV_32FC1);
|
41 |
|
42 | measurement.setTo(Scalar(0));
|
43 | namedWindow("kalman", 1);
|
44 |
|
45 | float m[2][2] = {{1, 1}, {0, 1}};
|
46 | kalman.transitionMatrix = Mat(2, 2, CV_32FC1, m);
|
47 |
|
48 | setIdentity(kalman.measurementMatrix, Scalar(1));
|
49 | setIdentity(kalman.processNoiseCov, Scalar(1e-5));
|
50 | setIdentity(kalman.measurementNoiseCov, Scalar(1e-1));
|
51 | setIdentity(kalman.errorCovPost, Scalar(1));
|
52 |
|
53 | int code = -1;
|
54 |
|
55 | while (true) {
|
56 | randu(state, Scalar(0), Scalar(0.1));
|
57 | randu(kalman.statePost, Scalar(0), Scalar(0.1));
|
58 |
|
59 | while (true) {
|
60 | img.setTo(Scalar(0));
|
61 |
|
62 | float state_angle = state.at<float>(0,0);
|
63 | Point state_pt = calc_point(img, state_angle);
|
64 |
|
65 |
|
66 | Mat prediction = kalman.predict();
|
67 | float predict_angle = prediction.at<float>(0, 0);
|
68 | Point predict_pt = calc_point(img, predict_angle);
|
69 |
|
70 |
|
71 | randn(measurement_noise, Scalar(0), Scalar(sqrt(kalman.measurementNoiseCov.at<float>(0, 0))));
|
72 | measurement = kalman.measurementMatrix * state + measurement_noise;
|
73 |
|
74 | float measurement_angle = measurement.at<float>(0, 0);
|
75 | Point measurement_pt = calc_point(img, measurement_angle);
|
76 |
|
77 |
|
78 | line(img, state_pt, measurement_pt, CV_RGB(255, 0,0), 3, CV_AA, 0);
|
79 | line(img, state_pt, predict_pt, CV_RGB(255, 255, 0), 3, CV_AA, 0);
|
80 | draw_cross(img, state_pt, CV_RGB(255, 255, 255), 3);
|
81 | draw_cross(img, measurement_pt, CV_RGB(255, 0,0), 3);
|
82 | draw_cross(img, predict_pt, CV_RGB(0, 255, 0), 3);
|
83 |
|
84 |
|
85 | kalman.correct(measurement);
|
86 |
|
87 |
|
88 | randn(process_noise, Scalar(0), Scalar(sqrt(kalman.processNoiseCov.at<float>(0, 0))));
|
89 | state = kalman.transitionMatrix * state + process_noise;
|
90 |
|
91 | imshow("kalman", img);
|
92 | code = waitKey(100);
|
93 | if (code > -1)
|
94 | break;
|
95 | };
|
96 |
|
97 | if (code == 27 || code == 113 || code == 65617)
|
98 | break;
|
99 | };
|
100 | }; |