Tracker YAMLs
Algorithm defaults live in immutable Python config classes such as
BotSortConfig. Each boxmot/configs/trackers/<tracker>.yaml file defines the
corresponding tuning search space and shared component settings. Every searchable
parameter includes an explicit default; algorithm defaults must match the
value and type in the corresponding Python config. Tuned presets live under
boxmot/configs/trackers/presets. Single-profile presets are runtime
overlays and declare their owning tracker with a top-level tracker field.
The EagerMOT eagermot-kitti-mots-val.yaml preset contains both car and
pedestrian profiles and loads through --class-config; see
the evaluation example.
Role
The filename matches the tracker name used from the CLI:
--tracker bytetrackloadsboxmot/configs/trackers/bytetrack.yaml--tracker boosttrackloadsboxmot/configs/trackers/boosttrack.yaml
Runtime vs tuning
Runtime defaults and optimization policy are resolved together:
track,eval, the Python factory, and direct tracker classes use the same typed algorithm defaults- YAML presets overlay those defaults
tunereadstype,range,options,values,activates,depends_on,cases,geometry, andassociation
Search entries can declare geometry: aabb or geometry: obb. Image tuning
keeps entries for the other geometry fixed at their runtime values, including
any conditional descendants. OccluBoost uses this to exclude OBB thresholds
from AABB searches and AABB-only settings from OBB searches.
Select the backend for the run with --tracker-backend; it is not a search
dimension. BoT-SORT, ByteTrack, and OccluBoost share their new algorithm controls
and search ranges across the Python and C++ implementations.
Algorithm fields omitted from a tuning profile retain their typed defaults and
are not searched. Built-in YAMLs omit unused inherited fields and display-only
controls. Empty mappings ({}) keep effective setup parameters fixed, such as
camera-motion settings, input frame dimensions, and recovery-history capacity.
For example, OC-SORT searches iou_threshold over [0.1, 0.7], while its recovery
history max_obs stays fixed; StrongSORT searches
nn_budget over [25, 50, 100, 200] appearance features per track.
ByteTrack and BotSort search max_lost_frames directly over integers 1 through
199 (range: [1, 200]). This lifetime counts tracker updates and is independent
of input FPS in both geometries and backends.
For shared component settings, an entry with only default is also fixed. If that entry controls an activates
block, a true value enables the children's search ranges and a false value
keeps the children fixed. A searchable parent's default does not fix its
children: the selected trial value controls Optuna and HyperOpt branches.
Random search samples variable branches as a flat space.
Use association to declare which metrics a search parameter applies to.
An overlap threshold is searched only for the listed overlap metrics, while
the centroid radius is searched only when asso_func is centroid:
iou_threshold:
association: [iou, giou, diou, ciou, hmiou]
type: uniform
default: 0.3
range: [0.1, 0.9]
centroid_max_distance:
association: [centroid]
type: uniform
default: 0.05
range: [0.005, 0.1]
Parameters outside their applicable metrics are not searched; their typed or
authored runtime values are retained. association works together with
geometry and activates, and applies to random, Optuna, and HyperOpt search,
whether asso_func is fixed or searched. Centroid ignores overlap thresholds
at runtime and uses centroid_max_distance for distance eligibility. Optional
Kalman motion fusion adds its own uncertainty gate in the first association pass.
Use depends_on and cases when an applicable parameter needs different numeric
ranges for different metrics, as ByteTrack does for GIoU, DIoU, and CIoU.
Searchable parameters inside activates blocks and parameters searched only in
a case also declare their defaults on the parameter entry. Case fragments inherit
that default unless they override it. Cases override the base distribution;
a case containing only default fixes that value, including when a runtime
profile supplies a different starting
value. Without a matching case, the base distribution applies, or the runtime
default if no distribution exists.
Python algorithm configs
Pass algorithm settings through a matching config class. Component settings and geometry/class selection stay on the constructor:
from boxmot import BotSort, BotSortConfig, ReIDConfig
tracker = BotSort(
config=BotSortConfig(match_thresh=0.8, max_lost_frames=40),
reid=ReIDConfig(device="cpu"),
per_class=True,
)
All eleven trackers expose a <TrackerName>Config from boxmot. Configs are
frozen dataclasses with validation, to_dict(), and from_mapping().
tracker.config contains the resolved algorithm settings. See
tracker classes and autocomplete
for the complete list and factory override precedence.
Useful algorithm controls include:
| Tracker | Controls |
|---|---|
| BoT-SORT | alpha_fixed_emb controls appearance smoothing; fuse_unconfirmed_associate controls tentative-track score fusion. |
| ByteTrack | fuse_first_associate and fuse_unconfirmed_associate control score fusion in the two high-confidence association stages. |
| BoT-SORT / ByteTrack | duplicate_distance_thresh controls active/lost duplicate suppression using IoU distance, independently of the association metric. Zero disables suppression. |
| BoostTrack / OccluBoost | alpha_fixed_emb, lambda_emb_multiplier, appearance_thresh, and appearance_iou_fraction configure first-pass appearance matching; dlo_soft_alpha, dlo_soft_power, dlo_threshold_start, and dlo_threshold_end configure DLO boosting; duo_mahalanobis_thresh and duo_iou_thresh configure DUO boosting. track_confidence_decay and track_confidence_warmup control track confidence. |
| StrongSORT | gating_only_position selects position-only motion gating; geometric_recovery_max_age controls how long unmatched tracks can use geometric recovery. |
| HybridSORT | confidence_floor sets the lower bound on predicted confidence in AABB mode. |
| MAF-HDA | kcf_padding, kcf_sigma, kcf_regularization, and kcf_output_sigma_factor configure its appearance filter. kcf_update_mode chooses template reinitialization or interpolation; kcf_interp_factor applies to interpolation. max_area_ratio, min_intersection_ratio, and recovery_overlap_thresh configure non-centroid geometric gates. |
Their defaults preserve the original algorithms. For example, this runtime preset adjusts BoT-SORT's appearance smoothing and duplicate suppression:
tracker: botsort
alpha_fixed_emb: 0.8
duplicate_distance_thresh: 0.1
fuse_unconfirmed_associate: false
These BoT-SORT overrides and the new ByteTrack and OccluBoost algorithm controls work with both tracker backends. Rebuild native libraries after upgrading to the expanded configuration ABI.
Kalman noise
Runtime YAML groups all configurable Kalman settings under kalman. Covariance
scales and their unit metadata belong to its noise group:
tracker: ocsort
kalman:
variable_dt: false
noise:
process_position_scale: 1.0
process_velocity_scale: 1.0
measurement_noise_scale: 1.0
initial_position_scale: 1.0
initial_velocity_scale: 1.0
reference_dt_s: 0.03333333333333333
time_unit: frames
Pass the file through --tracker-config. Partial profiles override individual
fields; omitted fields retain the tracker defaults. Python uses the corresponding
KalmanConfig object through the kalman constructor argument. Its noise
field accepts a KalmanNoiseConfig.
kalman.variable_dt selects capture timing. Fresh noise settings can use
time_unit: null to derive units from it; calibrated profiles save the resolved
unit. Timing and the reference interval remain fixed during tuning.
kalman.adaptive_kf selects innovation-based adaptation in BoostTrack and
OccluBoost. kalman.is_angular selects EagerMOT's object yaw-velocity state.
OccluBoost's kalman.ams group holds enabled, alpha0, threshold,
buffer_size, and shrink_ratio for its AABB gain-suppression policy. Other
trackers reject these policy groups. kalman.type selects a compatible Python
2D filter (xyah, xywh, xysr, xyhr, or xyscr). Built-in 2D Kalman
profiles search these five named types and declare explicit defaults:
| Tracker | Default kalman.type |
|---|---|
| ByteTrack, StrongSORT | xyah |
| BoT-SORT | xywh |
| OC-SORT, DeepOC-SORT | xysr |
| HybridSORT | xyscr |
| BoostTrack, OccluBoost | xyhr |
The Python factory and CLI use these YAML defaults for both AABB and OBB.
Direct constructors without a Kalman configuration use their geometry-dependent
filter defaults; explicitly supplying kalman.type: null also requests that
fallback. For OBB, that fallback is xywh for ByteTrack and StrongSORT and
xysr for HybridSORT. An explicit runtime
kalman.type, calibration, covariance vectors, or adaptive KF policy fixes
the filter; C++ tuning keeps its native filter. Use
tune --select-kf to
compare types and noise profiles before tuning tracker thresholds.
For 2D calibration, the five covariance groups also support coordinate vectors:
process_position_diagonal, process_velocity_diagonal,
measurement_noise_diagonal, initial_position_diagonal, and
initial_velocity_diagonal. Their lengths match the selected filter's
measurement coordinates. Calibration fits these vectors and saves the global
*_scale multipliers as 1.0; explicit --tune-kf options refine those
multipliers while preserving the fitted coordinate ratios. EagerMOT's 3D
calibration continues to use five scalar scales.
With per-class tracking, kalman.noise.by_class maps detector class IDs to
complete noise profiles. Unlisted classes use the global profile. Calibration
with --per-class writes these profiles and records when a class used pooled
estimates because it lacked sufficient evidence.
Calibrated files also carry a calibration mapping describing the tracker,
backend, geometry, filter dimensions, and timing basis. Loading validates that
signature before creating a tracker. A single-class profile also binds the
factory's class selection. The YAML is portable without its report sidecar;
dataset and split identify the calibration evidence and allow reuse on held-out
data.
Built-in search schemas use the same group, with a default entry for each
field. Search backends address scalar leaves such as
kalman.noise.measurement_noise_scale. Noise scales stay fixed unless selected
with --tune-kf; see Kalman tuning.
EagerMOT class profiles
EagerMOT sensor evaluation loads both class profiles from one YAML through
--class-config. The saved eagermot-kitti-mots-val.yaml preset contains
car and pedestrian mappings; tuning writes the same format to best.yaml.
Association function
The 2D box trackers and MAF-HDA expose asso_func through the same config
entry. AABB and OBB box tracking both support iou, giou, diou, ciou,
hmiou, and centroid; EagerMOT uses IoU for its image associations.
Select a metric without editing the built-in file by
passing a runtime override:
from boxmot import create_tracker
from boxmot.trackers import TrackerSpec
tracker = create_tracker(
TrackerSpec(
name="ocsort",
geometry="aabb",
options=(("asso_func", "centroid"), ("centroid_max_distance", 0.05)),
)
)
For live tracking or evaluation from the CLI, use the same selector directly:
boxmot track --tracker bytetrack --asso-func giou --source video.mp4
boxmot eval --dataset mot17 --build BUILD_ID --tracker ocsort --asso-func centroid
For OBB detections, BoxMOT uses these exact definitions:
asso_func |
Status | OBB similarity |
|---|---|---|
iou |
Supported | IoU from the intersection and union of the two oriented rectangles. |
giou |
Supported | Oriented IoU with the unused area in the convex hull of both rectangles as the GIoU penalty. |
diou |
Supported | Oriented IoU with squared center distance normalized by the squared diagonal of the rotation-invariant, minimum-area oriented rectangle enclosing both boxes. |
ciou |
Experimental | The OBB DIoU construction plus a custom aspect-ratio penalty computed from each box's ordered long and short sides. |
hmiou |
Experimental | Oriented IoU multiplied by the interval IoU of the boxes' projections onto the image's global y-axis. |
centroid |
Supported | 1 - center_distance / (centroid_max_distance * frame_diagonal), with pairs outside the radius forbidden. |
GIoU, DIoU, and CIoU are transformed with (score + 1) / 2 before
association. OBB results are defensively clipped to [0, 1]; AABB CIoU uses
the same clipping.
OBB ciou is an experimental, representation-invariant adaptation of the AABB
aspect-ratio term; it is not a canonical rotated-CIoU definition. OBB hmiou
is also experimental. Its global-y projection follows the screen-space height
cue from Hybrid-SORT, so use it only when
image vertical has a meaningful relationship to object height or depth, such as
upright subjects under a stable camera. It is not rotation-invariant and is
usually unsuitable for arbitrary-heading aerial objects. Retune association
thresholds when changing metrics.
Centroid association needs the frame dimensions for normalization, so trackers
using it need an image until those dimensions have been initialized. SFSORT can
instead use the explicit frame_width and frame_height fields in SFSORTConfig.
centroid_max_distance is a positive fraction of the frame diagonal, at most
1.0, with a runtime default of 0.05. On a 1920×1080 frame, 0.05 gives a
maximum center displacement of approximately 110 pixels. This hard distance
limit applies to every matching and recovery pass; appearance similarity cannot
override it. Overlap thresholds do not add another centroid distance cutoff:
settings such as iou_threshold, match_thresh, and proximity_thresh do not
tighten the radius, even when supplied through a runtime profile. The tracker
still uses its confidence, appearance, and lifecycle rules, and competing pairs
are ranked by its association scores. A pair inside the radius is eligible for
geometric matching, rather than guaranteed a match. With optional motion fusion,
the first pass also requires the pair to pass the Kalman uncertainty gate.
IoU and the other metrics ignore centroid_max_distance.
ByteTrack exposes second_match_thresh and unconfirmed_match_thresh alongside
match_thresh for other metrics. Their runtime defaults remain 0.5 and 0.7.
Centroid uses the same radius in the high-confidence, low-confidence, and
unconfirmed passes. A centroid runtime profile needs only the metric and radius:
The native backends expose the same choices for both box layouts; see the native tracker documentation for C++ integration details.
Association fusion
Python trackers expose fusion controls where their association cues support them. New controls default to disabled; StrongSORT retains its existing motion blend and ByteTrack/BotSort retain their existing score-fusion defaults. Built-in tuning profiles search the relevant switches automatically.
| Tracker | Motion fusion | Detection-confidence fusion | ReID–IoU fusion |
|---|---|---|---|
| ByteTrack | Optional, first pass | Existing first/unconfirmed switches | Unavailable; no ReID |
| BotSort | Optional, first pass | Existing first/unconfirmed switches | Optional, first pass with embeddings |
| OC-SORT | Optional, first pass | Optional, first pass | Unavailable; no ReID |
| DeepOCSORT, HybridSORT, BoostTrack, OccluBoost | Optional, first pass | Optional, first pass | Optional, first pass with embeddings |
| StrongSORT | Existing blend; selectable off/gate/blend | Optional, appearance pass | Optional, appearance pass |
| SFSORT | Unavailable; no Kalman filter | Optional, first pass | Unavailable; no ReID |
| MAF-HDA | Uses its own motion-affinity model | Optional, segment-to-track pass | Unavailable; uses KCF appearance |
EagerMOT retains its separate 3D/sensor association workflow.
motion_fusion accepts off, gate, or blend. gate rejects pairs outside
the 95% chi-square region without changing other costs. blend also computes
lambda * cost + (1 - lambda) * squared_mahalanobis_distance. The distance is
not normalized, so changing the blend can require different matching thresholds.
motion_fusion_lambda defaults to 0.98 and is searched only for blend;
motion_fusion_only_position defaults to false and is searched only when motion
fusion is enabled. StrongSORT uses its existing mc_lambda and
gating_only_position names for these two settings.
Motion fusion uses each track's selected KF, covariance, and predicted state
after CMC. Full geometry uses four measurement coordinates for AABB or five for
OBB; position-only gating uses two. Confidence in an XYSCR state is excluded
from the geometry gate. OBB measurements are aligned to equivalent rectangles
before angular residuals are computed. Motion gates remain hard constraints
through mask conditioning and assignment. They apply to the first pass only;
later recovery passes keep their existing rules.
HybridSORT applies first-pass fusion in AABB mode only when tcm_first_step
is enabled; its OBB first pass runs independently of that setting.
fuse_iou multiplies appearance similarity by (1 + IoU) / 2, using oriented
IoU for OBB. It is searched only when appearance embeddings are enabled.
fuse_detection_score multiplies the first-pass similarity by detection
confidence. ByteTrack and BotSort keep their existing score-fusion option names.
MAF-HDA applies equivalent confidence weighting in its log-affinity cost scale;
it does not apply this weighting to tracklet recovery.
For example, this runtime profile enables ByteTrack motion gating without requiring a ReID model:
Use it with --tracker-config bytetrack-motion.yaml in track or eval.
For tune, runtime values set the baseline and the shipped search profile can
still vary the fusion settings. Start a new tuning run to search new dimensions;
an already running study retains its original search space. Resuming requires
the saved and requested search spaces to match.
The new fusion switches currently require the Python backend. Native C++ tuning keeps them disabled and native constructors reject explicitly enabled options. Existing native score fusion remains supported.
Example schema
track_thresh:
type: uniform
default: 0.6
range: [0.4, 0.7]
max_lost_frames:
type: randint
default: 30
range: [1, 200]
The tracker name selects its combined built-in file. track and eval accept
--tracker-config to overlay a runtime YAML file or a built-in preset. Explicit
runtime flags override the loaded values. The Python factory accepts a canonical
TrackerSpec; place scalar overrides in its sorted options tuple. Tuning
writes resolved runtime YAML that can be reused with --tracker-config.