kalmanfilteroned.cc
来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 352 行
CC
352 行
/*************************************************************** * 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 <cstdio>#include "KalmanFilterOneD.h"#include "NagVector.h"#include "NagMatrix.h"#include "text_output.h"namespace ReadingPeopleTracker{//#define USE_OVERWEIGHTING1#define USE_OVERWEIGHTING2//#define USE_OVERWEIGHTING3StaticKalmanOneD::StaticKalmanOneD(realno Q, realno r_0, realno b_0, realno p11_0, realno eps){ q = Q; old_p11 = p11 = p11_0; old_b = b = b_0; def_r = r_0; epsilon = eps; }realno StaticKalmanOneD::update_state(){ realno new_p11 = p11 + q; old_p11 = p11 = new_p11; old_b = b; return b;}realno StaticKalmanOneD::add_observation(realno b_obs, realno r){ old_b = b; old_p11 = p11; b_obs -= b; realno denom = p11 + r; #ifdef USE_OVERWEIGHTING2 b += ((p11 + epsilon * epsilon * r) / denom) * b_obs; p11 = ((p11 + epsilon * epsilon * r) * r) / denom; // realno gain1 = p11 / denom;// realno gain2 = q / (q + r);// realno gain = gain1 + epsilon * gain2;// b += gain * b_obs;// p11 = gain * r; #else b += (1.0 + epsilon) * (p11 / denom) * b_obs; p11 = (1.0 + epsilon) * (p11 * r) / denom;#endif return b;}realno StaticKalmanOneD::delta_update(realno delta_b, realno inv_r){ if (inv_r == 0) return 0; old_b = b; old_p11 = p11; realno denom = 1 + p11 * inv_r; #ifdef USE_OVERWEIGHTING2 p11 = ((p11 + (epsilon * epsilon / inv_r))) / denom; // realno method1 = p11 / (1.0 + p11 * inv_r);// realno method2 = q / (1.0 + q * inv_r); // p11 = (1 /* - epsilon */) * method1 + epsilon * method2; #else p11 = (p11 / denom);#endif b += p11 * delta_b; return p11 * inv_r; }void StaticKalmanOneD::remove_last_observation(){ b = old_b; p11 = old_p11;}#ifdef _SVID_SOURCE// the following uses SVID 48-bit random numbers...void StaticKalmanOneD::add_noise(realno var){ b += sqrt(var) * NagVector::normal_random(); p11 += var;}#endifDynamicKalmanOneD::DynamicKalmanOneD(realno Q11, realno Q12, realno Q22, realno r_0, realno b_0, realno db_0, realno p11_0, realno p12_0, realno p22_0 , realno delta_t, realno eps){ q11 = Q11; q12 = Q12; q22 = Q22; old_p11 = p11 = p11_0; old_p12 = p12 = p12_0; old_p22 = p22 = p22_0; dt = delta_t; old_b = b = b_0; old_db = db = db_0; def_r = r_0; t = 0; epsilon = eps; }realno DynamicKalmanOneD::get_prediction(realno delta_t){ b += delta_t * db; t += delta_t; realno new_p11 = p11 + delta_t * (2 * p12 + delta_t * p22) + delta_t * q11; realno new_p12 = p12 + (delta_t * p22) + delta_t * q12; realno new_p22 = p22 + (delta_t * q22); old_p11 = p11 = new_p11; old_p12 = p12 = new_p12; old_p22 = p22 = new_p22; old_b = b; old_db = db; return b;}realno DynamicKalmanOneD::add_observation(realno b_obs, realno r){ old_b = b; old_db =db; old_p11 = p11; old_p12 = p12; old_p22 = p22; b_obs -= b; realno denom = p11 + r; #ifdef USE_OVERWEIGHTING1 b += ((p11 + epsilon * epsilon * r) / denom) * b_obs; b += (p11 / denom) * b_obs; db += (p12 / denom) * b_obs; realno new_p11 = ((p11 + epsilon * epsilon * r) * r) / denom; // realno gain1 = p11 / denom;// realno q_pos = 0.5 * q22 * dt * dt * dt;// realno gain2 = q_pos / (q_pos + r);// realno gain = gain1 + epsilon * gain2;// b += gain * b_obs;// db += (p12 / denom) * b_obs; // realno new_p11 = r * gain; #else b += (1.0 + epsilon) * (p11 / denom) * b_obs; db += (1.0 + epsilon) * (p12 / denom) * b_obs; realno new_p11 = (p11 * r) / denom; #endif realno new_p12 = (p12 * r) / denom; realno new_p22 = p22 - ((p12 * p12) / denom); p11 = new_p11; p12 = new_p12; p22 = new_p22; return b;}realno DynamicKalmanOneD::delta_update(realno delta_b, realno inv_r){ if (inv_r == 0) return 0; old_b = b; old_db = db; old_p11 = p11; old_p12 = p12; old_p22 = p22; realno denom = 1 + p11 * inv_r; p22 -= (p12 * p12 * inv_r) / denom; p12 /= denom; #ifdef USE_OVERWEIGHTING1 p11 = (p11 / denom) + (epsilon * epsilon) / (inv_r * denom);// realno method1 = p11 / (1.0 + p11 * inv_r);// realno q_pos = 0.5 * q22 * dt * dt * dt;// realno method2 = q_pos / (1.0 + q_pos * inv_r); // p11 = (1 /* - epsilon */) * method1 + epsilon * method2; #else p11 = (p11 / denom);#endif b += p11 * delta_b; db += p12 * delta_b; // return the Kalman gain for parameter 'b' return p11 * inv_r; }void DynamicKalmanOneD::remove_last_observation(){ b = old_b; db = old_db; p11 = old_p11; p12 = old_p12; p22 = old_p22;}#ifdef _SVID_SOURCE// the following uses SVID 48-bit random numbers...void DynamicKalmanOneD::add_noise(realno var){ b += sqrt(var) * NagVector::normal_random(); p11 += var;}#endifVibrationFilter::VibrationFilter(realno Q11, realno Q12, realno Q22, realno pass_a, realno pass_b, realno r_0, realno x_0, realno dx_0, realno p11_0, realno p12_0, realno p22_0, realno delta_t){ q11 = Q11; q12 = Q12; q22 = Q22; a = pass_a; b = pass_b; p11 = p11_0; p12 = p12_0; p22 = p22_0; dt = delta_t; x = x_0; bias = x_p = 0; dx = dx_0; def_r = r_0; t = 0; }// assume delta_t is small// the exact solution exists in terms of exponentials// too difficult for the moment!realno VibrationFilter::get_prediction(realno delta_t){// bias += 0.1 * (x - x_p); NagMatrix thi(2,2); NagVector new_x(2); NagVector old_x(2); thi.set(0,0,1); thi.set(0,1,delta_t); thi.set(1,0, a * delta_t); thi.set(1,1,1 + b * delta_t); old_x[0] = x; old_x[1] = dx; thi.multiply(old_x, new_x); x = new_x[0]; dx = new_x[1] - thi.read(1,0) * bias; NagMatrix tmp_P(2,2); NagMatrix tmp_Q(2,2); NagMatrix new_P; tmp_P.set(0,0,p11); tmp_P.set(0,1,p12); tmp_P.set(1,0,p12); tmp_P.set(1,1,p22); tmp_Q.set(0,0,q11); tmp_Q.set(0,1,q12); tmp_Q.set(1,0,q12); tmp_Q.set(1,1,q22); tmp_P.ortho_transform(thi, new_P, false); tmp_Q.scale(delta_t, tmp_Q); new_P.add(tmp_Q, new_P); p11 = new_P.read(0,0); p12 = new_P.read(0,1); p22 = new_P.read(1,1); t += delta_t; x_p = x; return x;}realno VibrationFilter::add_observation(realno x_obs, realno r){ x_obs -= x; realno denom = p11 + r; x += (p11 / denom) * x_obs; dx += (p12 / denom) * x_obs; realno new_p11 = (p11 * r) / denom; realno new_p12 = (p12 * r) / denom; realno new_p22 = p22 - ((p12 * p12) / denom); p11 = new_p11; p12 = new_p12; p22 = new_p22; return x;}realno VibrationFilter::delta_update(realno delta_x, realno inv_r){ if (inv_r == 0) return 0; realno denom = 1 + p11 * inv_r; p22 -= (p12 * p12 * inv_r) / denom; p12 /= denom; p11 = (p11 / denom); x += p11 * delta_x; dx += p12 * delta_x; // return the Kalman gain for 'x' return p11 * inv_r; }} // namespace ReadingPeopleTracker
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?