-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmultiTracker.cpp
More file actions
117 lines (103 loc) · 3.37 KB
/
multiTracker.cpp
File metadata and controls
117 lines (103 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "multiTracker.hpp"
/* MultiTracker::MultiTracker(...) {{{*/
/* Tracker. Manage tracks. Create, remove, update. */
MultiTracker::MultiTracker(
float dt,
float accelNoiseMag,
float distThres,
int maximumAllowedSkippedFrames,
int maxTraceLength
)
:
dt( dt ),
accelNoiseMag( accelNoiseMag ),
distThres( distThres ),
maximumAllowedSkippedFrames( maximumAllowedSkippedFrames ),
maxTraceLength( maxTraceLength )
{
this->NextTrackID = 0;
}
/* }}} */
/* void MultiTracker::update( const vector<cv::Point2f> &detections ) {{{*/
void MultiTracker::update( const vector<cv::Point2f> &detections )
{
/* If there is no tracks yet, then every cv::Point begins its own track. */
if ( tracks.size() == 0 )
{
/* If no tracks yet */
for ( uint i = 0; i < detections.size(); i++ )
{
tracks.push_back( Tracker( detections[i], dt, accelNoiseMag, NextTrackID++ ) );
}
}
int N = tracks.size();
int M = detections.size();
vector<int> assignment;
if ( tracks.empty() == false )
{
vector<float> Cost( N * M );
for ( uint i = 0; i < tracks.size(); i++ )
{
for ( uint j = 0; j < detections.size(); j++ )
{
Cost[i + j * N] = tracks[i].calcDist( detections[j] );
}
}
/* Solving assignment problem (tracks and predictions of Kalman filter) */
assignmentProblemSolver APS( N, M );
APS.Solve( Cost );
assignment = APS.getAssignment();
/* clean assignment from pairs with large distance */
for ( uint i = 0; i < assignment.size(); i++ )
{
if ( assignment[i] != -1 )
{
if ( Cost[i + assignment[i] * N] > distThres )
{
assignment[i] = -1;
tracks[i].skippedFrames = 1;
}
}
else
{
// If track have no assigned detect, then increment skipped frames counter.
tracks[i].skippedFrames++;
}
}
/* If track didn't get detects long time, remove it. */
for ( uint i = 0; i < tracks.size(); i++ )
{
if ( tracks[i].skippedFrames > maximumAllowedSkippedFrames )
{
tracks.erase( tracks.begin() + i );
assignment.erase( assignment.begin() + i );
i--;
}
}
}
/* Search for unassigned detects and start new tracks for them. */
for ( uint i = 0; i < detections.size(); ++i )
{
if ( find( assignment.begin(), assignment.end(), i ) == assignment.end() )
{
tracks.push_back( Tracker( detections[i], dt, accelNoiseMag, NextTrackID++ ) );
}
}
/* Update Kalman Filters state */
for ( uint i = 0; i < assignment.size(); i++ )
{
/* If track updated less than one time, than filter state is not correct. */
/* If we have assigned detect, then update using its coordinates */
if ( assignment[i] != -1 )
{
tracks[i].skippedFrames = 0;
tracks[i].update( detections[assignment[i]], true, maxTraceLength );
}
/* if not continue using predictions */
else
{
tracks[i].update( cv::Point2f(), false, maxTraceLength );
}
}
}
/* }}} */