Trackforge is a unified, high-performance computer vision tracking library implemented in Rust with Python bindings. It provides real-time multi-object tracking algorithms, optimized for speed and designed as the CPU "glue" between GPU-based object detectors and your tracking pipeline.
| Tracker | Type | Appearance (Re-ID) |
|---|---|---|
| ByteTrack | IoU + confidence association | No |
| DeepSORT | IoU + cosine distance | Yes (pluggable) |
| OC-SORT | IoU + velocity direction (OCM) | No |
| Deep OC-SORT | IoU + velocity (OCM) + appearance | Yes (pluggable) |
| SORT | IoU + Kalman filter | No |
- 🚀 Native Rust Core Blazingly fast tracking (< 1ms/frame for ByteTrack) with full memory safety
- 🐍 Python Bindings First-class
pip install trackforgesupport via PyO3 - 🎯 Multi-Algorithm ByteTrack, OC-SORT, DeepSORT, Deep OC-SORT, and SORT with a unified API
- 🔌 Pluggable Re-ID DeepSORT's appearance extractor is a trait; plug in any feature model
- 📐 Generic Kalman Filter Configurable position/velocity weighting, gating distance computation
Important
Under active development. APIs and features are subject to change. MSRV: Rust 1.89.
pip install trackforgeAdd to your Cargo.toml:
[dependencies]
trackforge = "0.3.0"To build the Python bindings from source (e.g., via maturin develop), enable the python feature:
[dependencies]
trackforge = { version = "0.3.0", features = ["python"] }from trackforge import BYTETRACK
tracker = BYTETRACK(track_thresh=0.5, track_buffer=30, match_thresh=0.8, det_thresh=0.6)
# Format: ([x, y, w, h], confidence, class_id)
detections = [
([100.0, 100.0, 50.0, 100.0], 0.9, 0),
([200.0, 200.0, 60.0, 120.0], 0.85, 0),
]
tracks = tracker.update(detections)
for track_id, tlwh, score, class_id in tracks:
print(f"ID: {track_id}, Box: {tlwh}")from trackforge import DEEPSORT
tracker = DEEPSORT(
max_age=30,
n_init=3,
max_iou_distance=0.7,
max_cosine_distance=0.2,
nn_budget=100,
)
detections = [([100.0, 100.0, 50.0, 100.0], 0.9, 0)]
embeddings = [[0.1, 0.2, 0.3, ...]] # appearance feature vectors
tracks = tracker.update(detections, embeddings)
for track_id, tlwh, score, class_id in tracks:
print(f"ID: {track_id}, Box: {tlwh}, Score: {score}")from trackforge import OCSORT
tracker = OCSORT(
max_age=30,
min_hits=3,
iou_threshold=0.3,
delta_t=3,
inertia=0.2,
)
detections = [
([100.0, 100.0, 50.0, 100.0], 0.9, 0),
([200.0, 200.0, 60.0, 120.0], 0.85, 0),
]
tracks = tracker.update(detections)
for track_id, tlwh, score, class_id in tracks:
print(f"ID: {track_id}, Box: {tlwh}")from trackforge import DEEPOCSORT
tracker = DEEPOCSORT(
max_age=30,
min_hits=3,
iou_threshold=0.3,
delta_t=3,
inertia=0.2,
appearance_weight=0.5,
max_cosine_distance=0.2,
nn_budget=100,
)
detections = [([100.0, 100.0, 50.0, 100.0], 0.9, 0)]
embeddings = [[0.1, 0.2, 0.3]] # one appearance vector per detection
# Pass embeddings for appearance-aware tracking, or omit them for motion only.
tracks = tracker.update(detections, embeddings)
for track_id, tlwh, score, class_id in tracks:
print(f"ID: {track_id}, Box: {tlwh}")use trackforge::trackers::byte_track::ByteTrack;
let mut tracker = ByteTrack::new(0.5, 30, 0.8, 0.6);
// Format: ([x, y, w, h], confidence, class_id)
let detections = vec![
([100.0, 100.0, 50.0, 100.0], 0.9, 0),
([200.0, 200.0, 60.0, 120.0], 0.85, 0),
];
let tracks = tracker.update(detections);
for t in tracks {
println!("ID: {}, Box: {:?}", t.track_id, t.tlwh);
}use trackforge::trackers::deepsort::DeepSort;
// `extractor` implements the AppearanceExtractor trait (plug in any Re-ID model).
let mut tracker = DeepSort::new(extractor, 30, 3, 0.7, 0.2, 100);
let detections = vec![(BoundingBox::new(100.0, 100.0, 50.0, 100.0), 0.9, 0)];
let tracks = tracker.update(&image, detections)?;
for t in tracks {
println!("ID: {}, Box: {:?}", t.track_id, t.to_tlwh());
}use trackforge::trackers::ocsort::OcSort;
let mut tracker = OcSort::new(30, 3, 0.3, 3, 0.2);
let detections = vec![
([100.0, 100.0, 50.0, 100.0], 0.9, 0),
([200.0, 200.0, 60.0, 120.0], 0.85, 0),
];
let tracks = tracker.update(detections);
for t in tracks {
println!("ID: {}, Box: {:?}", t.track_id, t.tlwh);
}use trackforge::trackers::deep_ocsort::DeepOcSort;
// `extractor` implements AppearanceExtractor (plug in any Re-ID model).
let mut tracker = DeepOcSort::new(extractor, 30, 3, 0.3, 3, 0.2, 0.5, 0.2, 100);
let tracks = tracker.update(&image, detections)?;
for t in tracks {
println!("ID: {}, Box: {:?}", t.track_id, t.tlwh);
}use trackforge::trackers::sort::Sort;
let mut tracker = Sort::new(1, 3, 0.3);
let detections = vec![([100.0, 100.0, 50.0, 100.0], 0.9, 0)];
let tracks = tracker.update(detections);
for t in tracks {
println!("ID: {}, Box: {:?}", t.track_id, t.tlwh);
}Runnable demos live under examples/, with both a Python and a Rust entry per tracker.
| Tracker | Python | Rust |
|---|---|---|
| ByteTrack | byte_track_demo.py (YOLO11) |
byte_track_demo.rs |
| DeepSORT | deepsort_demo.py (YOLO + ResNet18) |
deepsort_simple.rs, deepsort_ort.rs (ONNX) |
| OC-SORT | ocsort_demo.py |
— |
| SORT | sort_yolo_demo.py (YOLO), sort_rtdetr_demo.py (RT-DETR) |
— |
| All four | tracker_comparison.py (side-by-side benchmark) |
— |
# Python
python examples/python/byte_track_demo.py
# Rust
cargo run --example byte_track_demo
cargo run --example deepsort_simple
cargo run --example deepsort_ort --features advanced_examplesThe Python demos use the usual detector stacks: ultralytics (YOLO), transformers + torch
(RT-DETR), and torch + torchvision (ResNet Re-ID); install what a given demo imports. The
deepsort_ort Rust demo needs the advanced_examples feature (ONNX Runtime + OpenCV).
Each tracker's parameters and defaults (identical across Python and Rust) are documented on the Parameters page.
- Rust 1.89+ (MSRV)
- Python 3.8+ and
maturinfor the bindings prekfor git hooks (optional but recommended)
git clone https://github.com/onuralpszr/trackforge.git
cd trackforge
# Rust core
cargo build
cargo test
# Python bindings (build into the active virtualenv)
maturin developThese mirror CI, run them before opening a PR:
cargo fmt --all -- --check # formatting
cargo clippy --all-targets -- -D warnings # lint, warnings are errors
cargo test # unit, integration, and doc tests
cargo llvm-cov --summary-only # coverage (cargo install cargo-llvm-cov)
prek run --all-files # all pre-commit hooks at oncepythonbuilds the PyO3 bindings.advanced_examplesenables the ONNX/OpenCV-backed examples (deepsort_ort), which need ONNX Runtime and OpenCV on the system.
cargo test --features python
cargo run --example deepsort_ort --features advanced_examples# After `maturin develop`:
python examples/python/deepsort_demo.py --video your_video.mp4Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- For major changes, open an issue first to discuss what you would like to change.
- PRs should pass CI:
cargo fmt,cargo clippy -- -D warnings,cargo test. - Use Commitizen for commit messages:
cz commit.
Planned trackers and milestones live on the Roadmap page.
If you use trackforge in your research or project, please cite it. GitHub's "Cite this
repository" button reads the CITATION.cff metadata, or use:
@software{trackforge,
author = {Sezer, Onuralp},
title = {trackforge: A unified, high-performance multi-object tracking library},
url = {https://github.com/onuralpszr/trackforge},
license = {MIT}
}trackforge provides clean-room implementations of published tracking algorithms. Please also cite the paper for the tracker you use:
Per-tracker citations
@inproceedings{bewley2016sort,
title={Simple Online and Realtime Tracking},
author={Bewley, Alex and Ge, Zongyuan and Ott, Lionel and Ramos, Fabio and Upcroft, Ben},
booktitle={IEEE International Conference on Image Processing (ICIP)},
year={2016}
}
@inproceedings{wojke2017deepsort,
title={Simple Online and Realtime Tracking with a Deep Association Metric},
author={Wojke, Nicolai and Bewley, Alex and Paulus, Dietrich},
booktitle={IEEE International Conference on Image Processing (ICIP)},
year={2017}
}
@inproceedings{zhang2022bytetrack,
title={ByteTrack: Multi-Object Tracking by Associating Every Detection Box},
author={Zhang, Yifu and Sun, Peize and Jiang, Yi and Yu, Dongdong and Weng, Fucheng and Yuan, Zehuan and Luo, Ping and Liu, Wenyu and Wang, Xinggang},
booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
year={2022}
}
@inproceedings{cao2023ocsort,
title={Observation-Centric SORT: Rethinking SORT for Robust Multi-Object Tracking},
author={Cao, Jinkun and Pang, Jiangmiao and Weng, Xinshuo and Khirodkar, Rawal and Kitani, Kris},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
year={2023}
}
@inproceedings{maggiolino2023deepocsort,
title={Deep OC-SORT: Multi-Pedestrian Tracking by Adaptive Re-Identification},
author={Maggiolino, Gerard and Ahmad, Adnan and Cao, Jinkun and Kitani, Kris},
booktitle={IEEE International Conference on Image Processing (ICIP)},
year={2023}
}Distributed under the MIT License. See LICENSE for details.