#include "cv.h" #include "highgui.h" #include <math.h> int main(int argc, char** argv) { /* A matrix data */ const float A[] = { 1, 1, 0, 1 }; IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); CvKalman* kalman = cvCreateKalman( 2, 1, 0 );//分配 Kalman 滤波器结构 /* state is (phi, delta_phi) - angle and angle increment */ CvMat* state = cvCreateMat( 2, 1, CV_32FC1 ); CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 ); /* only phi (angle) is measured */ CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 ); CvRandState rng;////产生随机结构数组 int code = -1; cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );// 初始化结构数字 cvZero( measurement ); cvNamedWindow( "Kalman", 1 ); for(;;) { cvRandSetRange( &rng, 0, 0.1, 0 ); rng.disttype = CV_RAND_NORMAL;//上边设置rng为CV_RAND_NORMAL状态 cvRand( &rng, state ); memcpy( kalman->transition_matrix->data.fl, A, sizeof(A)); cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );//初始化带尺度的单位矩阵 cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) ); cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) ); cvSetIdentity( kalman->error_cov_post, cvRealScalar(1)); /* choose random initial state */ cvRand( &rng, kalman->state_post ); rng.disttype = CV_RAND_NORMAL; for(;;) { #define calc_point(angle) \ cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \ cvRound(img->height/2 - img->width/3*sin(angle))) float state_angle = state->data.fl[0]; CvPoint state_pt = calc_point(state_angle); /* predict point position */ const CvMat* prediction = cvKalmanPredict( kalman, 0 ); float predict_angle = prediction->data.fl[0]; CvPoint predict_pt = calc_point(predict_angle); float measurement_angle; CvPoint measurement_pt; cvRandSetRange( &rng, 0, sqrt(kalman->measurement_noise_cov->data.fl[0]), 0 ); cvRand( &rng, measurement ); /* generate measurement */ cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement ); measurement_angle = measurement->data.fl[0]; measurement_pt = calc_point(measurement_angle); /* plot points */ #define draw_cross( center, color, d ) \ cvLine( img, cvPoint( center.x - d, center.y - d ), \ cvPoint( center.x + d, center.y + d ), color, 1, 0 ); \ cvLine( img, cvPoint( center.x + d, center.y - d ), \ cvPoint( center.x - d, center.y + d ), color, 1, 0 ) cvZero( img ); draw_cross( state_pt, CV_RGB(255,255,255), 3 ); draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ); draw_cross( predict_pt, CV_RGB(0,255,0), 3 ); cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 ); /* adjust Kalman filter state */ cvKalmanCorrect( kalman, measurement );//调节模型状态 cvRandSetRange( &rng, 0, sqrt(kalman->process_noise_cov->data.fl[0]), 0 ); cvRand( &rng, process_noise ); cvMatMulAdd( kalman->transition_matrix, state, process_noise, state ); cvShowImage( "Kalman", img ); code = cvWaitKey( 100 ); if( code > 0 ) /* break current simulation by pressing a key */ break; } if( code == 27 ) /* exit by ESCAPE */ break; } return 0; }
第二个:
#include "cv.h" #include "highgui.h" #include <math.h> int main(int argc, char** argv) { cvNamedWindow( "Kalman", 1 );//创建窗口,当为的时候,表示窗口大小自动设定 CvRandState rng; cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );/* CV_RAND_UNI 指定为均匀分布类型、随机数种子为-1 */ IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); CvKalman* kalman = cvCreateKalman( 2, 1, 0 );/*状态向量为维,观测向量为维,无激励输入维*/ // State is phi, delta_phi - angle and angular velocity // Initialize with random guess CvMat* x_k = cvCreateMat( 2, 1, CV_32FC1 );/*创建行列、元素类型为CV_32FC1,元素为位单通道浮点类型矩阵。*/ cvRandSetRange( &rng, 0, 0.1, 0 );/*设置随机数范围,随机数服从正态分布,均值为,均方差为.1,通道个数为*/ rng.disttype = CV_RAND_NORMAL; cvRand( &rng, x_k ); /*随机填充数组*/ // Process noise CvMat* w_k = cvCreateMat( 2, 1, CV_32FC1 ); // Measurements, only one parameter for angle CvMat* z_k = cvCreateMat( 1, 1, CV_32FC1 );/*定义观测变量*/ cvZero( z_k ); /*矩阵置零*/ // Transition matrix F describes model parameters at and k and k+1 const float F[] = { 1, 1, 0, 1 }; /*状态转移矩阵*/ memcpy( kalman->transition_matrix->data.fl, F, sizeof(F)); /*初始化转移矩阵,行列,具体见CvKalman* kalman = cvCreateKalman( 2, 1, 0 );*/ // Initialize other Kalman parameters cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );/*观测矩阵*/ cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) );/*过程噪声*/ cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) );/*观测噪声*/ cvSetIdentity( kalman->error_cov_post, cvRealScalar(1) );/*后验误差协方差*/ // Choose random initial state cvRand( &rng, kalman->state_post );/*初始化状态向量*/ // Make colors CvScalar yellow = CV_RGB(255,255,0);/*依次为红绿蓝三色*/ CvScalar white = CV_RGB(255,255,255); CvScalar red = CV_RGB(255,0,0); while( 1 ){ // Predict point position const CvMat* y_k = cvKalmanPredict( kalman, 0 );/*激励项输入为*/ // Generate Measurement (z_k) cvRandSetRange( &rng, 0, sqrt( kalman->measurement_noise_cov->data.fl[0] ), 0 );/*设置观测噪声*/ cvRand( &rng, z_k ); cvMatMulAdd( kalman->measurement_matrix, x_k, z_k, z_k ); // Update Kalman filter state cvKalmanCorrect( kalman, z_k ); // Apply the transition matrix F and apply "process noise" w_k cvRandSetRange( &rng, 0, sqrt( kalman->process_noise_cov->data.fl[0] ), 0 );/*设置正态分布过程噪声*/ cvRand( &rng, w_k ); cvMatMulAdd( kalman->transition_matrix, x_k, w_k, x_k ); // Plot Points cvZero( img );/*创建图像*/ // Yellow is observed state 黄色是观测值 //cvCircle(IntPtr, Point, Int32, MCvScalar, Int32, LINE_TYPE, Int32) //对应于下列其中,shift为数据精度 //cvCircle(img, center, radius, color, thickness, lineType, shift) //绘制或填充一个给定圆心和半径的圆 cvCircle( img, cvPoint( cvRound(img->width/2 + img->width/3*cos(z_k->data.fl[0])), cvRound( img->height/2 - img->width/3*sin(z_k->data.fl[0])) ), 4, yellow ); // White is the predicted state via the filter cvCircle( img, cvPoint( cvRound(img->width/2 + img->width/3*cos(y_k->data.fl[0])), cvRound( img->height/2 - img->width/3*sin(y_k->data.fl[0])) ), 4, white, 2 ); // Red is the real state cvCircle( img, cvPoint( cvRound(img->width/2 + img->width/3*cos(x_k->data.fl[0])), cvRound( img->height/2 - img->width/3*sin(x_k->data.fl[0])) ), 4, red ); CvFont font; cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5f,0.5f,0,1,8); cvPutText(img,"Yellow:observe",cvPoint(0,20),&font,cvScalar(0,0,255)); cvPutText(img,"While:predict",cvPoint(0,40),&font,cvScalar(0,0,255)); cvPutText(img,"Red:real",cvPoint(0,60),&font,cvScalar(0,0,255)); cvPutText(img,"Press Esc to Exit...",cvPoint(0,80),&font,cvScalar(255,255,255)); cvShowImage( "Kalman", img ); // Exit on esc key if(cvWaitKey(100) == 27) break; } cvReleaseImage(&img);/*释放图像*/ cvReleaseKalman(&kalman);/*释放kalman滤波对象*/ cvDestroyAllWindows();/*释放所有窗口*/ return 0; }