-
Notifications
You must be signed in to change notification settings - Fork 903
/
example_17-01.cpp
106 lines (85 loc) · 3 KB
/
example_17-01.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Example 17-1. Kalman filter example code
#include <vector>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <opencv2/opencv.hpp>
using std::cout;
using std::endl;
#define phi2xy(mat) \
cv::Point(cvRound(img.cols / 2 + img.cols / 3 * cos(mat.at<float>(0))), \
cvRound(img.rows / 2 - img.cols / 3 * sin(mat.at<float>(0))))
void help(char** argv ) {
cout << "\n"
<< "Example 17-1: code for using cv::KalmanFilter\n"
<< argv[0] << "\n\n"
<< "For example:\n"
<< argv[0] <<"\n\n"
<< "Esc to quit\n"
<< endl;
}
int main(int argc, char** argv) {
help(argv);
// Initialize, create Kalman filter object, window, random number
// generator etc.
//
cv::Mat img(500, 500, CV_8UC3);
cv::KalmanFilter kalman(2, 1, 0);
// state is (phi, delta_phi) - angle and angular velocity
// Initialize with random guess.
//
cv::Mat x_k(2, 1, CV_32F);
randn(x_k, 0.0, 0.1);
// process noise
//
cv::Mat w_k(2, 1, CV_32F);
// measurements, only one parameter for angle
//
cv::Mat z_k = cv::Mat::zeros(1, 1, CV_32F);
// Transition matrix 'F' describes relationship between
// model parameters at step k and at step k+1 (this is
// the "dynamics" in our model.
//
float F[] = {1, 1, 0, 1};
kalman.transitionMatrix = cv::Mat(2, 2, CV_32F, F).clone();
// Initialize other Kalman filter parameters.
//
cv::setIdentity(kalman.measurementMatrix, cv::Scalar(1));
cv::setIdentity(kalman.processNoiseCov, cv::Scalar(1e-5));
cv::setIdentity(kalman.measurementNoiseCov, cv::Scalar(1e-1));
cv::setIdentity(kalman.errorCovPost, cv::Scalar(1));
// choose random initial state
//
randn(kalman.statePost, 0.0, 0.1);
for (;;) {
// predict point position
//
cv::Mat y_k = kalman.predict();
// generate measurement (z_k)
//
cv::randn(z_k, 0.0,
sqrt(static_cast<double>(kalman.measurementNoiseCov.at<float>(0, 0))));
z_k = kalman.measurementMatrix*x_k + z_k;
// plot points (e.g., convert
//
img = cv::Scalar::all(0);
cv::circle(img, phi2xy(z_k), 4, cv::Scalar(128, 255, 255)); // observed
cv::circle(img, phi2xy(y_k), 4, cv::Scalar(255, 255, 255), 2); // predicted
cv::circle(img, phi2xy(x_k), 4, cv::Scalar(0, 0, 255)); // actual to
// planar co-ordinates and draw
cv::imshow("Kalman", img);
// adjust Kalman filter state
//
kalman.correct(z_k);
// Apply the transition matrix 'F' (e.g., step time forward)
// and also apply the "process" noise w_k
//
cv::randn(w_k, 0.0, sqrt(static_cast<double>(kalman.processNoiseCov.at<float>(0, 0))));
x_k = kalman.transitionMatrix*x_k + w_k;
// exit if user hits 'Esc'
if ((cv::waitKey(100) & 255) == 27) {
break;
}
}
return 0;
}