Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reid track pruning bug Issue 325 #326

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions norfair/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,13 @@ def hit(self, detection: "Detection", period: int = 1):
self.is_initializing = False
self._acquire_ids()

# Reset reid_hit_counter if we are are successfully tracking this object.
# If hit_counter was 0 when Tracker.update was called and ReID is being used,
# we preemptively set reid_hit_counter to reid_hit_counter_max. But if the object
# is hit, we need to reset it.
if self.hit_counter_is_positive:
self.reid_hit_counter = None

# We use a kalman filter in which we consider each coordinate on each point as a sensor.
# This is a hacky way to update only certain sensors (only x, y coordinates for
# points which were detected).
Expand Down
53 changes: 53 additions & 0 deletions tests/test_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,59 @@ def dist(new_obj, tracked_obj):
assert tracked_objects[0].id != obj_id


def test_reid_hit_counter_reset():
#
# test that reid hit counter resets to None if it had started counting down but
# then the track was hit with an incoming detection
#

# simple reid distance
def dist(new_obj, tracked_obj):
return np.linalg.norm(new_obj.estimate - tracked_obj.estimate)

hit_counter_max = 2
reid_hit_counter_max = 2

tracker = Tracker(
distance_function="euclidean",
distance_threshold=1,
hit_counter_max=hit_counter_max,
initialization_delay=1,
reid_distance_function=dist,
reid_distance_threshold=5,
reid_hit_counter_max=reid_hit_counter_max,
)

# check that hit counters initialize correctly
tracked_objects = tracker.update([Detection(points=np.array([[1, 1]]))])
tracked_objects = tracker.update([Detection(points=np.array([[1, 1]]))])
assert len(tracked_objects) == 1
assert tracked_objects[0].hit_counter == 2
assert tracked_objects[0].reid_hit_counter == None

# check that object is still alive when hit_counter goes to 0
obj_id = tracked_objects[0].id
for _ in range(hit_counter_max):
tracked_objects = tracker.update()
assert len(tracked_objects) == 1
assert tracked_objects[0].hit_counter == 0
assert tracked_objects[0].reid_hit_counter is None

# check that object is alive and reid_hit_counter is None after being matched again
tracked_objects = tracker.update([Detection(points=np.array([[1, 1]]))])
assert len(tracked_objects) == 1
assert tracked_objects[0].hit_counter == 1
assert tracked_objects[0].reid_hit_counter is None

# check that after reid_hit_counter_max more updates, object still exists
for _ in range(reid_hit_counter_max + 2):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+2 because with the bug,

  • After reid_hit_counter_max updates, reid_hit_counter will be 0
  • After reid_hit_counter_max + 1 updates, reid_hit_counter will be -1 but because of the bug, hit_counter will be positive at the end of the update call, so the tracked object will still be returned and alive
  • At the start of the reid_hit_counter_max + 2 update, reid_hit_counter will be -1 and the tracked object will be marked as dead and won't be sent for normal matching

tracked_objects = tracker.update([Detection(points=np.array([[1, 1]]))])
assert len(tracked_objects) == 1
assert tracked_objects[0].hit_counter == 2
assert tracked_objects[0].reid_hit_counter is None
assert tracked_objects[0].id == obj_id


# TODO tests list:
# - detections with different labels
# - partial matches where some points are missing
Expand Down