Skip to main content

A unified library for object tracking featuring clean room re-implementations of leading multi-object tracking algorithms

Project description

version downloads license python-version discord

trackers

trackers logo

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trackers-2.1.0.tar.gz (137.7 kB view details)

Uploaded Source

Built Distribution

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

trackers-2.1.0-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

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

Hashes for trackers-2.1.0.tar.gz
Algorithm Hash digest
SHA256 101f75852e66e02b7d13fa0ecf664a9487703295e928054d61626dc0365dc52c
MD5 caf7cbec901e318b51f05b2c76cfb7cb
BLAKE2b-256 cbb8ca88a7eed9ab71e1127ee30fc8298870c58cb71d373a8a5681e553ea620b

See more details on using hashes here.

Provenance

The following attestation bundles were made for trackers-2.1.0.tar.gz:

Publisher: publish-release.yml on roboflow/trackers

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for trackers-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 34da8808296a7c0853dc2b79144c747895191a14b662510c8fd1fafd76f65409
MD5 3f21b343c6f88fda54cda06860f8e283
BLAKE2b-256 f81367d22ca50f35c8b89466019e97c60751d919824c8a88162160ad9a550abd

See more details on using hashes here.

Provenance

The following attestation bundles were made for trackers-2.1.0-py3-none-any.whl:

Publisher: publish-release.yml on roboflow/trackers

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page