Skip to content

Commit 1bc1138

Browse files
Bordaclaude
andcommitted
add stage2_min_updates gate to stage-2 (default=0 disabled)
- Mature-track-only stage-2: only tracks with >= N updates participate in low-conf recovery - Neutral at N=0,1; regresses at N>=2 — ghost exclusion hurts legitimate young tracks - Added to Optuna search space [0, 5] for future joint optimisation --- Co-authored-by: Claude Code <noreply@anthropic.com>
1 parent 14cb36c commit 1bc1138

4 files changed

Lines changed: 24 additions & 2 deletions

File tree

autotrack/default_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"max_interpolation_gap": 32,
1818
"p_reset_threshold": 26,
1919
"oru_threshold": 14,
20-
"conf_cost_weight": 0.0
20+
"conf_cost_weight": 0.0,
21+
"stage2_min_updates": 0
2122
},
2223
"sort": {
2324
"lost_track_buffer": 30,

autotrack/optimize_tracking.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def _build_tracker(params: dict, tracker_name: str):
186186
iou_age_weight=params["iou_age_weight"],
187187
high_conf_det_threshold=params["high_conf_det_threshold"],
188188
conf_cost_weight=params.get("conf_cost_weight", 0.0),
189+
stage2_min_updates=params.get("stage2_min_updates", 0),
189190
)
190191
if tracker_name == "sort":
191192
from trackers import SORTTracker

autotrack/search_space.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@
9292
"type": "float",
9393
"low": 0.0,
9494
"high": 1.0
95+
},
96+
"stage2_min_updates": {
97+
"type": "int",
98+
"low": 0,
99+
"high": 5
95100
}
96101
},
97102
"sort": {

trackers/core/bytetrack/tracker.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def __init__(
8383
iou_age_weight: float = 0.03,
8484
high_conf_det_threshold: float = 0.6,
8585
conf_cost_weight: float = 0.0,
86+
stage2_min_updates: int = 0,
8687
) -> None:
8788
# Calculate maximum frames without update based on lost_track_buffer and
8889
# frame_rate. This scales the buffer based on the frame rate to ensure
@@ -95,6 +96,7 @@ def __init__(
9596
self.track_activation_threshold = track_activation_threshold
9697
self.high_conf_det_threshold = high_conf_det_threshold
9798
self.conf_cost_weight = conf_cost_weight
99+
self.stage2_min_updates = stage2_min_updates
98100
self.tracks: list[ByteTrackKalmanBoxTracker] = []
99101

100102
def update(
@@ -187,7 +189,20 @@ def update(
187189
out_det_indices.append(int(high_indices[col]))
188190
out_tracker_ids.append(track.tracker_id)
189191

190-
remaining_tracks = [self.tracks[i] for i in unmatched_tracks]
192+
# Stage-2 maturity gate: only established tracks participate in low-conf
193+
# recovery. Young tracks (number_of_successful_updates < stage2_min_updates)
194+
# are excluded to prevent tentative ghost tracks from being incorrectly
195+
# recovered via low-confidence detections. When stage2_min_updates == 0
196+
# (default) all unmatched tracks participate, preserving the original behaviour.
197+
if self.stage2_min_updates > 0:
198+
remaining_tracks = [
199+
self.tracks[i]
200+
for i in unmatched_tracks
201+
if self.tracks[i].number_of_successful_updates
202+
>= self.stage2_min_updates
203+
]
204+
else:
205+
remaining_tracks = [self.tracks[i] for i in unmatched_tracks]
191206

192207
# Step 2: associate low-confidence detections to remaining tracks
193208
iou_matrix = get_iou_matrix(remaining_tracks, low_boxes)

0 commit comments

Comments
 (0)