Ultralytics YOLO27:

Multi-Object Tracking with Ultralytics YOLO#

YOLO multi-object tracking with trajectory paths

Object tracking in the realm of video analytics is a critical task that not only identifies the location and class of objects within the frame but also maintains a unique ID for each detected object as the video progresses. The applications are limitlessโ€”ranging from surveillance and security to real-time sports analytics.

See the unreleased YOLO27 preview for planned tracking support.

๐Ÿš€ New Trackers: OC-SORT, Deep OC-SORT, FastTracker, TrackTrack

Starting with ultralytics 8.4.63, OC-SORT, Deep OC-SORT, FastTracker, and TrackTrack are available alongside BoT-SORT and ByteTrack.

Why Choose Ultralytics YOLO for Object Tracking?#

The output from Ultralytics trackers is consistent with standard object detection but has the added value of object IDs. This makes it easy to track objects in video streams and perform subsequent analytics. Here's why you should consider using Ultralytics YOLO for your object tracking needs:

  • Efficiency: Process video streams in real-time without compromising accuracy.
  • Flexibility: Supports multiple tracking algorithms and configurations.
  • Ease of Use: Simple Python API and CLI options for quick integration and deployment.
  • Customizability: Easy to use with custom-trained YOLO models, allowing integration into domain-specific applications.


Watch: How to Run Multi-Object Tracking with Ultralytics YOLO26 | BoT-SORT & ByteTrack | VisionAI ๐Ÿš€

Real-world Applications#

TransportationRetailAquaculture
Vehicle TrackingPeople TrackingFish Tracking

Quick Start#

Run tracking on a video with the default TrackTrack tracker. Swap to another tracker by changing the tracker argument.

Example
from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Default tracker (TrackTrack)
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True)

# Switch to ByteTrack
results = model.track(source="https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml")

To run the tracker on video streams, use a trained Detect, Segment, Pose, or OBB model such as YOLO26n, YOLO26n-seg, YOLO26n-pose, or YOLO26n-obb. You can train custom models locally or with Ultralytics Platform cloud training.

Example
from ultralytics import YOLO

# Load an official or custom model
model = YOLO("yolo26n.pt")  # Load an official Detect model
model = YOLO("yolo26n-seg.pt")  # Load an official Segment model
model = YOLO("yolo26n-pose.pt")  # Load an official Pose model
model = YOLO("path/to/best.pt")  # Load a custom-trained model

# Perform tracking with the model
results = model.track("https://youtu.be/LNwODJXcvt4", show=True)  # Tracking with default tracker
results = model.track("https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml")  # with ByteTrack

Supported Trackers#

Ultralytics YOLO ships with six built-in trackers. Enable one by passing its YAML config file to the tracker argument.

TrackerConfig fileMotion modelAppearance / ReIDCamera motion compensationOcclusion handling
BoT-SORTbotsort.yamlLinear KalmanOptional (with_reid)Configurable (gmc_method)Track buffer + ReID rebinding
ByteTrackbytetrack.yamlLinear KalmanNoneNoTwo-stage low-conf rescue
OC-SORTocsort.yamlObservation-centric KalmanNoneNoORU, OCM, OCR re-update from last observation
Deep OC-SORTdeepocsort.yamlObservation-centric KalmanOptional (with_reid)Configurable (gmc_method)OC-SORT + optional adaptive appearance EMA
FastTrackerfasttrack.yamlLinear Kalman + rollbackNoneNoKalman rollback + bbox enlargement on occlusion
TrackTracktracktrack.yamlLinear Kalman (NSA)Optional (with_reid)Configurable (gmc_method)Iterative multi-cue association + TAI

Which Tracker Should I Use?#

Use this flow to pick a starting point; tracktrack.yaml is used when you pass no tracker:

  1. Need the fastest, simplest baseline? โ†’ ByteTrack (no ReID, no camera-motion compensation, minimum overhead).
  2. Handheld, drone, or moving-camera footage? โ†’ BoT-SORT (adds camera-motion compensation and optional ReID).
  3. Non-linear motion (sports, dancing, abrupt turns) and no ReID? โ†’ OC-SORT (observation-centric corrections without appearance cost).
  4. Crowded moving-camera scenes where ID swaps are the main problem? โ†’ Deep OC-SORT or TrackTrack (both support optional appearance matching; TrackTrack also adds multi-cue association and duplicate-ID suppression).
  5. Frequent partial overlap in real-time, no ReID budget? โ†’ FastTracker (occlusion-aware ByteTrack variant with Kalman rollback).

Switching Trackers#

Pass the tracker config filename to tracker=. All other code stays the same.

Example
from ultralytics import YOLO

model = YOLO("yolo26n.pt")

results = model.track(source="path/to/video.mp4", tracker="bytetrack.yaml")
results = model.track(source="path/to/video.mp4", tracker="ocsort.yaml")
results = model.track(source="path/to/video.mp4", tracker="tracktrack.yaml")

Configuration#

Tracking Arguments#

Tracking configuration shares properties with Predict mode, such as conf, iou, and show. For further configurations, refer to the Predict model page.

Example
from ultralytics import YOLO

# Configure the tracking parameters and run the tracker
model = YOLO("yolo26n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", conf=0.1, iou=0.7, show=True)

Custom Tracker Configuration#

Ultralytics also allows you to use a modified tracker configuration file. To do this, simply make a copy of a tracker config file (for example, custom_tracker.yaml) from ultralytics/cfg/trackers and modify any configurations (except the tracker_type) as per your needs.

Example
from ultralytics import YOLO

# Load the model and run the tracker with a custom configuration file
model = YOLO("yolo26n.pt")
results = model.track(source="https://youtu.be/LNwODJXcvt4", tracker="custom_tracker.yaml")

Shared Tracker Arguments#

The following parameters are common to most tracker YAML files; not every parameter appears in every config:

Tracker Threshold Information

Detections at or above track_high_thresh enter the first association stage. Detections between track_low_thresh and track_high_thresh can recover existing tracks when the selected tracker enables low-confidence association, but they do not start new tracks. Detections at or below track_low_thresh are ignored.

ParameterValid Values or RangesDescription
tracker_typebotsort, bytetrack, ocsort, deepocsort, fasttrack, tracktrackSpecifies the tracker type.
track_high_thresh0.0-1.0Threshold for the first association. Affects how confidently a detection is matched to an existing track.
track_low_thresh0.0-1.0Lower bound for low-confidence recovery detections. OC-SORT and Deep OC-SORT use these only when use_byte: True; TrackTrack includes them in its penalized association pool.
new_track_thresh0.0-1.0Threshold to initialize a new track if the detection does not match any existing tracks.
track_buffer>=0Frames lost tracks are kept alive before removal. Higher value means more tolerance for occlusion.
match_thresh0.0-1.0Threshold for matching tracks. Higher values make matching more lenient.
fuse_scoreTrue, FalseWhether to fuse confidence scores with IoU distances before matching.
gmc_methodsparseOptFlow, orb, sift, ecc, noneGlobal motion compensation method. Helps account for camera movement.
proximity_thresh0.0-1.0Minimum IoU required for a valid ReID match. Ensures spatial closeness before using appearance cues.
appearance_thresh0.0-1.0Minimum normalized appearance similarity required for ReID.
with_reidTrue, FalseEnable appearance-based matching for better tracking across occlusions. Supported by BoT-SORT, Deep OC-SORT, and TrackTrack.
modelauto or compatible ReID model pathReID model. auto uses native YOLO backbone features when available; otherwise falls back to yolo26n-cls.pt. A custom encoder can be a .pt checkpoint or an exported model such as .torchscript, .onnx, .engine, or an OpenVINO model directory.

Tracker-specific Arguments#

Each algorithm exposes additional knobs on top of the shared parameters. See the per-tracker sections below for descriptions and tuning advice, or refer directly to the config files:

Enabling Re-Identification (ReID)#

ReID is disabled by default to minimize overhead. Enable it by setting with_reid: True in a tracker config file.

ReID model options:

  • model: auto โ€” Uses native YOLO detector features, adding minimal overhead. Ideal when you need some ReID without a large performance hit. Falls back to yolo26n-cls.pt if the detector does not expose compatible features.
  • Custom ReID model โ€” Point model: at a .pt checkpoint or a compatible exported embedding model, such as .torchscript, .onnx, .engine, or an OpenVINO model directory. Exported models are loaded through AutoBackend and must output an embedding tensor directly.

Ready-to-use ONNX encoders are published for every model size. Set model: to one of these names and the file is downloaded automatically the first time the tracker runs (the same way YOLO weights are fetched) โ€” no manual export or download step required:

# In your tracker config (e.g. tracktrack.yaml)
with_reid: True
model: yolo26n-reid.onnx # downloaded on first use; swap nโ†’s/m/l/x for a larger encoder
Modelsize
(pixels)
params
(M)
FLOPs
(B)
YOLO26n-reid.onnx4482.82.0
YOLO26s-reid.onnx4487.56.6
YOLO26m-reid.onnx44812.420.1
YOLO26l-reid.onnx44815.325.2
YOLO26x-reid.onnx44832.755.9
ReID is tracking-only

Only ONNX ReID encoders for the tracker appearance branch are currently available. ReID train, val, and predict modes, as well as dedicated ReID export recipes, are still under development.

For better performance with a separate classification model, export it to a faster backend like TensorRT:

Exporting a ReID model to TensorRT
from torch import nn

from ultralytics import YOLO

# Load the classification model
model = YOLO("yolo26n-cls.pt")

# Add average pooling layer
head = model.model.model[-1]
pool = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)), nn.Flatten(start_dim=1))
pool.f, pool.i = head.f, head.i
model.model.model[-1] = pool

# Export to TensorRT
model.export(format="engine", quantize=16, dynamic=True, batch=32)

Once exported, point to the TensorRT model path in your tracker config.

Tracker Details#

The sections below describe each tracker's design, specific parameters, and tuning tips.



Watch: Which Object Tracker Performs Better? | Speed, FPS & ID Stability | Ultralytics YOLO26 ๐Ÿ“Š

BoT-SORT#

BoT-SORT (Aharon et al., 2022) extends ByteTrack with camera-motion compensation and optional ReID:

  • Camera Motion Compensation (CMC): an affine warp estimated each frame (sparse optical flow by default; ORB / ECC also available) is applied to Kalman states before IoU matching.
  • Optional ReID: appearance embeddings can be fused into the cost matrix. Disabled by default; enable with with_reid: True.

Best for: general-purpose tracking, especially moving cameras. Add ReID only when look-alike crowds cause ID swaps.

BoT-SORT-specific arguments:

ParameterValid Values or RangesDescription
gmc_methodsparseOptFlow, orb, sift, ecc, noneCamera-motion-compensation backend. sparseOptFlow is the default. none disables CMC.
with_reidTrue, FalseEnable appearance-based matching. Off by default.
modelauto or compatible ReID model pathauto uses native YOLO features when available; custom models can be .pt checkpoints or compatible exports.
proximity_thresh0.0-1.0Minimum IoU before appearance features are considered.
appearance_thresh0.0-1.0Minimum normalized appearance similarity required for a ReID match. Raise to make matching stricter.

Tuning tips: