-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathtest_tracker.py
More file actions
139 lines (112 loc) · 4.57 KB
/
test_tracker.py
File metadata and controls
139 lines (112 loc) · 4.57 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from collections import Counter
import numpy as np
import pytest
from motpy import ModelPreset
from motpy.core import Detection, setup_logger
from motpy.testing import data_generator
from motpy.tracker import (IOUAndFeatureMatchingFunction, MultiObjectTracker,
exponential_moving_average_fn, match_by_cost_matrix)
from numpy.testing import assert_almost_equal, assert_array_equal
logger = setup_logger(__name__)
USE_SIMPLE_TRACKER = -1
@pytest.mark.parametrize("num_objects", [2, 5])
@pytest.mark.parametrize("order_pos", [USE_SIMPLE_TRACKER, 0, 1, 2])
@pytest.mark.parametrize("feature_similarity_beta", [None, 0.5])
def test_simple_tracking_objects(
num_objects: int,
order_pos: int,
feature_similarity_beta: float,
fps: int = 24,
num_steps: int = 240):
gen = data_generator(
num_steps=num_steps,
miss_prob=0.2,
det_err_sigma=3.0,
num_objects=num_objects,
max_omega=0.01)
dt = 1 / fps
num_steps_warmup = 1.0 * fps # 1 second of warmup
if order_pos == USE_SIMPLE_TRACKER:
model_spec = None
else:
model_spec = {'order_pos': order_pos, 'dim_pos': 2, 'order_size': 0, 'dim_size': 2}
matching_fn = IOUAndFeatureMatchingFunction(feature_similarity_beta=feature_similarity_beta)
mot = MultiObjectTracker(
dt=dt,
model_spec=model_spec,
matching_fn=matching_fn)
history = {idx: [] for idx in range(num_objects)}
for i in range(num_steps):
dets_gt, dets_pred = next(gen)
detections = [d for d in dets_pred if d.box is not None]
_ = mot.step(detections=detections)
if i <= num_steps_warmup:
continue
matches = match_by_cost_matrix(mot.trackers, dets_gt)
for m in matches:
gidx, tidx = m[0], m[1]
track_id = mot.trackers[tidx].id
history[gidx].append(track_id)
assert len(mot.trackers) == num_objects
count_frames = (num_steps - num_steps_warmup)
for gid in range(num_objects):
c = Counter(history[gid])
count_tracked = c.most_common(1)[0][1]
logger.info('object %d mostly tracked in %.1f%% frames' %
(gid, (100.0 * count_tracked / count_frames)))
assert count_tracked > 0.95 * count_frames
def test_tracker_diverges():
box = np.array([0, 0, 10, 10])
mot = MultiObjectTracker(dt=0.1)
mot.step([Detection(box=box)])
assert len(mot.trackers) == 1
first_track_id = mot.active_tracks()[0].id
# check if dt is propagated to single object tracker
assert_almost_equal(mot.trackers[0].model.dt, 0.1)
# check valid tracker
assert not mot.trackers[0].is_invalid()
mot.trackers[0]._tracker.x[2] = np.nan
assert mot.trackers[0].is_invalid()
mot.cleanup_trackers()
assert len(mot.trackers) == 0
# pass invalid box
mot.step([Detection(box=box)])
assert len(mot.trackers) == 1
assert mot.active_tracks()[0].id != first_track_id
def test_tracker_det_indices():
mot = MultiObjectTracker(dt=5)
box0 = np.array([0, 0, 10, 10])
box1 = np.array([20, 20, 30, 30])
mot.step([Detection(box=box) for box in [box0, box1]])
track_ids = [t.id for t in mot.active_tracks()]
assert len(track_ids) == 2
_, indices = mot.active_tracks(return_indices=True)
assert indices == [0, 1]
mot.step([Detection(box=box) for box in [box1, box0]])
assert track_ids == [t.id for t in mot.active_tracks()]
track_ids_idx, indices = mot.active_tracks(return_indices=True)
assert track_ids == [t.id for t in track_ids_idx]
assert indices == [1, 0]
mot.step([Detection(box=box) for box in []])
_, indices = mot.active_tracks(return_indices=True)
assert indices == [-1, -1]
def test_class_smoothing():
box = np.array([0, 0, 10, 10])
mot = MultiObjectTracker(dt=0.1)
mot.step([Detection(box=box, class_id=1)])
mot.step([Detection(box=box, class_id=2)])
mot.step([Detection(box=box, class_id=2)])
assert mot.trackers[0].class_id == 2
mot.step([Detection(box=box, class_id=1)])
mot.step([Detection(box=box, class_id=1)])
assert mot.trackers[0].class_id == 1
def test_exponential_moving_average():
update_fn = exponential_moving_average_fn(0.5)
# scalars
assert update_fn(None, 100.) == 100.
assert update_fn(50., None) == 50.
assert update_fn(50., 100.) == 75.
# sequences
assert_array_equal(update_fn(None, [100., 50]), [100., 50])
assert_array_equal(update_fn([80., 50], None), [80., 50])
assert_array_equal(update_fn(np.array([80., 100]), [90, 90]), [85., 95])