tracks: AABB (M, 8), or OBB (M, 9) with angle after h
September 1, 2026 · View on GitHub
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 gives you one CLI and one Python API for running modern multi-object tracking workflows. It covers direct tracking, catalog-backed evaluation, tuning, research loops, ReID training and evaluation, and ReID export without forcing you to rebuild the detector and tracker stack for each experiment.
Why BoxMOT
- One interface for
track,generate,eval,tune,research,train-reid,eval-reid,export, and nativebuildworkflows. - Swappable trackers with shared detector and ReID plumbing.
- Dataset and experiment workflows with reusable detections and embeddings.
- Support for both AABB and OBB tracking paths.
- Optional production-ready native C++ tracker implementations with the same metrics as the Python path, opted into via
--tracker-backend cppand embeddable in standalone C++ projects via CMake (see Native C++ Integration). - Public Python API for embedding the same workflows in applications and notebooks.
Installation
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.
Docker images
Published images cover GPU and CPU CLI workflows plus separate CPU geometry and GPU ReID tracker services:
# GPU-enabled detector, CLI, evaluation, and interactive workflows
docker run --rm -it --gpus all boxmot/boxmot:latest
# The same CLI workflows on CPU
docker run --rm -it boxmot/boxmot:latest-cpu
# CPU-only stateful HTTP tracking from externally supplied detections
docker run --rm -p 8000:8000 boxmot/boxmot-service:latest
# CUDA/ReID stateful tracking from detections plus an encoded image per frame
docker run --rm --gpus all -p 8000:8000 \
-v "$PWD/models/osnet_x0_25_msmt17.pt:/models/osnet_x0_25_msmt17.pt:ro" \
-e BOXMOT_SERVICE_REID_WEIGHTS=/models/osnet_x0_25_msmt17.pt \
boxmot/boxmot-service:latest-gpu
Versioned and commit-addressed tags are also published. GPU CLI tags are
<version> and sha-<commit>; CPU CLI tags append -cpu. The CPU service uses
canonical <version> and sha-<commit> tags in its own repository, while the
GPU service appends -gpu. See the
installation guide for local builds.
Both services accept ordered AABB or OBB detections and keep isolated state per
stream/session; neither runs a detector. The CPU image supports ByteTrack,
OCSort, and SFSORT without image pixels. The GPU image supports StrongSORT,
BotSORT, DeepOCSORT, HybridSORT, BoostTrack, and OccluBoost, and requires a raw
base64-encoded JPEG or PNG in image_base64 for every frame, including empty
detection frames. See the deployment guide for the
request schema and horizontal-scaling requirements.
Benchmark Results
| Tracker | 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:
Minimal Usage
CLI:
boxmot track --detector yolo26n --reid lmbn_n_duke --tracker occluboost --source 0 --save --show
Python:
import numpy as np
from boxmot.trackers import OccluBoost
tracker = OccluBoost()
# dets: (N, 6) array with [x1, y1, x2, y2, conf, cls] per detection
dets = np.array([[100, 200, 300, 400, 0.9, 0]], dtype=np.float32)
# OBB alternative: (N, 7) with [cx, cy, w, h, angle_radians, conf, cls]
# dets = np.array([[200, 300, 200, 200, 0.25, 0.9, 0]], dtype=np.float32)
img = np.zeros((480, 640, 3), dtype=np.uint8) # current frame
# tracks: AABB (M, 8), or OBB (M, 9) with angle after h
tracks = tracker.update(dets, img)
print(tracks)
Contributing
Start with CONTRIBUTING.md and the contributor docs.
Contributors
Support and Citation
- Bugs and feature requests: GitHub Issues
- Questions and discussion: GitHub Discussions or Discord
- Limited free consulting is available for nonprofit nature conservation projects using BoxMOT. Contact
box-mot@outlook.comto discuss your project. - Citation metadata: CITATION.cff
- Commercial support:
box-mot@outlook.com