motrics
Fast MOT and HOTA metrics for Python, powered by Rust.
MOT17-train, wall time, from a live CI run. See Benchmarks.
Highlights
- Fast. Rust core; see Benchmarks for numbers against TrackEval and py-motmetrics.
- Validated. Bit-exact parity with TrackEval on CLEAR, Identity, and HOTA, checked in CI.
- Drop-in migration. Swap one import to replace py-motmetrics or TrackEval.
Install
pip install motrics
Prebuilt wheels for Linux, macOS, and Windows (Python 3.10+). Building from source instead? See CONTRIBUTING.md for the dev setup.
Quickstart
import motrics
# Parse MOTChallenge ground truth and tracker results.
gt = motrics.load_motchallenge("seq/gt/gt.txt")
pred = motrics.load_motchallenge("seq/res.txt", min_confidence=0.5)
# Align onto a shared frame timeline, bundle each side, then evaluate.
gt_ids, gt_boxes, pred_ids, pred_boxes = motrics.align_frames(gt, pred)
result = motrics.evaluate(
motrics.Frames(ids=gt_ids, boxes=gt_boxes),
motrics.Frames(ids=pred_ids, boxes=pred_boxes),
)
print(result.clear.mota, result.identity.idf1, result.hota.hota)
- Only need one metric?
compute_clear/compute_identity/compute_hotatake the same four arguments directly, noFramesneeded. - Boxes:
xyxyby default,box_format="xywh"for the alternative; NumPy(N, 4)arrays accepted too.
Datasets
Each dataset gets a small adapter (ingest + preprocessing + similarity) on top of the shared metric core. All are validated against TrackEval's own preprocessing:
| Dataset | Box/mask | Similarity | Load |
|---|---|---|---|
| MOTChallenge / DanceTrack | box | IoU | load_motchallenge(_gt) |
| KITTI 2D-box | box | IoU | load_kitti(_gt) |
| KITTI-MOTS | mask (RLE) | mask IoU | load_kitti_mots(_gt) |
| DAVIS (unsupervised) | indexed PNG mask | mask IoU | load_davis |
| BDD100K | box (JSON) | IoU | load_bdd100k(_gt) |
| KITTI-3D | oriented 3D box | volumetric IoU | load_kitti_3d(_gt) |
Migrating from py-motmetrics or TrackEval
Swap one import, the rest of your code is unchanged.
py-motmetrics
# before
import motmetrics as mm
# after: same code, motrics underneath
import motrics.compat.motmetrics as mm
acc = mm.MOTAccumulator(auto_id=True)
for gt_ids, gt_boxes, pred_ids, pred_boxes in sequence:
dists = mm.distances.iou_matrix(gt_boxes, pred_boxes, max_iou=0.5)
acc.update(gt_ids, pred_ids, dists)
summary = mm.metrics.create().compute(acc, metrics=mm.metrics.SUPPORTED, name="acc")
pip install motrics[compat] (pulls in pandas, needed only for this subpackage).
The full motmetrics.metrics.motchallenge_metrics field set is supported:
mota, motp, idf1, idp, idr, recall, precision,
num_false_positives, num_misses, num_switches, num_unique_objects,
mostly_tracked, partially_tracked, mostly_lost, num_fragmentations,
num_transfer, num_ascend, num_migrate.
See python/motrics/compat/motmetrics/
for what else differs (e.g. no events/mot_events DataFrame).
TrackEval
# before
import trackeval
# after: same code, motrics underneath
import motrics.compat.trackeval as trackeval
eval_config = trackeval.Evaluator.get_default_eval_config()
evaluator = trackeval.Evaluator(eval_config)
dataset_config = trackeval.datasets.MotChallenge2DBox.get_default_dataset_config()
dataset_config["GT_FOLDER"] = "data/gt/mot_challenge/"
dataset_config["TRACKERS_FOLDER"] = "data/trackers/mot_challenge/"
dataset_list = [trackeval.datasets.MotChallenge2DBox(dataset_config)]
metrics_list = [trackeval.metrics.HOTA(), trackeval.metrics.CLEAR(), trackeval.metrics.Identity()]
results, messages = evaluator.evaluate(dataset_list, metrics_list)
print(results["MotChallenge2DBox"]["my_tracker"]["COMBINED_SEQ"]["pedestrian"]["CLEAR"]["MOTA"])
Same class names, config keys, directory/seqmap conventions, and result shape
as real TrackEval. No trackeval/scipy install required, only numpy (a
core dependency already).
| ✅ Supported | HOTA, Identity, and CLEAR's full field set (MOTA/MOTP/MODA/sMOTA/MOTAL, MT/PT/ML/Frag, CLR_Re/CLR_Pr/MTR/PTR/MLR/CLR_F1/FP_per_frame), bit-exact vs real TrackEval |
| ❌ Not yet | Parallel evaluation, BREAK_ON_ERROR config, printing/plotting, zipped input, DO_PREPROC=False, MOT15, IDEucl/JAndF/TrackMAP/VACE |
See python/motrics/compat/trackeval/
for the full list of what differs from real TrackEval.
Metric name map: TrackEval / py-motmetrics / motrics' native API
Using motrics' own API directly (faster than the compat layer, no
per-frame Python bookkeeping)? Here's how the field names line up:
| Concept | TrackEval | py-motmetrics | motrics (native) |
|---|---|---|---|
| Matched detections (incl. switches) | CLR_TP |
num_detections |
ClearMetrics.num_matches |
| False positives | CLR_FP |
num_false_positives |
ClearMetrics.num_false_positives |
| Misses | CLR_FN |
num_misses |
ClearMetrics.num_misses |
| Identity switches | IDSW |
num_switches |
ClearMetrics.num_switches |
| MOTA / MOTP | MOTA / MOTP |
mota / motp |
ClearMetrics.mota / .motp |
| Identity TP / FP / FN | IDTP/IDFP/IDFN |
idtp/idfp/idfn |
IdentityMetrics.idtp/.idfp/.idfn |
| IDF1 / IDP / IDR | IDF1/IDP/IDR |
idf1/idp/idr |
IdentityMetrics.idf1/.idp/.idr |
| HOTA / DetA / AssA / LocA | HOTA/DetA/AssA/LocA |
(not in motmetrics) | HotaMetrics.hota/.deta/.assa/.loca |
Benchmarks
On real MOT17 data, release build, end-to-end from raw boxes (chart at the top
of this README). Numbers are illustrative and machine-dependent. See the CI
benchmark comment on any PR for a live measurement, and
benchmarks/README.md for methodology and how to run
it yourself.
Roadmap
- Project scaffolding (build, lint, packaging, CI)
- Published to PyPI, automated tag-and-release on every
Cargo.tomlversion bump - Box IoU + assignment (Hungarian/greedy) primitives
- CLEAR metrics: MOTA/MOTP, ID switches, FP/FN, MT/PT/ML, fragmentations, and the derived MODA/sMOTA/MOTAL/CLR_Re/CLR_Pr fields
- Identity metrics (IDF1/IDP/IDR)
- HOTA (DetA, AssA, alpha sweep)
- MOTChallenge ingest, integration tests, TrackEval numeric parity tests
- Benchmark & parity infrastructure vs TrackEval and py-motmetrics on real MOTChallenge data, validated in CI
- Zero-copy NumPy input path;
xyxy/xywhbox formats - Precomputed-similarity core inputs (
compute_*_from_similarity) -
motrics.compat.motmetrics: drop-inMOTAccumulator, fullmotchallenge_metricsfield set including switch subtypes (num_transfer/num_ascend/num_migrate) -
motrics.compat.trackeval: drop-inEvaluator/MotChallenge2DBox/HOTA/CLEAR/Identity - Ergonomic native API:
Frames,evaluate(), streamingAccumulatorfor CLEAR + Identity - Mask-IoU similarity kernel (RLE codec, ignore-region/IoA semantics) for mask-based adapters
- 3D IoU similarity kernel (oriented boxes) for KITTI-3D
- Dataset adapters: DanceTrack, KITTI 2D-box, KITTI-MOTS, DAVIS, BDD100K, KITTI-3D (see Datasets)
- Other TrackEval metrics:
IDEucl,TrackMAP,VACE,JAndF(DAVIS's native metric) - Remaining
compat.trackevalEvaluatorbehaviors: parallel evaluation, printing/plotting, zipped input,DO_PREPROC=False,MOT15,BREAK_ON_ERROR
Acknowledgments
motrics reimplements the evaluation protocols and metric definitions of two projects. All credit for the underlying methodology belongs to their authors; motrics is a from-scratch Rust port, not a wrapper around either.
- TrackEval: the reference implementation for CLEAR, Identity, and HOTA, and for every dataset adapter's preprocessing rules. motrics is validated against it in CI.
- py-motmetrics: the reference
implementation for the MOTChallenge metric set and the
MOTAccumulatorAPI thatcompat.motmetricsmirrors.
Contributing
See CONTRIBUTING.md for the development setup, tooling, and checks to run before opening a PR.
License
MIT © 2026 Kevin Serrano
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file motrics-0.3.0.tar.gz.
File metadata
- Download URL: motrics-0.3.0.tar.gz
- Upload date:
- Size: 262.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
461b6ddae04891dc47de3a5d7de465fd1146523dfced885c397b9df21e1f4e7f
|
|
| MD5 |
03c5cbe69a7b3502f6fe5b393167e2e7
|
|
| BLAKE2b-256 |
73e3efda1eeb09f0cbef7fbd1bd61ec8aa832439148a20ca60815202e041016e
|
File details
Details for the file motrics-0.3.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: motrics-0.3.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 375.3 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6774930ae31709e3804dc27366be67b27775b52fa44aa1ee03101503a0905cd3
|
|
| MD5 |
a6e09ba9e4fe6a313c2eb087b76be267
|
|
| BLAKE2b-256 |
41560595b688512328ec554e5a04fe1ce5e604e9c08d5ea0796f4b8244985308
|
File details
Details for the file motrics-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: motrics-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 495.7 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21e9f5a6e26bf2f5b56e57a85d887c69aa61f23c3f80eb2cab7518d1acefa66c
|
|
| MD5 |
b4e3c2cbb7fa5229a88149d16b147f1e
|
|
| BLAKE2b-256 |
1c92037613e833e3a05927eeb51cebb8cedb036658c3bd89cfd51b3f39d9b567
|
File details
Details for the file motrics-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: motrics-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 480.2 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6d087ff3cf8ae6a46b76ed927b450f35e3103bfab9f839c9b26b458d600198b
|
|
| MD5 |
c3d9d7f4c51716c8ff79299914e6609c
|
|
| BLAKE2b-256 |
2796b9ed724269e71b1d39abb41e7bb48b341f6a65ce1579d99faa17c732109a
|
File details
Details for the file motrics-0.3.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: motrics-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 449.2 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1457e8c33f20d0257fff486cbe479a7a0675a4cb4b0c74642f60428abef83d8c
|
|
| MD5 |
e6afb3e92d39bec5df318d254db1d360
|
|
| BLAKE2b-256 |
524a26c6ea2b8c53ae3121477c361f79e56749e049e0e246a4474cd16296aa9a
|
File details
Details for the file motrics-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: motrics-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 461.3 kB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d671b711c02877aaf814f5dfb48fa214fbe031357f128d02c0796625def129f
|
|
| MD5 |
c36b3baddef1e7190d19f010c4313b40
|
|
| BLAKE2b-256 |
fa0b12ddd35c745c25fd4e4d0d7a9ef8c6a093c203b0189daf74752708080157
|