(1)获取视频帧
(2)手动获取跟踪目标(鼠标事件处理)
(3)进行kalman跟踪:
状态估计值x --> state;当前观测值z --> measurement;kalman类内成员变量transitionMatrix就是状态转移方程中的矩阵A;kalman类内成员变量measurementMatrix就是量测方程中矩阵H
《1》初始化kalman滤波
const int stateNum=4;
//设置状态变量(x,y,dx,dy)
const int measureNum=2;
//设置观测变量(x,y)
CvKalman* kalman = cvCreateKalman( stateNum, measureNum, 0 );/初始化kalman滤波,其返回值为kalman变量:
CvMat* process_noise = cvCreateMat( stateNum, 1, CV_32FC1 );
//创建4行1列的状态噪声向量
CvMat* measurement = cvCreateMat( measureNum, 1, CV_32FC1 );//创建观测噪声向量
CvRNG rng = cvRNG(-1);
float A[stateNum][stateNum] ={//transition matrix
1,0,1,0,
0,1,0,1,
0,0,1,0,
0,0,0,1
};
//状态转移矩阵
//将状态转移矩阵赋值给kalman
memcpy( kalman->transition_matrix->data.fl,A,sizeof(A));
//cvSetIdentity()将会把数组中除了行数与列数相等以外的所有元素的值都设置为0;行数与列数相等的元素的值都设置为1
//设置观测矩阵就是一个2×2的单位阵,设置kalman的观测矩阵
cvSetIdentity(kalman->measurement_matrix,cvRealScalar(1) );
//设置状态噪声
cvSetIdentity(kalman->process_noise_cov,cvRealScalar(1e-5));
//设置观测噪声
cvSetIdentity(kalman->measurement_noise_cov,cvRealScalar(1e-1));
//设置kalman迭代的误差
cvSetIdentity(kalman->error_cov_post,cvRealScalar(1));
//初始化kalman的状态变量,这个初始化和图像的长宽有关Hei表示图像宽,wid表示图像的高
cvRandArr(&rng,kalman->state_post,CV_RAND_UNI,cvRealScalar(0),cvRealScalar(Hei>Wid?Wid:Hei));
//字体初始化
CvFont font;
cvInitFont(&font,CV_FONT_HERSHEY_PLAIN,1,1);
《2》kalman预测
const CvMat* prediction=cvKalmanPredict(kalman,0);
//获取预测的点坐标,即和测量量相同
CvPoint predict_pt=cvPoint((int)prediction->data.fl[0],(int)prediction->data.fl[1]);
《3》更新量测
从鼠标获取的位置量进行赋值
measurement->data.fl[0]=(float)mousePosition.x;
measurement->data.fl[1]=(float)mousePosition.y;
《4》更新kalman相关变量
cvKalmanCorrect( kalman, measurement );
(4)进行相关的显示表达