Skip to content

fix(L100-003): remove frame_rate param from ByteTrack, simplify max_time_lost#2206

Open
Zeesejo wants to merge 1 commit intoroboflow:developfrom
Zeesejo:fix/l100-003-bytetrack-frame-rate
Open

fix(L100-003): remove frame_rate param from ByteTrack, simplify max_time_lost#2206
Zeesejo wants to merge 1 commit intoroboflow:developfrom
Zeesejo:fix/l100-003-bytetrack-frame-rate

Conversation

@Zeesejo
Copy link
Copy Markdown

@Zeesejo Zeesejo commented Apr 7, 2026

Description

Fixes #2202

The frame_rate parameter in ByteTrack.__init__ was only ever used in one place:

self.max_time_lost = int(frame_rate / 30.0 * lost_track_buffer)

This was confusing for two reasons:

  1. The hardcoded 30.0 divisor means the parameter doesn't behave as its name implies — changing frame_rate silently scales max_time_lost in a non-obvious way.
  2. The docstring for lost_track_buffer says "Number of frames to buffer when a track is lost", which is inconsistent with the scaled formula.

With the default frame_rate=30, the formula resolves to int(30 / 30.0 * 30) = 30, so max_time_lost was always equal to lost_track_buffer for the vast majority of users.

Changes

  • Removed frame_rate parameter from ByteTrack.__init__.
  • Simplified to self.max_time_lost = lost_track_buffer (same pattern as minimum_consecutive_frames).
  • Updated the class docstring to remove the frame_rate argument entry.

Backward Compatibility

  • Users using defaults (frame_rate=30, lost_track_buffer=30): no behaviour change — max_time_lost stays 30.
  • Users who passed a custom frame_rate: they should now pass the desired frame count directly via lost_track_buffer. This is a breaking change for that subset, but the old API was semantically misleading.

Type of change

  • Bug fix (non-breaking fix for incorrect/misleading behaviour)
  • Breaking change (removes frame_rate parameter)

How Has This Been Tested?

  • Verified that all existing usages in the codebase pass frame_rate=30 (the default) or omit it entirely, meaning max_time_lost is unchanged.
  • No existing tests reference the frame_rate parameter.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have updated the docstring accordingly
  • My changes generate no new warnings

…ime_lost

The frame_rate parameter was only used in a single expression:

    self.max_time_lost = int(frame_rate / 30.0 * lost_track_buffer)

The hardcoded 30.0 divisor made frame_rate confusing: changing it scaled
max_time_lost in a non-obvious way, and the docstring for lost_track_buffer
("Number of frames to buffer when a track is lost") was inconsistent with
the actual scaled behaviour.

Fix:
- Remove frame_rate parameter entirely.
- Set max_time_lost = lost_track_buffer directly (mirrors how
  minimum_consecutive_frames is already handled).
- Update docstring to reflect the correct semantics.

Backward-compatible: users who relied on the default frame_rate=30
get identical max_time_lost values (30/30*30 == 30). Users who passed a
custom frame_rate should migrate to setting lost_track_buffer directly.

Fixes roboflow#2202
@Zeesejo Zeesejo requested a review from SkalskiP as a code owner April 7, 2026 13:23
Copilot AI review requested due to automatic review settings April 7, 2026 13:23
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

Removes the misleading frame_rate argument from supervision.tracker.byte_tracker.core.ByteTrack.__init__ and makes max_time_lost directly equal to lost_track_buffer, aligning the implementation with the documented “frames to buffer” semantics.

Changes:

  • Removed frame_rate from ByteTrack.__init__ and its docstring.
  • Simplified max_time_lost computation to lost_track_buffer.

Comment on lines 42 to 48
def __init__(
self,
track_activation_threshold: float = 0.25,
lost_track_buffer: int = 30,
minimum_matching_threshold: float = 0.8,
frame_rate: int = 30,
minimum_consecutive_frames: int = 1,
):
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

frame_rate is removed from __init__, but there are still in-repo call sites that pass frame_rate= (e.g. src/supervision/detection/tools/smoother.py docstring example and several scripts under examples/). This makes the codebase examples/docs inconsistent and also contradicts the PR description claim that all usages omit frame_rate or use the default. Either update those references in the same PR, or keep frame_rate as a deprecated/ignored parameter that emits SupervisionWarnings guidance to use lost_track_buffer directly.

Copilot uses AI. Check for mistakes.
Comment on lines 52 to 55
self.frame_id = 0
self.det_thresh = self.track_activation_threshold + 0.1
self.max_time_lost = int(frame_rate / 30.0 * lost_track_buffer)
self.max_time_lost = lost_track_buffer
self.minimum_consecutive_frames = minimum_consecutive_frames
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

self.max_time_lost used to be explicitly converted to int(...). With self.max_time_lost = lost_track_buffer, callers who pass a non-int (e.g. track_seconds * fps where track_seconds is a float) will now silently change the type/rounding behavior. Consider normalizing/validating lost_track_buffer (e.g. cast to int and/or reject negative values) so max_time_lost remains an integer frame count as documented.

Copilot uses AI. Check for mistakes.
Comment on lines 42 to 55
def __init__(
self,
track_activation_threshold: float = 0.25,
lost_track_buffer: int = 30,
minimum_matching_threshold: float = 0.8,
frame_rate: int = 30,
minimum_consecutive_frames: int = 1,
):
self.track_activation_threshold = track_activation_threshold
self.minimum_matching_threshold = minimum_matching_threshold

self.frame_id = 0
self.det_thresh = self.track_activation_threshold + 0.1
self.max_time_lost = int(frame_rate / 30.0 * lost_track_buffer)
self.max_time_lost = lost_track_buffer
self.minimum_consecutive_frames = minimum_consecutive_frames
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

This PR changes a public initializer API and alters max_time_lost semantics, but there are no tests asserting the new behavior (e.g. that lost_track_buffer controls removal timing, and/or that passing frame_rate is rejected or produces a deprecation warning). Adding a focused unit test would prevent regressions and clarify the intended contract.

Copilot generated this review using guidance from repository custom instructions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unnecessary frame_rate-parameter in Byte Track

2 participants