OpenShot Library | libopenshot 0.5.0
Loading...
Searching...
No Matches
KalmanTracker.cpp
Go to the documentation of this file.
1// © OpenShot Studios, LLC
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
6// KalmanTracker.cpp: KalmanTracker Class Implementation Declaration
7
8#include "KalmanTracker.h"
9#include <ctime>
10
11using namespace std;
12using namespace cv;
13
14// initialize Kalman filter
15void KalmanTracker::init_kf(
16 StateType stateMat)
17{
18 int stateNum = 8;
19 int measureNum = 4;
20 kf = KalmanFilter(stateNum, measureNum, 0);
21
22 measurement = Mat::zeros(measureNum, 1, CV_32F);
23
24 kf.transitionMatrix = (Mat_<float>(8, 8) << 1, 0, 0, 0, 1, 0, 0, 0,
25
26 0, 1, 0, 0, 0, 1, 0, 0,
27 0, 0, 1, 0, 0, 0, 1, 0,
28 0, 0, 0, 1, 0, 0, 0, 1,
29 0, 0, 0, 0, 1, 0, 0, 0,
30 0, 0, 0, 0, 0, 1, 0, 0,
31 0, 0, 0, 0, 0, 0, 1, 0,
32 0, 0, 0, 0, 0, 0, 0, 1);
33
34 setIdentity(kf.measurementMatrix);
35 setIdentity(kf.processNoiseCov, Scalar::all(1e-1));
36 kf.processNoiseCov.at<float>(2, 2) = 1e0; // higher noise for area (s) to adapt to size changes
37 kf.processNoiseCov.at<float>(3, 3) = 1e0; // higher noise for aspect ratio (r)
38 setIdentity(kf.measurementNoiseCov, Scalar::all(1e-4));
39 setIdentity(kf.errorCovPost, Scalar::all(1e-2));
40
41 // initialize state vector with bounding box in [cx,cy,s,r] style
42 kf.statePost.at<float>(0, 0) = stateMat.x + stateMat.width / 2;
43 kf.statePost.at<float>(1, 0) = stateMat.y + stateMat.height / 2;
44 kf.statePost.at<float>(2, 0) = stateMat.area();
45 kf.statePost.at<float>(3, 0) = stateMat.width / stateMat.height;
46 kf.statePost.at<float>(4, 0) = 0.0f;
47 kf.statePost.at<float>(5, 0) = 0.0f;
48 kf.statePost.at<float>(6, 0) = 0.0f;
49 kf.statePost.at<float>(7, 0) = 0.0f;
50}
51
52// Predict the estimated bounding box.
54{
55 // predict
56 Mat p = kf.predict();
57 m_age += 1;
58
59 if (m_time_since_update > 0)
60 m_hit_streak = 0;
62
63 StateType predictBox = get_rect_xysr(p.at<float>(0, 0), p.at<float>(1, 0), p.at<float>(2, 0), p.at<float>(3, 0));
64
65 m_history.push_back(predictBox);
66 return m_history.back();
67}
68
70{
71 // predict
72 Mat p = kf.predict();
73
74 StateType predictBox = get_rect_xysr(p.at<float>(0, 0), p.at<float>(1, 0), p.at<float>(2, 0), p.at<float>(3, 0));
75
76 return predictBox;
77}
78
79// Update the state vector with observed bounding box.
81 StateType stateMat)
82{
84 m_history.clear();
85 m_hits += 1;
86 m_hit_streak += 1;
87
88 // measurement
89 measurement.at<float>(0, 0) = stateMat.x + stateMat.width / 2;
90 measurement.at<float>(1, 0) = stateMat.y + stateMat.height / 2;
91 measurement.at<float>(2, 0) = stateMat.area();
92 measurement.at<float>(3, 0) = stateMat.width / stateMat.height;
93
94 // update
95 kf.correct(measurement);
96 // time_t now = time(0);
97 // convert now to string form
98
99 // detect_times.push_back(dt);
100}
101
102// Return the current state vector
104{
105 Mat s = kf.statePost;
106 return get_rect_xysr(s.at<float>(0, 0), s.at<float>(1, 0), s.at<float>(2, 0), s.at<float>(3, 0));
107}
108
109// Convert bounding box from [cx,cy,s,r] to [x,y,w,h] style.
111 float cx,
112 float cy,
113 float s,
114 float r)
115{
116 float w = sqrt(s * r);
117 float h = s / w;
118 float x = (cx - w / 2);
119 float y = (cy - h / 2);
120
121 if (x < 0 && cx > 0)
122 x = 0;
123 if (y < 0 && cy > 0)
124 y = 0;
125
126 return StateType(x, y, w, h);
127}
#define StateType
StateType predict()
StateType get_state()
void update(StateType stateMat)
StateType predict2()
StateType get_rect_xysr(float cx, float cy, float s, float r)