fix(io): reject duplicate per-frame track ids - #562
Draft
AlexBodner wants to merge 1 commit into
Draft
Conversation
CLEAR, HOTA and Identity all accumulate per-id counts with fancy-indexed `+=`, which NumPy buffers instead of adding: `counts[[1, 1, 2]] += 1` leaves 1 at index 1, not 2. A track id repeated inside one frame therefore deflates the very totals the metrics divide by, and every reported number comes back quietly wrong. `_prepare_mot_sequence` now rejects a repeated id, matching TrackEval, which raises on the same input. The check runs after filtering, so the two legitimate cases still pass: ids on rows dropped as ignored or non-pedestrian, and unconfirmed detections that all share id -1. Guarding in sequence preparation covers all three metric families at one chokepoint rather than patching each accumulation site. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Rejects malformed MOT input containing duplicate per-frame track IDs before metric evaluation.
Changes:
- Adds per-frame uniqueness validation after relevant filtering.
- Adds coverage for duplicates, repeated cross-frame IDs, filtered IDs, and unconfirmed IDs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/trackers/io/mot.py |
Validates unique ground-truth and tracker IDs per frame. |
tests/io/test_mot.py |
Tests duplicate rejection and valid exceptions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
CLEAR, HOTA and Identity all accumulate per-id counts with fancy-indexed
+=, which NumPy buffers instead of adding:A track id repeated inside one frame therefore deflates the very totals the metrics divide by, and every reported number comes back quietly wrong.
Fix
_prepare_mot_sequencerejects a repeated id. TrackEval raises on the same input, so this matches the reference.The check runs after filtering, so the two legitimate cases still pass:
-1and are expected to repeatTests
-1ids are allowed.tests/io,tests/evalandtests/tunepass at 138.Notes
Guarding in sequence preparation covers all three metric families at one chokepoint rather than patching each accumulation site in
clear.py,hota.pyandidentity.py. Switching those tonp.add.atwould make duplicates count correctly instead of rejecting them, but duplicate ids in a frame are malformed input, and TrackEval treats them as an error too.Made with Cursor