A unified library for object tracking featuring clean room re-implementations of leading multi-object tracking algorithms
Project description
trackers
Trackers gives you clean, modular re-implementations of leading multi-object tracking algorithms released under the permissive Apache 2.0 license. You combine them with any detection model you already use.
https://github.com/user-attachments/assets/eef9b00a-cfe4-40f7-a495-954550e3ef1f
Install
You can install and use trackers in a Python>=3.10 environment. For detailed installation instructions, including installing from source and setting up a local development environment, check out our install page.
pip install trackers
install from source
By installing trackers from source, you can explore the most recent features and enhancements that have not yet been officially released. Please note that these updates are still in development and may not be as stable as the latest published release.
pip install https://github.com/roboflow/trackers/archive/refs/heads/develop.zip
Tracking Algorithms
Trackers gives you clean, modular re-implementations of leading multi-object tracking algorithms. The package currently supports SORT and ByteTrack. OC-SORT support is coming soon. For full results, see the benchmarks page.
| Algorithm | Trackers API | MOT17 HOTA | MOT17 IDF1 | MOT17 MOTA | SportsMOT HOTA | SoccerNet HOTA |
|---|---|---|---|---|---|---|
| SORT | SORTTracker |
58.4 | 69.9 | 67.2 | 70.9 | 81.6 |
| ByteTrack | ByteTrackTracker |
60.1 | 73.2 | 74.1 | 73.0 | 84.0 |
| OC-SORT | OCSORTTracker |
— | — | — | — | — |
Quickstart
With a modular design, Trackers lets you combine object detectors from different libraries with the tracker of your choice. Here's how you can use ByteTrack with various detectors. These examples use OpenCV for decoding and display. Replace <SOURCE_VIDEO_PATH> with your input.
import cv2
import supervision as sv
from rfdetr import RFDETRMedium
from trackers import ByteTrack
tracker = ByteTrack()
model = RFDETRMedium()
box_annotator = sv.BoxAnnotator()
label_annotator = sv.LabelAnnotator()
video_capture = cv2.VideoCapture("<SOURCE_VIDEO_PATH>")
if not video_capture.isOpened():
raise RuntimeError("Failed to open video source")
while True:
success, frame_bgr = video_capture.read()
if not success:
break
frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
detections = model.predict(frame_rgb)
detections = tracker.update(detections)
annotated_frame = box_annotator.annotate(frame_bgr, detections)
annotated_frame = label_annotator.annotate(annotated_frame, detections, labels=detections.tracker_id)
cv2.imshow("RF-DETR + ByteTrack", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video_capture.release()
cv2.destroyAllWindows()
run with Inference
import cv2
import supervision as sv
from inference import get_model
from trackers import ByteTrack
tracker = ByteTrack()
model = get_model(model_id="rfdetr-medium")
box_annotator = sv.BoxAnnotator()
label_annotator = sv.LabelAnnotator()
video_capture = cv2.VideoCapture("<SOURCE_VIDEO_PATH>")
if not video_capture.isOpened():
raise RuntimeError("Failed to open video source")
while True:
success, frame_bgr = video_capture.read()
if not success:
break
frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
result = model.infer(frame_rgb)[0]
detections = sv.Detections.from_inference(result)
detections = tracker.update(detections)
annotated_frame = box_annotator.annotate(frame_bgr, detections)
annotated_frame = label_annotator.annotate(annotated_frame, detections, labels=detections.tracker_id)
cv2.imshow("Inference + ByteTrack", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video_capture.release()
cv2.destroyAllWindows()
run with Ultralytics
import cv2
import supervision as sv
from ultralytics import YOLO
from trackers import ByteTrack
tracker = ByteTrack()
model = YOLO("yolo26m.pt")
box_annotator = sv.BoxAnnotator()
label_annotator = sv.LabelAnnotator()
video_capture = cv2.VideoCapture("<SOURCE_VIDEO_PATH>")
if not video_capture.isOpened():
raise RuntimeError("Failed to open video source")
while True:
success, frame_bgr = video_capture.read()
if not success:
break
frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
result = model(frame_rgb)[0]
detections = sv.Detections.from_ultralytics(result)
detections = tracker.update(detections)
annotated_frame = box_annotator.annotate(frame_bgr, detections)
annotated_frame = label_annotator.annotate(annotated_frame, detections, labels=detections.tracker_id)
cv2.imshow("Ultralytics + ByteTrack", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video_capture.release()
cv2.destroyAllWindows()
run with Transformers
import torch
import cv2
import supervision as sv
from trackers import ByteTrack
from transformers import RTDetrImageProcessor, RTDetrV2ForObjectDetection
tracker = ByteTrack()
processor = RTDetrImageProcessor.from_pretrained("PekingU/rtdetr_v2_r18vd")
model = RTDetrV2ForObjectDetection.from_pretrained("PekingU/rtdetr_v2_r18vd")
box_annotator = sv.BoxAnnotator()
label_annotator = sv.LabelAnnotator()
video_capture = cv2.VideoCapture("<SOURCE_VIDEO_PATH>")
if not video_capture.isOpened():
raise RuntimeError("Failed to open video source")
while True:
success, frame_bgr = video_capture.read()
if not success:
break
frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
inputs = processor(images=frame_rgb, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
h, w = frame_bgr.shape[:2]
results = processor.post_process_object_detection(
outputs,
target_sizes=torch.tensor([[h, w]]),
threshold=0.5
)[0]
detections = sv.Detections.from_transformers(
transformers_results=results,
id2label=model.config.id2label
)
detections = tracker.update(detections)
annotated_frame = box_annotator.annotate(frame_bgr, detections)
annotated_frame = label_annotator.annotate(annotated_frame, detections, labels=detections.tracker_id)
cv2.imshow("Transformers + ByteTrack", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video_capture.release()
cv2.destroyAllWindows()
License
The code is released under the Apache 2.0 license.
Contribution
We welcome all contributions—whether it’s reporting issues, suggesting features, or submitting pull requests. Please read our contributor guidelines to learn about our processes and best practices.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 trackers-2.1.0.tar.gz.
File metadata
- Download URL: trackers-2.1.0.tar.gz
- Upload date:
- Size: 137.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
101f75852e66e02b7d13fa0ecf664a9487703295e928054d61626dc0365dc52c
|
|
| MD5 |
caf7cbec901e318b51f05b2c76cfb7cb
|
|
| BLAKE2b-256 |
cbb8ca88a7eed9ab71e1127ee30fc8298870c58cb71d373a8a5681e553ea620b
|
Provenance
The following attestation bundles were made for trackers-2.1.0.tar.gz:
Publisher:
publish-release.yml on roboflow/trackers
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trackers-2.1.0.tar.gz -
Subject digest:
101f75852e66e02b7d13fa0ecf664a9487703295e928054d61626dc0365dc52c - Sigstore transparency entry: 868085556
- Sigstore integration time:
-
Permalink:
roboflow/trackers@e4cc6233a2dd22ed018a4f12f08b731a5887b045 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/roboflow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-release.yml@e4cc6233a2dd22ed018a4f12f08b731a5887b045 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file trackers-2.1.0-py3-none-any.whl.
File metadata
- Download URL: trackers-2.1.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34da8808296a7c0853dc2b79144c747895191a14b662510c8fd1fafd76f65409
|
|
| MD5 |
3f21b343c6f88fda54cda06860f8e283
|
|
| BLAKE2b-256 |
f81367d22ca50f35c8b89466019e97c60751d919824c8a88162160ad9a550abd
|
Provenance
The following attestation bundles were made for trackers-2.1.0-py3-none-any.whl:
Publisher:
publish-release.yml on roboflow/trackers
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
trackers-2.1.0-py3-none-any.whl -
Subject digest:
34da8808296a7c0853dc2b79144c747895191a14b662510c8fd1fafd76f65409 - Sigstore transparency entry: 868085557
- Sigstore integration time:
-
Permalink:
roboflow/trackers@e4cc6233a2dd22ed018a4f12f08b731a5887b045 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/roboflow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-release.yml@e4cc6233a2dd22ed018a4f12f08b731a5887b045 -
Trigger Event:
workflow_dispatch
-
Statement type: