Skip to content

fix(bytetrack): prune unmatched tracks after kalman refactor#376

Merged
Borda merged 7 commits into
roboflow:developfrom
omkar-334:fix/bytetrack-prune-after-refactor
Apr 27, 2026
Merged

fix(bytetrack): prune unmatched tracks after kalman refactor#376
Borda merged 7 commits into
roboflow:developfrom
omkar-334:fix/bytetrack-prune-after-refactor

Conversation

@omkar-334
Copy link
Copy Markdown
Contributor

@omkar-334 omkar-334 commented Apr 26, 2026

What does this PR do?

Add parametrized regression tests across SORT, ByteTrack, and OCSORT covering three contracts every tracker must satisfy after the recent kalman/tracklet refactor (#310):
1. A confirmed track is pruned after lost_track_buffer + N empty frames.
2. time_since_update advances when a track is not matched in a frame.
3. A confirmed track survives a short occlusion (a few empty frames well below the lost-track buffer).

These tests pass on SORT and OCSORT. On ByteTrack, two of them fail: the tracker never calls tracklet.update(None) on tracks unmatched in either association pass, so time_since_update stays at 0 and
_get_alive_tracklets never sees an expired track.

Related Issue(s):

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Testing

  • I have tested this change locally
  • I have added/updated tests for this change

Test details:

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code where necessary, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have updated the documentation accordingly (if applicable)

omkar-334 and others added 2 commits April 26, 2026 19:30
@omkar-334 omkar-334 requested a review from SkalskiP as a code owner April 26, 2026 14:03
@omkar-334
Copy link
Copy Markdown
Contributor Author

omkar-334 commented Apr 26, 2026

@Borda the tests were failing earlier - f74ada7.
After I added the fixes for bytetrack, they're passing. However, the metrics for Bytetrack have now changed because of this fix.. what do you think?
I discovered this while working on #373 - the tests i had originall written in that PR were failing after rebasing on the refactor PR.

@omkar-334
Copy link
Copy Markdown
Contributor Author

omkar-334 commented Apr 26, 2026

PR #310 noted two deliberate behavioural changes for ByteTrack:

  1. switching maturity to number_of_successful_consecutive_updates,
  2. changing the tracklet init value.

This PR addresses two regressions that were not part of #310's stated intent:

  • update(None) was no longer being called on unmatched ByteTrack tracks, so time_since_update never advanced and tracks were never pruned. SORT was updated for the same refactor; ByteTrack was missed.

  • Once update(None) is correctly called, the consecutive_updates-based maturity check from Feat/core/refactor tracklet kalman filter #310 un-confirms a confirmed track on its first missed frame, breaking short-occlusion handling. The original ByteTrack paper's confirmed-track state is sticky: a Tracked track moves to Lost (not back to Tentative) on a miss and stays Lost through lost_track_buffer. We restore that with a sticky tracker_id != -1 signal alongside the bootstrap consecutive_updates check, so first confirmation still requires consecutive matches.

I'm a bit confused. Was this change intentional, or really a bug?
cc @AlexBodner

@omkar-334 omkar-334 mentioned this pull request Apr 26, 2026
7 tasks
@AlexBodner
Copy link
Copy Markdown
Collaborator

Good catch. The 1. switching maturity to number_of_successful_consecutive_updates was intended, but we seem to have introduced these bugs by no updating with None and by no checking track_id!=-1. For merging we need to rollback the numbers assigned to bytetrack in the documentation, (though its interesting that we've got better results)
@Borda

@Borda Borda added the bug Something isn't working label Apr 27, 2026
Comment thread test/core/test_tracker_pruning.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds cross-tracker regression coverage for track pruning semantics after the Kalman/tracklet refactor (#310), and fixes ByteTrack’s missed-frame accounting so expired tracks are actually pruned.

Changes:

  • Add parametrized pruning/occlusion regression tests that apply to SORT, ByteTrack, and OC-SORT.
  • Fix ByteTrack to call tracklet.update(None) for tracks unmatched after both association passes, ensuring time_since_update advances and tracks expire.
  • Adjust ByteTrack “alive tracklet” maturity logic to treat confirmation as sticky (based on assigned tracker_id), and update stored expected benchmark outputs.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
trackers/core/bytetrack/utils.py Makes “confirmed/mature” status sticky by using tracker_id != -1 as the confirmation signal.
trackers/core/bytetrack/tracker.py Advances time_since_update for tracks unmatched after both passes via update(None) to enable pruning.
trackers/core/base.py Adds a base-level tracks type annotation to formalize the common tracker surface.
test/data/tracker_expected_sportsmot.json Updates ByteTrack expected benchmark metrics after the behavioral fix.
test/data/tracker_expected_dancetrack.json Updates ByteTrack expected benchmark metrics after the behavioral fix.
test/core/test_tracker_pruning.py Introduces regression tests for pruning, missed-frame advancement, and short-occlusion survival across trackers.

Comment thread trackers/core/bytetrack/utils.py Outdated
Comment thread trackers/core/base.py
Comment thread test/core/test_tracker_pruning.py Outdated
omkar-334 and others added 3 commits April 27, 2026 18:04
Reflect corrected benchmark numbers across bytetrack.md and comparison.md.

Made-with: Cursor
@AlexBodner
Copy link
Copy Markdown
Collaborator

@Borda with the discussed changes applied, the PR LGTM

@Borda Borda merged commit a07ba38 into roboflow:develop Apr 27, 2026
16 checks passed
@Borda Borda mentioned this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants