Skip to main content

motrics

Fast MOT and HOTA metrics for Python, powered by Rust.

CI codecov PyPI License Python 3.10+ Ruff

Bar chart: motrics computes CLEAR+Identity+HOTA in 770ms vs TrackEval's 5930ms (7.7x faster), and CLEAR+Identity in 443ms vs py-motmetrics' 6211ms (14.0x faster).

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_hota take the same four arguments directly, no Frames needed.
  • Boxes: xyxy by 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.toml version 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/xywh box formats
  • Precomputed-similarity core inputs (compute_*_from_similarity)
  • motrics.compat.motmetrics: drop-in MOTAccumulator, full motchallenge_metrics field set including switch subtypes (num_transfer/num_ascend/num_migrate)
  • motrics.compat.trackeval: drop-in Evaluator/MotChallenge2DBox/ HOTA/CLEAR/Identity
  • Ergonomic native API: Frames, evaluate(), streaming Accumulator for 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.trackeval Evaluator behaviors: 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 MOTAccumulator API that compat.motmetrics mirrors.

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

motrics-0.3.0.tar.gz (262.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

motrics-0.3.0-cp310-abi3-win_amd64.whl (375.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

motrics-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (495.7 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

motrics-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (480.2 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

motrics-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (449.2 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

motrics-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (461.3 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

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

Hashes for motrics-0.3.0.tar.gz
Algorithm Hash digest
SHA256 461b6ddae04891dc47de3a5d7de465fd1146523dfced885c397b9df21e1f4e7f
MD5 03c5cbe69a7b3502f6fe5b393167e2e7
BLAKE2b-256 73e3efda1eeb09f0cbef7fbd1bd61ec8aa832439148a20ca60815202e041016e

See more details on using hashes here.

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

Hashes for motrics-0.3.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 6774930ae31709e3804dc27366be67b27775b52fa44aa1ee03101503a0905cd3
MD5 a6e09ba9e4fe6a313c2eb087b76be267
BLAKE2b-256 41560595b688512328ec554e5a04fe1ce5e604e9c08d5ea0796f4b8244985308

See more details on using hashes here.

File details

Details for the file motrics-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for motrics-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 21e9f5a6e26bf2f5b56e57a85d887c69aa61f23c3f80eb2cab7518d1acefa66c
MD5 b4e3c2cbb7fa5229a88149d16b147f1e
BLAKE2b-256 1c92037613e833e3a05927eeb51cebb8cedb036658c3bd89cfd51b3f39d9b567

See more details on using hashes here.

File details

Details for the file motrics-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for motrics-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d6d087ff3cf8ae6a46b76ed927b450f35e3103bfab9f839c9b26b458d600198b
MD5 c3d9d7f4c51716c8ff79299914e6609c
BLAKE2b-256 2796b9ed724269e71b1d39abb41e7bb48b341f6a65ce1579d99faa17c732109a

See more details on using hashes here.

File details

Details for the file motrics-0.3.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for motrics-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1457e8c33f20d0257fff486cbe479a7a0675a4cb4b0c74642f60428abef83d8c
MD5 e6afb3e92d39bec5df318d254db1d360
BLAKE2b-256 524a26c6ea2b8c53ae3121477c361f79e56749e049e0e246a4474cd16296aa9a

See more details on using hashes here.

File details

Details for the file motrics-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for motrics-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7d671b711c02877aaf814f5dfb48fa214fbe031357f128d02c0796625def129f
MD5 c36b3baddef1e7190d19f010c4313b40
BLAKE2b-256 fa0b12ddd35c745c25fd4e4d0d7a9ef8c6a093c203b0189daf74752708080157

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

6 files

0.2.0

6 files

0.1.0

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page