BotSort
Paper: BoT-SORT: Robust Associations Multi-Pedestrian Tracking
BoT-SORT extends the ByteTrack family by combining motion, appearance, and camera-motion compensation more explicitly. The paper improves the Kalman state, uses global motion compensation, and fuses ReID cues with IoU-based association to make identity assignment more stable in crowded scenes and moving-camera footage. The result is a tracker that is still online and practical, but more robust than motion-only alternatives when identities are ambiguous.
Python AABB mode also supports optional EdgeTAM mask guidance
with --tracker botsort --tracker-backend python --asso-func iou --edgetam --mask-guidance-weights edgetam.pt.
It requires IoU association and per_class=False, retains this tracker's
existing association rules, and adds temporal model inference. Accuracy
gains have not been established for this extension.
What BoxMOT Needs For BotSort
- A detector plus appearance embeddings when
use_embeddings=True. Both the Python implementation and native adapter can generate missing embeddings from a suppliedFrameor consume embeddings already attached toDetections. - Supports both AABB and OBB detections in BoxMOT.
- Best when you need stronger identity preservation than ByteTrack, especially with camera motion or repeated occlusions.
Direct construction accepts reid=ReIDConfig(...) or a prebuilt
AppearanceEncoder, as described in the
Python API.
Lost-track lifetime
max_lost_frames controls lost-track expiry in tracker updates, including updates
with no detections. It defaults to 40 for both AABB and OBB and for both backends.
The value is used directly; input FPS does not rescale it. For example,
BotSortConfig(max_lost_frames=60) sets a 60-update limit.
Expiry keeps the existing association order: matching runs before the lost-track
age check, and removed candidates leave the association pool on the following
update. Newly lost tracks first enter that check on their next update, including
when max_lost_frames=0. The built-in tuning profile searches integer values
from 1 through 199 (range: [1, 200], exclusive upper bound).
Native C++ Backend
BoxMOT also ships a native C++17 BotSort implementation under boxmot/native/cpp/trackers/botsort/. It supports:
- cached
evalandtunestreamed through the live typed API - live
trackthrough--tracker-backend cpp - both AABB and OBB detections for live tracking and cached evaluation
- typed generated or precomputed embeddings supplied through the same v2 update ABI
- model-free C++ tracker code; optional ReID inference is owned by its Python adapter
Requirements:
- C++17 compiler
- CMake 3.16+
- OpenCV 4.x
- Eigen3 3.3+
Example:
boxmot eval --experiment mot17/ablation-yolox-lmbn.yaml --build BUILD_ID --tracker botsort --tracker-backend cpp
boxmot track --tracker botsort --tracker-backend cpp --reid models/lmbn_n_duke.pt --source 0
The native BoT-SORT adapter bypasses its encoder when canonical Detections
already carry embeddings. Otherwise, a non-empty batch can generate them
lazily from its Frame, then pass the typed feature buffer to the C++ tracker.
The C++ library itself never loads or runs a ReID model. Python BoT-SORT follows
the same generated-or-attached contract. Materialized builds record the encoder
fingerprint and publish embeddings as keyed Parquet rows. Evaluation streams
those rows through the same live typed API used by track mode; there is no
positional replay executable. See
Native C++ Integration.
Python API
Pass algorithm settings through BotSortConfig, for example
BotSort(config=BotSortConfig(match_thresh=0.8)). Direct construction and
create_tracker("botsort") use the same algorithm defaults. See the
tracker configuration guide for presets and component settings.
Bases: TrackerConfig
Configure confidence stages, lost-track retention, and appearance matching.
Shared history and association settings are inherited from TrackerConfig.
Match and proximity thresholds apply to overlap metrics. Centroid matching
uses centroid_max_distance while appearance and confidence still rank pairs.
Parameters:
-
track_high_thresh(float, default:0.6296854875023994) –Detection confidence threshold for first-pass matching.
-
track_low_thresh(float, default:0.1014392537025336) –Lower confidence bound for second-pass candidates.
-
new_track_thresh(float, default:0.6246494191492591) –Minimum confidence required to initialize a new track.
-
max_lost_frames(int, default:40) –Maximum missed tracker updates before a lost track is marked removed. Measured directly in frames, without FPS scaling.
-
match_thresh(float, default:0.7722224024589055) –Maximum assignment cost for first-pass matching.
-
proximity_thresh(float, default:0.6084297894561342) –Maximum geometry distance that permits appearance matching.
-
appearance_thresh(float, default:0.6188818853936099) –Maximum embedding distance accepted for appearance matching.
-
use_cmc(bool, default:True) –Enable camera-motion compensation; requires image frames.
-
cmc_method(str, default:'sof') –Camera-motion compensation method used when CMC is enabled.
-
fuse_first_associate(bool, default:True) –Fuse detection confidence into the first-pass geometry cost.
-
fuse_unconfirmed_associate(bool, default:True) –Fuse detection confidence into tentative-track costs.
-
motion_fusion(str, default:'off') –First-pass motion handling: off, gate, or gate and blend.
-
motion_fusion_lambda(float, default:0.98) –Existing-cost weight when blending motion distance.
-
motion_fusion_only_position(bool, default:False) –Gate motion using center coordinates only.
-
fuse_iou(bool, default:False) –Combine first-pass appearance distances with IoU when embeddings are enabled.
-
alpha_fixed_emb(float, default:0.9) –Previous-embedding weight in appearance smoothing.
-
duplicate_distance_thresh(float, default:0.15) –Maximum IoU distance for suppressing duplicates between active and lost tracks. Zero disables duplicate suppression.
-
use_embeddings(bool, default:True) –Use supplied appearance embeddings, generating missing embeddings from image frames with the configured ReID backend.
-
second_match_thresh(float, default:0.28795081514328974) –Maximum assignment cost for low-confidence detections.
-
unconfirmed_match_thresh(float, default:0.41148010638233784) –Maximum assignment cost for tentative tracks.
-
unconfirmed_emb_scale(float, default:2.5445206391993294) –Divisor applied to tentative-track embedding distances.
-
removed_stracks_buffer(int, default:329) –Maximum number of removed tracks retained in history.
-
det_thresh(float, default:0.3) –Minimum detection confidence for the shared tracking kernel.
Bases: BoxTracker
Track AABB or OBB detections with two-stage matching, CMC, and optional ReID.
Attributes:
-
lost_stracks(list[STrack]) –Tracks kept in the lost state.
-
removed_stracks(list[STrack]) –Tracks removed from the tracker state.
-
max_lost_frames(int) –Maximum missed tracker updates before lost-track removal.
-
kalman_filter(KalmanFilterXYWH) –Motion model used for prediction.
-
cmc–Camera-motion compensation method.
Detection filtering uses track_high_thresh and track_low_thresh; lost-track retention uses max_lost_frames counted in tracker updates.
Parameters:
-
config(BotSortConfig | None, default:None) –Immutable algorithm settings. None selects BotSortConfig defaults.
-
kalman(KalmanConfig | None, default:None) –Immutable filter noise, timing, and supported behavior settings. None preserves tracker defaults.
-
reid(ReIDConfig | AppearanceEncoder | None, default:None) –Immutable encoder configuration or a canonical appearance encoder. Missing embeddings are generated lazily; None selects the default encoder.
-
**kwargs(Unpack[BoxTrackerOptions], default:{}) –Runtime
per_class,is_obb,class_ids,class_names,mask_guidance, andedgetamsettings.