Skip to content

Evaluate

Use eval to score tracking runs on MOT-style datasets with BoxMOT's in-repo MOT metrics.

Examples

Example

boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker boosttrack --verbose
from boxmot import BoxMOT

boxmot = BoxMOT(detector="yolov8n", reid="lmbn_n_duke", tracker="boosttrack")
metrics = boxmot.val(experiment="mot17-ablation-yolox-lmbn")
print(metrics)

Use a model-free dataset profile when the detector and ReID models should come from the CLI options or runtime defaults instead of an experiment:

boxmot eval --dataset mot17 --split ablation --tracker boosttrack

--dataset and --experiment are mutually exclusive. An experiment selected with --experiment remains the reproducible option when detector, ReID, and detection-source choices must be fixed by configuration.

Typical workflow

Example

For repeated experiments:

boxmot generate --experiment mot17-ablation-yolox-lmbn
boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker boosttrack

This lets eval reuse precomputed detections and embeddings.

from boxmot import BoxMOT

boxmot = BoxMOT(detector="yolov8n", reid="lmbn_n_duke", tracker="boosttrack")
metrics = boxmot.val(experiment="mot17-ablation-yolox-lmbn")
print(metrics)

Public detections

Select an experiment whose detections.source is public:

boxmot eval --experiment mot17-ablation-frcnn-lmbn --tracker boosttrack
boxmot eval --experiment mot17-ablation-sdp-lmbn --tracker boosttrack
boxmot eval --experiment mot17-ablation-dpm-lmbn --tracker boosttrack

The selected experiment identifies the public source in the central artifact profile. The compatibility option --detection-source accepts public or private, but a source-specific experiment ID is the reproducible way to choose FRCNN, SDP, or DPM.

See Experiment Workflows for details on how public detections are resolved.

Kalman filter noise tuning

Use --tune-kf to estimate per-sequence Kalman filter process and measurement noise (Q/R matrices) from the cached detections and ground truth before tracking:

boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker boosttrack --tune-kf

This is most useful for trackers with Kalman-filter-based motion models. It requires cached detections and ground truth to be available.

For runtime adaptation without ground truth, boosttrack and occluboost expose the adaptive_kf tracker setting, which estimates noise online via the Mehra (1970) method. It is a tracker configuration value, not a CLI flag. For example, the Python facade can override it directly:

from boxmot import BoxMOT

boxmot = BoxMOT(
    detector="yolov8n",
    reid="lmbn_n_duke",
    tracker="boosttrack",
    tracker_kwargs={"adaptive_kf": True},
)
metrics = boxmot.val(experiment="mot17-ablation-yolox-lmbn")

Compare with TrackEval

Install the optional TrackEval reference implementation and request an independent comparison:

uv sync --extra cpu --extra yolo --extra trackeval
boxmot eval --experiment mot17-ablation-yolox-lmbn \
  --tracker boosttrack \
  --compare-trackeval

The report shows BoxMOT's in-repo metrics followed by Δ vs TrackEval rows. TrackEval reads the generated MOT files and runs its own MOTChallenge preprocessing, including distractor removal. This comparison currently supports AABB MOT15, MOT16, MOT17, and MOT20 benchmarks.

Postprocessing

Example

eval can apply optional postprocessing before scoring. Multiple steps can be chained with commas and are applied sequentially to the same result files:

# Single step
boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker boosttrack --postprocessing gsi

# Chained: GSI runs first, then GTA reads GSI's output
boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker boosttrack --postprocessing gsi,gta

Available steps:

Step Description
gsi Gaussian-smoothed interpolation — fills gaps and smooths trajectories
gbrc Gradient-boosting reconnection — ML-based interpolation and smoothing
gta Global tracklet association — offline split-and-connect across the full sequence

BoxMOT.val(...) is the Python-facing validation entry point. Postprocessing details and metric interpretation are the same as in the CLI evaluation pipeline.

Chained steps overwrite in place

When chaining multiple postprocessing steps, each step reads the MOT result files, transforms them, and writes back to the same directory. The second step operates on the output of the first.

See Evaluation and Postprocessing.

See Experiment Workflows for cache reuse, MMOT experiment IDs, and replay image-loading behavior.

Native C++ replay

Use --tracker-backend cpp to run the cached replay stage through a native tracker implementation:

boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker bytetrack --tracker-backend cpp
boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker ocsort --tracker-backend cpp

Native replay is currently available for botsort, bytetrack, ocsort, occluboost, and sfsort. Select the implementation with the separate --tracker-backend option; tracker names do not accept a :cpp suffix.

Main outputs

  • combined benchmark metrics such as HOTA, MOTA, and IDF1
  • per-sequence summaries
  • optional runtime timing summary with --show-timing
  • MOT-style tracker outputs
  • reused cache paths and evaluation artifacts in the run directory

See Evaluation and Postprocessing.

CLI Arguments

boxmot eval

Evaluate tracking performance

Usage:

boxmot eval [OPTIONS]

Options:

Name Type Description Default
--experiment text experiment id or YAML file, e.g. mot17-ablation-yolox-lmbn or boxmot/configs/experiments/mot17/ablation-yolox-lmbn.yaml None
--dataset text dataset id or YAML file, e.g. mot17 or boxmot/configs/datasets/mot17.yaml; uses the selected/default detector and ReID model None
--split text Dataset split to use (e.g. train, val, test, ablation). Overrides auto-detection from source path. None
--detection-source choice (public | private) Detection source: "public" reads det/det.txt from sequences, "private" (default) runs the configured detector model. None
--tracking-backend choice (process | thread | cpp) Cached replay executor for eval/tune/research. Use 'cpp' as a compatibility alias for '--tracker-backend cpp'. process
--tracker-backend choice (python | cpp) Tracker implementation backend. Native 'cpp' is available for botsort, bytetrack, occluboost, ocsort, and sfsort. python
--imgsz text Image size for model input as H,W (e.g. 800,1440) or single int for square. Default: read from the selected detector config, otherwise use detector-specific defaults. None
--fps integer range (1 and above) frame-rate override: saved track video FPS or evaluation target FPS None
--conf float Min confidence threshold. Default: read from the selected detector config, fallback 0.01. None
--iou float IoU threshold for NMS 0.7
--device text cuda device(s), e.g. 0 or 0,1,2,3 or cpu cpu
--batch-size integer micro-batch size for batched detection/embedding 16
--auto-batch / --no-auto-batch boolean probe GPU memory with a dummy pass to pick a safe batch size True
--resume / --no-resume boolean resume detection/embedding generation from progress checkpoints True
--n-threads integer range (1 and above) Maximum CPU worker budget for image decoding and cached tracking 4
--project Path save results to project/name runs
--name text save results to project/name exp
--exist-ok boolean existing project/name ok, do not increment False
--half boolean use FP16 half-precision inference False
--vid-stride integer video frame-rate stride 1
--ci boolean reuse existing runs in CI (no UI) False
--tracker text one of: strongsort, ocsort, bytetrack, sfsort, botsort, deepocsort, hybridsort, boosttrack, occluboost, sam2mot bytetrack
--verbose boolean print detailed logs False
--show-timing / --hide-timing boolean print runtime timing summary after evaluation False
--agnostic-nms boolean class-agnostic NMS False
--postprocessing text Postprocess tracker output (comma-separated, applied in order): none gsi
--show boolean display tracking in a window False
--show-labels / --hide-labels boolean show or hide detection labels True
--show-conf / --hide-conf boolean show or hide detection confidences True
--show-trajectories boolean overlay past trajectories False
--show-kf-preds boolean show Kalman-filter predictions False
--save-txt boolean save results to a .txt file False
--save-crop boolean save cropped detections False
--save boolean save annotated video False
--line-width integer bounding box line width None
--per-class boolean track each class separately False
--target-id integer ID to highlight in green None
--masks-dir text Override directory for cached segmentation masks (.npz files) None
--masks-model choice (maskrcnn) Mask model to use for generation (stored under cache tree automatically) None
--detector Path one or more YOLO weights for detection [PosixPath('/home/runner/work/boxmot/boxmot/models/yolov8n.pt')]
--reid Path one or more ReID model weights [PosixPath('/home/runner/work/boxmot/boxmot/models/osnet_x0_25_msmt17.pt')]
--classes text filter by class indices, e.g. 0 or "0,1" None
--tune-kf / --no-tune-kf boolean Run KF noise tuning (Q/R estimation) before tracking. Automatically selects parameterization based on the tracker. Requires cached dets and GT. False
--compare-trackeval / --no-compare-trackeval boolean Compare BoxMOT metrics against TrackEval for an AABB MOTChallenge benchmark. False
--help boolean Show this message and exit. False