Kalman.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "defines.h"
  3. #include <memory>
  4. #include <deque>
  5. #include <opencv2/opencv.hpp>
  6. ///
  7. /// \brief The TKalmanFilter class
  8. /// http://www.morethantechnical.com/2011/06/17/simple-kalman-filter-for-tracking-using-opencv-2-2-w-code/
  9. ///
  10. class TKalmanFilter
  11. {
  12. public:
  13. TKalmanFilter(tracking::KalmanType type, bool useAcceleration, track_t deltaTime, track_t accelNoiseMag);
  14. ~TKalmanFilter() = default;
  15. cv::Point3f GetPointPrediction();
  16. cv::Point3f Update(cv::Point3f pt, bool dataCorrect);
  17. cv::Rect GetRectPrediction();
  18. cv::Rect Update(cv::Rect rect, bool dataCorrect);
  19. Rect3D GetRect3DPrediction();
  20. Rect3D Update(Rect3D rect, bool dataCorrect);
  21. cv::Vec<track_t, 2> GetVelocity() const;
  22. private:
  23. tracking::KalmanType m_type = tracking::KalmanLinear;
  24. cv::KalmanFilter m_linearKalman;
  25. static const size_t MIN_INIT_VALS = 4;
  26. std::deque<cv::Point3f> m_initialPoints;
  27. cv::Point3f m_lastPointResult;
  28. std::deque<cv::Rect> m_initialRects;
  29. cv::Rect_<track_t> m_lastRectResult;
  30. cv::Rect_<track_t> m_lastRect;
  31. std::deque<Rect3D> m_initialRect3Ds;
  32. Rect3D m_lastRect3DResult;
  33. cv::Rect_<track_t> m_lastRect3D;
  34. bool m_initialized = false;
  35. track_t m_deltaTime = 0.2f;
  36. track_t m_deltaTimeMin = 0.2f;
  37. track_t m_deltaTimeMax = 2 * 0.2f;
  38. track_t m_lastDist = 0;
  39. track_t m_deltaStep = 0;
  40. static const int m_deltaStepsCount = 20;
  41. track_t m_accelNoiseMag = 0.5f;
  42. bool m_useAcceleration = false; // If set true then will be used motion model x(t) = x0 + v0 * t + a * t^2 / 2
  43. // Constant velocity model
  44. void CreateLinear(cv::Point3f xy0, cv::Point3f xyv0);
  45. void CreateLinear(cv::Rect_<track_t> rect0, Point_t rectv0);
  46. void CreateLinear3D(Rect3D rect0, cv::Point3f rectv0);
  47. // Constant acceleration model
  48. // https://www.mathworks.com/help/driving/ug/linear-kalman-filters.html
  49. void CreateLinearAcceleration(cv::Point3f xy0, cv::Point3f xyv0);
  50. void CreateLinearAcceleration(cv::Rect_<track_t> rect0, Point_t rectv0);
  51. void CreateLinearAcceleration3D(Rect3D rect0, cv::Point3f rectv0);
  52. };
  53. //---------------------------------------------------------------------------
  54. ///
  55. /// \brief sqr
  56. /// \param val
  57. /// \return
  58. ///
  59. template<class T> inline
  60. T sqr(T val)
  61. {
  62. return val * val;
  63. }
  64. ///
  65. /// \brief get_lin_regress_params
  66. /// \param in_data
  67. /// \param start_pos
  68. /// \param in_data_size
  69. /// \param kx
  70. /// \param bx
  71. /// \param ky
  72. /// \param by
  73. ///
  74. template<typename T, typename CONT>
  75. void get_lin_regress_params(
  76. const CONT& in_data,
  77. size_t start_pos,
  78. size_t in_data_size,
  79. T& kx, T& bx, T& ky, T& by)
  80. {
  81. T m1(0.), m2(0.);
  82. T m3_x(0.), m4_x(0.);
  83. T m3_y(0.), m4_y(0.);
  84. const T el_count = static_cast<T>(in_data_size - start_pos);
  85. for (size_t i = start_pos; i < in_data_size; ++i)
  86. {
  87. m1 += i;
  88. m2 += sqr(i);
  89. m3_x += in_data[i].x;
  90. m4_x += i * in_data[i].x;
  91. m3_y += in_data[i].y;
  92. m4_y += i * in_data[i].y;
  93. }
  94. T det_1 = 1 / (el_count * m2 - sqr(m1));
  95. m1 *= -1;
  96. kx = det_1 * (m1 * m3_x + el_count * m4_x);
  97. bx = det_1 * (m2 * m3_x + m1 * m4_x);
  98. ky = det_1 * (m1 * m3_y + el_count * m4_y);
  99. by = det_1 * (m2 * m3_y + m1 * m4_y);
  100. }