kalmanfiltertwod.cc

来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 292 行

CC
292
字号
/*************************************************************** * C++ source * * File : 	KalmanFilter.cc * * Module :	KalmanFilter * * Author : 	A M Baumberg * * Creation Date : Mon Dec  6 12:53:14 1993  * * Comments : 	various Kalman Filter classes * ***************************************************************//* include files */#include <cstdio>#include "KalmanFilterTwoD.h"#include "NagVector.h"#include "NagMatrix.h"#include "text_output.h"namespace ReadingPeopleTracker{StaticKalmanTwoD::StaticKalmanTwoD(realno Qxx, realno Qxy, realno Qyy, 				   realno bx_0, realno by_0,				   realno pxx_0, realno pxy_0, 				   realno pyy_0) :    Q(Qxx, Qxy, Qyy),    b(bx_0, by_0),    old_b(bx_0, by_0),    Cov(pxx_0, pxy_0, pyy_0),    old_Cov(pxx_0, pxy_0, pyy_0){    // nothing}realno StaticKalmanTwoD::delta_update(realno dbx_obs, realno dby_obs,  				      realno rxx, realno rxy, realno ryy){      old_Cov = Cov;    old_b = b;        realno det1 =  Cov.determinant();    if (det1 < 0)    {	cerror << " StaticKalmanTwoD::delta_update(): det Cov < 0, aborting..." << endl;	abort();     }        // if det1 too small, measurement has no effect so return    if (det1 < 1e-30)	return 0;        Matrix2by2 R_inv(rxx,rxy,ryy);    Matrix2by2 tmp_m = Cov.inverse() + R_inv;        realno det2 = tmp_m.determinant();    if (det2 < 0)    {	cerror << " StaticKalmanTwoD::delta_update(): det2 < 0, aborting..." << endl;	abort();    }        Cov = tmp_m.inverse();    Point2 db_obs(dbx_obs, dby_obs);        b += Cov.multiply(db_obs);        Matrix2by2 K_gain = Cov * R_inv;    // return maximum eigenvalue as upper bound on gain    return K_gain.get_max_real_eigenvalue();}Point2 StaticKalmanTwoD::add_observation(Point2 b_obs, Matrix2by2 R){    Matrix2by2 tmp((Cov + R).inverse());    Matrix2by2 K = Cov.multiply(tmp);        Point2 db(b_obs - b);        old_b = b;        b += K.multiply(db);        old_Cov = Cov;        Cov -= K.multiply(old_Cov);        return b;}void StaticKalmanTwoD::update_state(){    Cov = Cov + Q;    old_Cov = Cov;}void StaticKalmanTwoD::remove_last_observation(){    Cov = old_Cov;    b = old_b;}void StaticKalmanTwoD::set_polar_noise_cov(realno sv, realno tv){    realno bx2 = b.x * b.x;    realno by2 = b.y * b.y;    realno bxy = b.x * b.y;    Q = Matrix2by2((bx2 * sv + by2 * tv),		   (bxy * (sv - tv)),		   (by2 * sv + bx2 * tv));}#ifdef _SVID_SOURCE// the following uses SVID 48-bit random numbers...void StaticKalmanTwoD::add_noise(realno var_x, realno var_y){    b.x += sqrt(var_x) * NagVector::normal_random();    b.y += sqrt(var_y) * NagVector::normal_random();    Cov.val00 += var_x;    Cov.val11 += var_y;}#endifrealno StaticKalmanTwoD::get_uncertainty(){     // return maximum eigenvalue of the covariance matrix    // which is a bound on the expected errors    return Cov.get_max_real_eigenvalue();    }// 2D constant velocity discrete Kalman Filter// constructor :// diagonal of system noise passed as (q_x, q_y, q_dx, q_dy)// diagonal of initial covariance passed as //	(var_x, var_y, var_dx, var_dy)// assume all other covariance terms are zero// initial position pos_0// initial velocity vel_0DynamicKalmanTwoD::DynamicKalmanTwoD(realno q_x, realno q_y,				     realno q_dx, realno q_dy,				     Point2 pos_0, Point2 vel_0, 				     realno var_x, realno var_y, 				     realno var_dx, realno var_dy,				     realno del_t) :    Q00(q_x, q_y), Q11(q_dx, q_dy),    C00(var_x, var_y), C11(var_dx, var_dy),    old_C00(var_x, var_y), old_C11(var_dx, var_dy),    pos(pos_0), velocity(vel_0), old_pos(pos_0), old_velocity(vel_0){        t = 0;    dt = del_t;    // nothing left to initialise    }//#ifndef WIN32//inline//#endifvoid DynamicKalmanTwoD::reset_noise_covariance(realno q_x, realno q_y,					       realno q_dx, realno q_dy){    Q00 = Matrix2by2(q_x, q_y);    Q11 = Matrix2by2(q_dx, q_dy);}//// add an observation  ...// pos_obs  	observed value// sensor covariance [ rxx rxy ]//                   [ rxy ryy ]Point2 DynamicKalmanTwoD::add_observation(Point2 pos_obs, realno rxx, 					  realno rxy, realno ryy){    Matrix2by2 R(rxx, rxy, ryy);    Matrix2by2 tmp((C00 + R).inverse());    Matrix2by2 K_pos = C00.multiply(tmp);    Matrix2by2 K_vel = C01.multiply(tmp);        Point2 dp(pos_obs - pos);        old_pos = pos;    old_velocity = velocity;        pos += K_pos.multiply(dp);    velocity += K_vel.multiply(dp);        old_C00 = C00; old_C01 = C01; old_C11 = C11;        C00 -= K_pos.multiply(old_C00);    C01 -= K_pos.multiply(old_C01);    C11 -= K_vel.multiply(old_C01);        return dp;   // FIXME: added by nts 31/10/00  ---  correct???}// delta_update ...// add an observation // with //	delta_pos = ( R^{-1} (pos_obs - pos) ) // and measurement inverse covariance R^{-1} given by////	R^{-1} =	[ rxx rxy ]//			[ rxy ryy ]	// // return the Kalman gainrealno DynamicKalmanTwoD::delta_update(Point2 delta_pos, realno rxx, 				       realno rxy, realno ryy){            Matrix2by2 R_inv(rxx, rxy, ryy);    if (fabs(R_inv.determinant()) < 1e-30) return 0.0;        Matrix2by2 R(R_inv.inverse());        Point2 dp(R.multiply(delta_pos));        Matrix2by2 tmp((C00 + R).inverse());    Matrix2by2 K_pos = C00.multiply(tmp);    Matrix2by2 K_vel = C01.multiply(tmp);        old_pos = pos;    old_velocity = velocity;        pos += K_pos.multiply(dp);    velocity += K_vel.multiply(dp);        old_C00 = C00; old_C01 = C01; old_C11 = C11;        C00 -= K_pos.multiply(old_C00);    C01 -= K_pos.multiply(old_C01);    C11 -= K_vel.multiply(old_C01);        return K_pos.get_max_real_eigenvalue();}//// get_prediction and update estimates ...// delta_t 	time elapsed since last update//Point2 DynamicKalmanTwoD::get_prediction(realno delta_t){    t += delta_t;        pos += delta_t * velocity;    old_pos = pos;        C00 += C01.scale(2 * delta_t) + C11.scale(delta_t * delta_t)	+ Q00.scale(delta_t);    C01 += C11.scale(delta_t);    C11 += Q11.scale(delta_t);        old_C00 = C00; old_C01 = C01; old_C11 = C11;        return pos;}void DynamicKalmanTwoD::remove_last_observation(){    C00 = old_C00; C01 = old_C01; C11 = old_C11;    pos = old_pos; velocity = old_velocity;}realno DynamicKalmanTwoD::get_uncertainty(){    return C00.get_max_real_eigenvalue();}} // namespace ReadingPeopleTracker

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?