BoxMOT: Pluggable Python and C++ SOTA multi-object tracking modules with support for axis-aligned and oriented bounding boxes
See the code
Pluggable Python and C++ multi-object tracking modules for axis-aligned and oriented bounding box detections from any model.
Docs • Installation • Modes • API Reference • Trackers • Contributing

BoxMOT provides independent detector, segmentor, appearance-encoder, and tracker components built around validated Torch structures. Pipelines compose those components; the CLI owns sources, outputs, materialized datasets, evaluation, tuning, research, and ReID workflows.
track, materialize, materialize --time-variant, eval,
tune, research, train-reid, eval-reid, compare-reid, export,
export-edgetam, install, and native build workflows.--tracker-backend cpp and embeddable in standalone C++ projects via CMake (see Native C++ Integration).BoxMOT supports Python 3.10 through 3.13.
pip install boxmot
boxmot --help
The default package uses the standard PyPI PyTorch build. Source checkouts and
CI can explicitly select the lockfile-backed cpu or cu130 profile. For
those profiles and mode-specific extras such as yolo, service, evolve,
research, onnx, openvino, and tflite, see the
installation guide.
| Tracker key | Status | MOT17 ablation | SportsMOT val | MMOT OBB test | OBB | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| HOTA | MOTA | IDF1 | HOTA | MOTA | IDF1 | HOTA | MOTA | IDF1 | |||
| occluboost | ✅ | 71.10 (71.10) | 78.50 (78.50) | 85.28 (85.28) | 83.17 | 97.48 | 89.36 | 49.84 (49.84) | 39.41 (39.41) | 58.60 (58.60) | ✅ |
| botsort | ✅ | 69.68 (69.74) | 78.23 (78.27) | 82.33 (82.55) | 76.93 | 98.11 | 78.30 | 52.31 (52.40) | 45.43 (45.53) | 61.42 (61.42) | ✅ |
| boosttrack | ✅ | 69.25 (—) | 75.91 (—) | 83.20 (—) | 76.32 | 97.08 | 77.82 | 48.39 (—) | 41.36 (—) | 56.36 (—) | ✅ |
| strongsort | ✅ | 68.05 (—) | 76.19 (—) | 80.76 (—) | 79.80 | 97.31 | 80.27 | 49.76 (—) | 43.70 (—) | 57.32 (—) | ✅ |
| deepocsort | ✅ | 67.95 (—) | 75.83 (—) | 80.54 (—) | 79.51 | 97.94 | 79.59 | 50.84 (—) | 44.21 (—) | 59.33 (—) | ✅ |
| bytetrack | ✅ | 67.68 (67.68) | 78.04 (78.04) | 79.16 (79.16) | 67.93 | 97.25 | 76.90 | 33.97 (33.97) | 33.72 (33.72) | 39.74 (39.74) | ✅ |
| hybridsort | ✅ | 67.31 (—) | 74.09 (—) | 78.87 (—) | 81.14 | 98.07 | 81.88 | 54.64 (—) | 47.50 (—) | 64.67 (—) | ✅ |
| ocsort | ✅ | 66.44 (66.44) | 74.55 (74.55) | 77.90 (77.90) | 76.34 | 96.60 | 75.64 | 28.64 (28.64) | 26.17 (26.17) | 30.06 (30.06) | ✅ |
| sfsort | ✅ | 62.65 (62.65) | 76.87 (76.87) | 69.18 (69.18) | 75.73 | 98.39 | 72.99 | 47.83 (47.83) | 45.42 (45.42) | 52.09 (52.09) | ✅ |
Scores are Python first and C++ in parentheses.
MMOT reported metrics are 'class average'. See Experiment Workflows for details.
Related guides:
CLI:
boxmot track --detector yolo26n --reid lmbn_n_duke --tracker occluboost \
--source 0 --save --show
Evaluate a tracker:
boxmot eval \
--dataset mot17 \
--split ablation \
--detector yolox-x-mot17 \
--reid lmbn-n-duke \
--tracker botsort
See the evaluation guide for --fps and
--calibrate-kf usage.
For saved KITTI predictions, choose the inputs your tracker needs:
boxmot eval --experiment kitti-mots/2d \
--data-root ./kitti-mots --tracker ocsort --cache-inputs
boxmot eval --experiment kitti-mots/full \
--data-root ./kitti-mots --tracker eagermot --cache-inputs
Both experiments reference the same kitti-mots.yaml inventory. The first
selects 2D boxes; the second adds masks, 3D boxes,
calibration, and camera poses. See KITTI experiments.
Use NumPy detections and BGR images directly:
import numpy as np
from boxmot import OccluBoost
tracker = OccluBoost()
dets = np.array([[100, 200, 300, 400, 0.9, 0]])
frame = np.zeros((480, 640, 3), dtype=np.uint8) # BGR image
tracks = tracker.update(dets, frame)
print(tracks[:, 4].astype(int)) # track IDs
# OBB: (cx, cy, w, h, angle in radians, confidence, class_id)
# tracker = OccluBoost(is_obb=True)
# dets = np.array([[200, 300, 200, 100, np.pi / 6, 0.9, 0]])
# tracks = tracker.update(dets, frame)
# print(tracks[:, 5].astype(int)) # track IDs
Start with CONTRIBUTING.md and the contributor docs.
box-mot@outlook.com to discuss your project.box-mot@outlook.com(top 30 of 44)
Python
95.2%
C++
4.6%
BoxMOT: Pluggable Python and C++ SOTA multi-object tracking modules with support for axis-aligned and oriented bounding boxes
See the code
Pluggable Python and C++ multi-object tracking modules for axis-aligned and oriented bounding box detections from any model.
Docs • Installation • Modes • API Reference • Trackers • Contributing

BoxMOT provides independent detector, segmentor, appearance-encoder, and tracker components built around validated Torch structures. Pipelines compose those components; the CLI owns sources, outputs, materialized datasets, evaluation, tuning, research, and ReID workflows.
track, materialize, materialize --time-variant, eval,
tune, research, train-reid, eval-reid, compare-reid, export,
export-edgetam, install, and native build workflows.--tracker-backend cpp and embeddable in standalone C++ projects via CMake (see Native C++ Integration).BoxMOT supports Python 3.10 through 3.13.
pip install boxmot
boxmot --help
The default package uses the standard PyPI PyTorch build. Source checkouts and
CI can explicitly select the lockfile-backed cpu or cu130 profile. For
those profiles and mode-specific extras such as yolo, service, evolve,
research, onnx, openvino, and tflite, see the
installation guide.
| Tracker key | Status | MOT17 ablation | SportsMOT val | MMOT OBB test | OBB | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| HOTA | MOTA | IDF1 | HOTA | MOTA | IDF1 | HOTA | MOTA | IDF1 | |||
| occluboost | ✅ | 71.10 (71.10) | 78.50 (78.50) | 85.28 (85.28) | 83.17 | 97.48 | 89.36 | 49.84 (49.84) | 39.41 (39.41) | 58.60 (58.60) | ✅ |
| botsort | ✅ | 69.68 (69.74) | 78.23 (78.27) | 82.33 (82.55) | 76.93 | 98.11 | 78.30 | 52.31 (52.40) | 45.43 (45.53) | 61.42 (61.42) | ✅ |
| boosttrack | ✅ | 69.25 (—) | 75.91 (—) | 83.20 (—) | 76.32 | 97.08 | 77.82 | 48.39 (—) | 41.36 (—) | 56.36 (—) | ✅ |
| strongsort | ✅ | 68.05 (—) | 76.19 (—) | 80.76 (—) | 79.80 | 97.31 | 80.27 | 49.76 (—) | 43.70 (—) | 57.32 (—) | ✅ |
| deepocsort | ✅ | 67.95 (—) | 75.83 (—) | 80.54 (—) | 79.51 | 97.94 | 79.59 | 50.84 (—) | 44.21 (—) | 59.33 (—) | ✅ |
| bytetrack | ✅ | 67.68 (67.68) | 78.04 (78.04) | 79.16 (79.16) | 67.93 | 97.25 | 76.90 | 33.97 (33.97) | 33.72 (33.72) | 39.74 (39.74) | ✅ |
| hybridsort | ✅ | 67.31 (—) | 74.09 (—) | 78.87 (—) | 81.14 | 98.07 | 81.88 | 54.64 (—) | 47.50 (—) | 64.67 (—) | ✅ |
| ocsort | ✅ | 66.44 (66.44) | 74.55 (74.55) | 77.90 (77.90) | 76.34 | 96.60 | 75.64 | 28.64 (28.64) | 26.17 (26.17) | 30.06 (30.06) | ✅ |
| sfsort | ✅ | 62.65 (62.65) | 76.87 (76.87) | 69.18 (69.18) | 75.73 | 98.39 | 72.99 | 47.83 (47.83) | 45.42 (45.42) | 52.09 (52.09) | ✅ |
Scores are Python first and C++ in parentheses.
MMOT reported metrics are 'class average'. See Experiment Workflows for details.
Related guides:
CLI:
boxmot track --detector yolo26n --reid lmbn_n_duke --tracker occluboost \
--source 0 --save --show
Evaluate a tracker:
boxmot eval \
--dataset mot17 \
--split ablation \
--detector yolox-x-mot17 \
--reid lmbn-n-duke \
--tracker botsort
See the evaluation guide for --fps and
--calibrate-kf usage.
For saved KITTI predictions, choose the inputs your tracker needs:
boxmot eval --experiment kitti-mots/2d \
--data-root ./kitti-mots --tracker ocsort --cache-inputs
boxmot eval --experiment kitti-mots/full \
--data-root ./kitti-mots --tracker eagermot --cache-inputs
Both experiments reference the same kitti-mots.yaml inventory. The first
selects 2D boxes; the second adds masks, 3D boxes,
calibration, and camera poses. See KITTI experiments.
Use NumPy detections and BGR images directly:
import numpy as np
from boxmot import OccluBoost
tracker = OccluBoost()
dets = np.array([[100, 200, 300, 400, 0.9, 0]])
frame = np.zeros((480, 640, 3), dtype=np.uint8) # BGR image
tracks = tracker.update(dets, frame)
print(tracks[:, 4].astype(int)) # track IDs
# OBB: (cx, cy, w, h, angle in radians, confidence, class_id)
# tracker = OccluBoost(is_obb=True)
# dets = np.array([[200, 300, 200, 100, np.pi / 6, 0.9, 0]])
# tracks = tracker.update(dets, frame)
# print(tracks[:, 5].astype(int)) # track IDs
Start with CONTRIBUTING.md and the contributor docs.
box-mot@outlook.com to discuss your project.box-mot@outlook.com(top 30 of 44)
Python
95.2%
C++
4.6%