OpenCV使い始めて8年.
最初の頃はIntel Primitive Library(IPL)とか
Intel Performance Primitives(IPP)とか,
Intelのライブラリが必須だったのに,
いつの間にかそいつらは不要になって単体で
動くようになったOpenCVも今は2.1がリリース
されちゃってます.
2.1で特質すべきはC++の実装があること.
CvSeq*とかCvMat*とかポインタのお化けプログラムから
おさらばしたくてC++のOpenCVにチャレンジしてますが,
サンプルが不足してて苦戦します.
今日はkalman filterのサンプルをC++実装に置き換えて
みたので調子にのってブログにアップしちゃいます.
と言っても100%C++ライクになっているかといえば
嘘で行列周りでCvMatに戻ったりしてますがその辺は
許してください.
C++にしてよかったと思えるのは今のところ行列の計算
だけですね.
13 | #define CV_NO_BACKWARD_COMPATIBILITY |
18 | int main( int argc, char ** argv) |
20 | const float A[] = { 1, 1, 0, 1 }; |
21 | Mat img(500, 500, CV_8UC3); |
22 | KalmanFilter kalman(2, 1, 0); |
23 | Mat state(2, 1, CV_32FC1); |
24 | Mat process_noise(2, 1, CV_32FC1); |
25 | Mat measurement(1, 1, CV_32FC1); |
29 | namedWindow( "kalman" , 1); |
32 | rng.fill(state, CV_RAND_NORMAL, Scalar(0), Scalar(0.1)); |
33 | CvMat transition_matrix = kalman.transitionMatrix; |
34 | memcpy (transition_matrix.data.fl, A, sizeof (A)); |
35 | CvMat measurement_matrix = kalman.measurementMatrix; |
36 | cvSetIdentity(&measurement_matrix, cvRealScalar(1) ); |
37 | CvMat process_noise_cov = kalman.processNoiseCov; |
38 | cvSetIdentity(&process_noise_cov, cvRealScalar(1e-5) ); |
39 | CvMat measurement_noise_cov = kalman.measurementNoiseCov; |
40 | cvSetIdentity(&measurement_noise_cov, cvRealScalar(1e-1) ); |
41 | CvMat error_cov_post = kalman.errorCovPost; |
42 | cvSetIdentity(&error_cov_post, cvRealScalar(1)); |
43 | rng.fill(kalman.statePost, CV_RAND_NORMAL, Scalar(0), Scalar(0.1)); |
46 | #define calc_point(angle) \ |
47 | cvPoint( cvRound(img.cols/2 + img.cols/3* cos (angle)), \ |
48 | cvRound(img.rows/2 - img.rows/3* sin (angle))) |
49 | float state_angle = state.at< float >(0,0); |
50 | CvPoint state_pt = calc_point(state_angle); |
51 | Mat prediction = kalman.predict(); |
52 | float predict_angle = prediction.at< float >(0, 0); |
53 | CvPoint predict_pt = calc_point(predict_angle); |
54 | float measurement_angle; |
55 | CvPoint measurement_pt; |
56 | rng.fill(measurement, CV_RAND_NORMAL, Scalar(0), Scalar( sqrt (kalman.measurementNoiseCov.at< float >(0,0)))); |
59 | measurement = kalman.measurementMatrix * state + measurement; |
60 | measurement_angle = measurement.at< float >(0,0); |
61 | measurement_pt = calc_point(measurement_angle); |
64 | #define draw_cross( center, color, d ) \ |
65 | line(img, Point( center.x - d, center.y - d ), \ |
66 | Point( center.x + d, center.y + d ), color, 1, CV_AA, 0); \ |
67 | line(img, Point( center.x + d, center.y - d ), \ |
68 | Point( center.x - d, center.y + d ), color, 1, CV_AA, 0 ) |
72 | draw_cross( state_pt, CV_RGB(255,255,255), 3 ); |
73 | draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ); |
74 | draw_cross( predict_pt, CV_RGB(0,255,0), 3 ); |
75 | line(img, state_pt, measurement_pt, CV_RGB(255,0,0), 3, CV_AA, 0 ); |
76 | line(img, state_pt, predict_pt, CV_RGB(255,255,0), 3, CV_AA, 0 ); |
77 | kalman.correct(measurement); |
78 | rng.fill(process_noise, CV_RAND_NORMAL, Scalar(0), Scalar( sqrt (kalman.processNoiseCov.at< float >(0,0)))); |
79 | state = kalman.transitionMatrix * state + process_noise; |
80 | imshow( "kalman" , img); |
81 | code = ( char ) cvWaitKey( 100 ); |
85 | if ( code == 27 || code == 'q' || code == 'Q' ) |
88 | cvDestroyWindow( "Kalman" ); |
91 | float >float >float >float >float >
|