brainstate

mikel-brostrom/boxmot · source

Snapshot 0 · 2026-11-04T12:47:26Z · Python · AGPL-3.0

Content fingerprintb8b1e5278a21a53724c3d2453bd87f958df5fe0d9c288ea424e5f565a27b624f

GitHub description at capture

BoxMOT: Pluggable Python and C++ SOTA multi-object tracking modules with support for axis-aligned and oriented bounding boxes

README at capture

<div align="center" markdown="1">

  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/logo/logo_white.png">
    <source media="(prefers-color-scheme: light)" srcset="docs/logo/logo_black.png">
    <img width="400"
         src="docs/logo/logo_black.png"
         alt="BoxMOT logo">
  </picture>

  <p><b>Pluggable Python and C++ multi-object tracking modules for axis-aligned and oriented bounding box detections from any model.</b></p>

  [![CI](https://github.com/mikel-brostrom/boxmot/actions/workflows/ci.yml/badge.svg)](https://github.com/mikel-brostrom/boxmot/actions/workflows/ci.yml)
  [![Coverage](https://codecov.io/gh/mikel-brostrom/boxmot/branch/master/graph/badge.svg)](https://app.codecov.io/gh/mikel-brostrom/boxmot/tree/master)
  [![PyPI version](https://badge.fury.io/py/boxmot.svg)](https://badge.fury.io/py/boxmot)
  [![downloads](https://static.pepy.tech/badge/boxmot)](https://pepy.tech/project/boxmot)
  [![license](https://img.shields.io/badge/license-AGPL%203.0-blue)](https://github.com/mikel-brostrom/boxmot/blob/master/LICENSE)
  [![python-version](https://img.shields.io/pypi/pyversions/boxmot)](https://badge.fury.io/py/boxmot)
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8132989.svg)](https://doi.org/10.5281/zenodo.8132989)
  [![colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/18nIqkBr68TkK8dHdarxTco6svHUJGggY?usp=sharing)
  [![discord](https://img.shields.io/discord/1377565354326495283?logo=discord&label=discord&labelColor=fff&color=5865f2)](https://discord.gg/tUmFEcYU4q)
  [<img src="https://devin.ai/assets/askdeepwiki.png" alt="Ask DeepWiki" height="20">](https://deepwiki.com/mikel-brostrom/boxmot)

  <a href="https://trendshift.io/repositories/13239" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13239" alt="mikel-brostrom%2Fboxmot | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"></a>

  ---

  [Docs](docs/index.md) • [Installation](docs/getting-started/installation.md) • [Modes](docs/modes/index.md) • [API Reference](docs/python/index.md) • [Trackers](docs/trackers/index.md) • [Contributing](CONTRIBUTING.md)

  <img width="640"
       src="https://github.com/mikel-brostrom/boxmot/releases/download/v12.0.0/output_640.gif"
       alt="BoxMOT demo">

</div>

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.

## Why BoxMOT

- One interface for `track`, `materialize`, `materialize --time-variant`, `eval`,
  `tune`, `research`, `train-reid`, `eval-reid`, `compare-reid`, `export`,
  `export-edgetam`, `install`, and native `build` workflows.
- Swappable components with explicit capabilities and requirements.
- Immutable, keyed Parquet builds with reusable detections, masks, 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 cpp` and embeddable in standalone C++ projects via CMake (see [Native C++ Integration](docs/native/index.md) and [platform dependency installation](docs/native/index.md#install-dependencies)).
- A structured Python API for embedding components and pipelines in applications.

## Installation

BoxMOT supports Python `3.10` through `3.13`.

```bash
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](docs/getting-started/installation.md).

## Benchmark Results

<div align="center" markdown="1">

<!-- START TRACKER TABLE -->
<table>
  <thead>
    <tr>
      <th rowspan="2" align="left"><sub>Tracker key</sub></th>
      <th rowspan="2" align="center"><sub>Status</sub></th>
      <th colspan="3" align="center"><sub>MOT17 ablation</sub></th>
      <th colspan="3" align="center"><sub>SportsMOT val</sub></th>
      <th colspan="3" align="center"><sub>MMOT OBB test</sub></th>
      <th rowspan="2" align="center"><sub>OBB</sub></th>
    </tr>
    <tr>
      <th align="right"><sub>HOTA</sub></th>
      <th align="right"><sub>MOTA</sub></th>
      <th align="right"><sub>IDF1</sub></th>
      <th align="right"><sub>HOTA</sub></th>
      <th align="right"><sub>MOTA</sub></th>
      <th align="right"><sub>IDF1</sub></th>
      <th align="right"><sub>HOTA</sub></th>
      <th align="right"><sub>MOTA</sub></th>
      <th align="right"><sub>IDF1</sub></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td align="left"><sub>occluboost</sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub><b>71.10</b><br>(71.10)</sub></td>
      <td align="right"><sub><b>78.50</b><br>(78.50)</sub></td>
      <td align="right"><sub><b>85.28</b><br>(85.28)</sub></td>
      <td align="right"><sub><b>83.17</b></sub></td>
      <td align="right"><sub>97.48</sub></td>
      <td align="right"><sub><b>89.36</b></sub></td>
      <td align="right"><sub>49.84<br>(49.84)</sub></td>
      <td align="right"><sub>39.41<br>(39.41)</sub></td>
      <td align="right"><sub>58.60<br>(58.60)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2206.14651">botsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>69.68<br>(69.74)</sub></td>
      <td align="right"><sub>78.23<br>(78.27)</sub></td>
      <td align="right"><sub>82.33<br>(82.55)</sub></td>
      <td align="right"><sub>76.93</sub></td>
      <td align="right"><sub><b>98.11</b></sub></td>
      <td align="right"><sub>78.30</sub></td>
      <td align="right"><sub>52.31<br>(52.40)</sub></td>
      <td align="right"><sub>45.43<br>(45.53)</sub></td>
      <td align="right"><sub>61.42<br>(61.42)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2408.13003">boosttrack</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>69.25<br>(—)</sub></td>
      <td align="right"><sub>75.91<br>(—)</sub></td>
      <td align="right"><sub>83.20<br>(—)</sub></td>
      <td align="right"><sub>76.32</sub></td>
      <td align="right"><sub>97.08</sub></td>
      <td align="right"><sub>77.82</sub></td>
      <td align="right"><sub>48.39<br>(—)</sub></td>
      <td align="right"><sub>41.36<br>(—)</sub></td>
      <td align="right"><sub>56.36<br>(—)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2202.13514">strongsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>68.05<br>(—)</sub></td>
      <td align="right"><sub>76.19<br>(—)</sub></td>
      <td align="right"><sub>80.76<br>(—)</sub></td>
      <td align="right"><sub>79.80</sub></td>
      <td align="right"><sub>97.31</sub></td>
      <td align="right"><sub>80.27</sub></td>
      <td align="right"><sub>49.76<br>(—)</sub></td>
      <td align="right"><sub>43.70<br>(—)</sub></td>
      <td align="right"><sub>57.32<br>(—)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2302.11813">deepocsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>67.95<br>(—)</sub></td>
      <td align="right"><sub>75.83<br>(—)</sub></td>
      <td align="right"><sub>80.54<br>(—)</sub></td>
      <td align="right"><sub>79.51</sub></td>
      <td align="right"><sub>97.94</sub></td>
      <td align="right"><sub>79.59</sub></td>
      <td align="right"><sub>50.84<br>(—)</sub></td>
      <td align="right"><sub>44.21<br>(—)</sub></td>
      <td align="right"><sub>59.33<br>(—)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2110.06864">bytetrack</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>67.68<br>(67.68)</sub></td>
      <td align="right"><sub>78.04<br>(78.04)</sub></td>
      <td align="right"><sub>79.16<br>(79.16)</sub></td>
      <td align="right"><sub>67.93</sub></td>
      <td align="right"><sub>97.25</sub></td>
      <td align="right"><sub>76.90</sub></td>
      <td align="right"><sub>33.97<br>(33.97)</sub></td>
      <td align="right"><sub>33.72<br>(33.72)</sub></td>
      <td align="right"><sub>39.74<br>(39.74)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2308.00783">hybridsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>67.31<br>(—)</sub></td>
      <td align="right"><sub>74.09<br>(—)</sub></td>
      <td align="right"><sub>78.87<br>(—)</sub></td>
      <td align="right"><sub>81.14</sub></td>
      <td align="right"><sub>98.07</sub></td>
      <td align="right"><sub>81.88</sub></td>
      <td align="right"><sub><b>54.64</b><br>(—)</sub></td>
      <td align="right"><sub><b>47.50</b><br>(—)</sub></td>
      <td align="right"><sub><b>64.67</b><br>(—)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/abs/2203.14360">ocsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>66.44<br>(66.44)</sub></td>
      <td align="right"><sub>74.55<br>(74.55)</sub></td>
      <td align="right"><sub>77.90<br>(77.90)</sub></td>
      <td align="right"><sub>76.34</sub></td>
      <td align="right"><sub>96.60</sub></td>
      <td align="right"><sub>75.64</sub></td>
      <td align="right"><sub>28.64<br>(28.64)</sub></td>
      <td align="right"><sub>26.17<br>(26.17)</sub></td>
      <td align="right"><sub>30.06<br>(30.06)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
    <tr>
      <td align="left"><sub><a href="https://arxiv.org/pdf/2404.07553">sfsort</a></sub></td>
      <td align="center"><sub>✅</sub></td>
      <td align="right"><sub>62.65<br>(62.65)</sub></td>
      <td align="right"><sub>76.87<br>(76.87)</sub></td>
      <td align="right"><sub>69.18<br>(69.18)</sub></td>
      <td align="right"><sub>75.73</sub></td>
      <td align="right"><sub>98.39</sub></td>
      <td align="right"><sub>72.99</sub></td>
      <td align="right"><sub>47.83<br>(47.83)</sub></td>
      <td align="right"><sub>45.42<br>(45.42)</sub></td>
      <td align="right"><sub>52.09<br>(52.09)</sub></td>
      <td align="center"><sub>✅</sub></td>
    </tr>
  </tbody>
</table>
<!-- END TRACKER TABLE -->

<p align="center">
  <sub>Scores are Python first and C++ in parentheses.</sub><br>
  <sub>MMOT reported metrics are 'class average'. See <a href="docs/guides/experiments.md">Experiment Workflows</a> for details.</sub>
</p>

</div>

Related guides:

- [Evaluation and Postprocessing](docs/guides/evaluation.md)
- [Experiment Workflows](docs/guides/experiments.md)
- [Native C++ Integration](docs/native/index.md)

## Minimal Usage

CLI:

```bash
boxmot track --detector yolo26n --reid lmbn_n_duke --tracker occluboost \
  --source 0 --save --show
```

Evaluate a tracker:

```bash
boxmot eval \
  --dataset mot17 \
  --split ablation \
  --detector yolox-x-mot17 \
  --reid lmbn-n-duke \
  --tracker botsort
```

Python with axis-aligned boxes (AABB):

```python
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
```

Python with oriented boxes (OBB):

```python
import numpy as np

from boxmot import OccluBoost

tracker = OccluBoost(is_obb=True)
# cx, cy, width, height, angle in radians, confidence, class_id
dets = np.array([[200, 300, 200, 100, np.pi / 6, 0.9, 0]])
frame = np.zeros((480, 640, 3), dtype=np.uint8)  # BGR image
tracks = tracker.update(dets, frame)
print(tracks[:, 5].astype(int))  # track IDs
```

2D/3D sensor fusion with ego-motion compensation using [EagerMot](docs/trackers/eagermot.md):

```python
import numpy as np

from boxmot import EagerMot

tracker = EagerMot()
camera = np.array([  # synthetic camera projection
    [100, 0, 100, 0],
    [0, 100, 50, 0],
    [0, 0, 1, 0],
])
camera_to_world = np.eye(4)
camera_to_world[0, 3] = 1.0  # synthetic pose: camera at world x = 1 meter
dets = np.array([[78, 39, 122, 62, 0.95, 0]])
# 3D in camera coordinates: x, y, z, yaw, length, width, height, confidence, class_id
dets_3d = np.array([[0, 1, 10, 0, 4, 2, 2, 0.9, 0]])

tracks_2d, tracks_3d = tracker.update(
    dets,
    detections_3d=dets_3d,
    camera=camera,
    image_size=(100, 200),  # height, width
    camera_to_world=camera_to_world,
)
print(tracks_2d[:, 4].astype(int))  # image track IDs
print(tracks_3d[:, 7].astype(int))  # 3D track IDs
```

Replace the synthetic pose with the current frame's absolute 4×4 camera-to-world
transform on every update. KITTI evaluation loads these from `poses.npy` when
the dataset declares a `poses` modality. If poses are unavailable, omit
`camera_to_world` throughout the sequence to track in camera coordinates.

## Contributing

Start with [CONTRIBUTING.md](CONTRIBUTING.md) and the [contributor docs](docs/contributing/index.md).

## Contributors

<a href="https://github.com/mikel-brostrom/boxmot/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=mikel-brostrom/boxmot" alt="BoxMOT contributors">
</a>

## Support and Citation

- Bugs and feature requests: [GitHub Issues](https://github.com/mikel-brostrom/boxmot/issues)
- Questions and discussion: [GitHub Discussions](https://github.com/mikel-brostrom/boxmot/discussions) or [Discord](https://discord.gg/tUmFEcYU4q)
- Limited free consulting is available for nonprofit nature conservation projects using BoxMOT. Contact `box-mot@outlook.com` to discuss your project.
- Citation metadata: [CITATION.cff](https://github.com/mikel-brostrom/boxmot/blob/master/CITATION.cff)
- Commercial support: `box-mot@outlook.com`