How to Tune IoU and Confidence Thresholds for Different Tracking Scenarios in BoxMOT
BoxMOT exposes detection confidence (conf/det_thresh) and IoU thresholds through CLI flags, tracker configuration files, and Ray Tune search spaces, letting you optimize tracking for crowded scenes, high-speed motion, or sparse environments.
The ability to tune IoU and confidence thresholds is essential for adapting multi-object trackers to diverse real-world conditions. In the mikel-brostrom/boxmot repository, these parameters control everything from which detections enter the tracking pipeline to how strictly bounding boxes must overlap for identity association. Understanding where these thresholds live in the source code enables precise calibration for any scenario, from drone aerial views to dense pedestrian crowds.
Where Thresholds Are Defined in the Code
BoxMOT separates threshold logic across three layers: CLI parsing for immediate runtime adjustments, tracker initialization for algorithm-specific defaults, and YAML configuration files for systematic hyper-parameter searches.
Detection Confidence Parameters
The detection confidence threshold filters which bounding boxes from the detector proceed to tracking. Two related parameters control this:
--confinboxmot/engine/cli.py(lines 58–60): Sets the minimum detector confidence score at the CLI level. Default is0.01, acting as a permissive first filter.det_threshinboxmot/trackers/basetracker.py(lines 16–20): Initialized inBaseTracker.__init__, this parameter typically defaults to0.3and represents the tracker's internal confidence gate. Higher values discard low-quality detections to reduce false positives, while lower values increase recall for small or distant objects.
IoU Thresholds for NMS and Data Association
BoxMOT uses IoU thresholds in two distinct stages: suppressing duplicate detections (NMS) and linking detections to existing tracks (association).
--iouinboxmot/engine/cli.py(lines 60–62): Controls the NMS IoU threshold with a default of0.7. Lower values (e.g.,0.5) keep more overlapping boxes, which helps in crowded scenes, whereas higher values aggressively merge duplicates.iou_threshin tracker configs (e.g.,boxmot/configs/trackers/deepocsort.yaml, lines 16–20): Defines the association IoU threshold for matching detections to tracks. TheBaseTrackerclass receives this asiou_thresholdand passes it to theAssociationFunctioninboxmot/utils/iou.py. Lowering this value (e.g., to0.2) allows tracks to survive larger motion gaps or occlusion, while raising it (e.g., to0.4) reduces ID switches by requiring stricter spatial overlap.
Manual Threshold Tuning via CLI
For quick experimentation, override thresholds directly when running the track command. The --conf flag adjusts the detector's output, while --iou modifies NMS behavior. To override tracker-specific thresholds like det_thresh or iou_thresh without editing files, use the --opt flag, which forwards arbitrary keyword arguments to the tracker constructor via a SimpleNamespace.
# Stricter detection confidence and looser NMS for crowded scenes
uv run python -m boxmot.engine.cli track \
--source videos/street.mp4 \
--conf 0.15 \
--iou 0.6 \
--tracking-method deepocsort \
--opt det_thresh=0.25 iou_thresh=0.4
In this example, --conf 0.15 filters weak detections before they reach the tracker, while --iou 0.6 allows more overlapping boxes to survive NMS. The --opt parameters override the default det_thresh and iou_thresh values defined in deepocsort.yaml.
Systematic Hyper-Parameter Optimization
For production deployments, manual tuning is insufficient. BoxMOT integrates Ray Tune to search the optimal threshold space automatically based on MOT metrics like HOTA and MOTA.
Editing Tracker Configuration Files
Each tracker stores its tunable parameters in boxmot/configs/trackers/<method>.yaml. Edit the det_thresh and iou_thresh entries to define search distributions:
# boxmot/configs/trackers/deepocsort.yaml
det_thresh:
type: uniform
default: 0.4
range: [0.2, 0.6]
iou_thresh:
type: uniform
default: 0.35
range: [0.2, 0.5]
The tuner.py script converts these YAML blocks into Ray Tune search spaces using yaml_to_search_space, sampling values across the defined ranges during optimization.
Running the Tune Command
Execute the built-in tune command to evaluate threshold combinations across your validation set:
uv run python -m boxmot.engine.cli tune \
--tracking-method deepocsort \
--yolo-model weights/yolov8s.pt \
--reid-model weights/osnet_x0_25_msmt17.pt \
--n-trials 50 \
--objectives HOTA MOTA
This pipeline generates detections and embeddings, creates MOT challenge format results, and runs TrackEval for each trial. The best configuration—including optimized det_thresh and iou_thresh values—is saved to runs/ray/<method>_tune/result_0/params.yaml. You can then load these parameters back into inference:
import yaml
from pathlib import Path
best_cfg_path = Path("runs/ray/deepocsort_tune/result_0/params.yaml")
with open(best_cfg_path) as f:
best_cfg = yaml.safe_load(f)
# Use best_cfg['det_thresh'] and best_cfg['iou_thresh'] in subsequent runs
Scenario-Specific Tuning Recommendations
Different tracking environments require distinct threshold trade-offs between precision and recall.
| Scenario | Recommended conf / det_thresh |
Recommended NMS iou |
Recommended Association iou_thresh |
|---|---|---|---|
| Sparse traffic, low-resolution | 0.1 (keep weak detections) |
0.7 (strict NMS) |
0.4 (allow larger motion) |
| Crowded pedestrian street | 0.2 (higher recall) |
0.5 (allow overlaps) |
0.25 (tolerant association) |
| High-speed sports (e.g., basketball) | 0.15 (moderate recall) |
0.6 (balance duplicates) |
0.35 (medium strictness) |
| Drone aerial view, small objects | 0.05 (permissive) |
0.6 (allow overlaps) |
0.2 (very tolerant for occlusions) |
In crowded scenes, lower the NMS IoU to prevent suppression of overlapping legitimate objects, and relax the association IoU to maintain identities through occlusion. For high-speed motion, balance the detection threshold to avoid missing fast-moving targets while keeping association strict enough to prevent switches.
Summary
- Detection confidence is controlled by
--conf(CLI) anddet_thresh(tracker config), filtering which boxes enter the tracking pipeline. - NMS IoU (
--iou) suppresses duplicate detections before tracking, while association IoU (iou_threshin YAML) determines detection-to-track matching criteria. - Manual tuning uses CLI flags and
--optfor rapid iteration, while systematic tuning leverages Ray Tune viaboxmot/engine/tuner.pyand tracker YAML files. - Lower thresholds increase recall for crowded or fast-moving scenarios; higher thresholds improve precision and reduce ID switches in sparse, static environments.
Frequently Asked Questions
What is the difference between --conf and det_thresh in BoxMOT?
The --conf flag sets the detector's minimum confidence score (default 0.01), filtering raw model outputs before they reach the tracker. The det_thresh parameter (default 0.3) is an additional filter applied inside the tracker class during BaseTracker.__init__. According to the mikel-brostrom/boxmot source code, raising det_thresh specifically helps reduce false positive tracks, while --conf primarily reduces the computational load by discarding weak detections early.
How do I prevent ID switches in crowded scenes?
Lower the association iou_thresh in your tracker configuration (e.g., to 0.2 or 0.25) and reduce the NMS --iou value (e.g., to 0.5 or 0.6). As implemented in boxmot/utils/iou.py, the association function uses this threshold to link detections to existing tracks. A lower value allows tracks to survive temporary occlusions or large frame-to-frame movements without switching identities, though it may increase the risk of incorrect merges.
Can I tune thresholds without editing YAML files?
Yes. Use the --opt flag in the CLI to pass arbitrary key-value pairs directly to the tracker constructor. For example, --opt det_thresh=0.25 iou_thresh=0.4 overrides the defaults in boxmot/trackers/basetracker.py and the tracker's specific config without modifying disk files. This approach is useful for quick A/B testing but does not support systematic searches like the Ray Tune integration.
Where does BoxMOT store the best thresholds after tuning?
After running boxmot tune, Ray Tune writes the optimal hyper-parameters to runs/ray/<tracker_name>_tune/result_0/params.yaml. This file contains the sampled values for det_thresh, iou_thresh, and other optimized variables. You can load this YAML in Python or pass the values via --opt to standard tracking runs for production deployment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →