association
sleap_nn.tracking.mot.association
¶
Similarity matrices, gates and assignment helpers for the MOT trackers.
Every function here is vectorized and NaN-free on output unless documented.
Similarities are in [0, 1]; costs are 1 - similarity. Rows are tracks
(or the first argument), columns are detections (or the second argument). Every
function accepts empty inputs and returns correctly shaped (n, 0) /
(0, m) results.
Functions:
| Name | Description |
|---|---|
adaptive_weight |
Deep OC-SORT adaptive weighting of the appearance matrix |
appearance_margins |
Top-1 minus top-2 cosine per row and per column over finite entries. |
centroid_similarity |
Gaussian similarity |
cosine_matrix |
Cosine similarity of L2-normalized vectors; NaN where either is missing. |
decisive_cells |
Cells where appearance decides a pair (per cell, not per row/column). |
fuse_score |
ByteTrack score fusion: |
ioa_min_matrix |
Intersection over the smaller area (duplicate detection); NaN boxes score 0. |
iou_matrix |
IoU between |
linear_assignment |
Minimum-cost assignment with a cost cap. |
linear_assignment_masked |
Maximum-score assignment, keeping only |
ocm_matrix |
OC-SORT observation-centric momentum term. |
oks_matrix |
Object keypoint similarity between two sets of poses. |
one_to_one_pattern |
OC-SORT/SORT shortcut: the valid pairs if they form a 1:1 pattern. |
speed_direction |
Unit |
adaptive_weight(E, aw_param=0.5, base=0.75)
¶
Deep OC-SORT adaptive weighting of the appearance matrix E.
W = base + 0.5 * min(row_top1 - row_top2, aw_param) + 0.5 * min(col_top1 -
col_top2, aw_param), computed only when E has at least 2 rows and 2
columns; otherwise every entry is base.
Non-finite entries of E are ignored when ranking; a row or column with
fewer than two finite entries gets no bonus.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
E
|
ndarray
|
|
required |
aw_param
|
float
|
Cap on each margin bonus (Deep OC-SORT |
0.5
|
base
|
float
|
Constant weight (Deep OC-SORT |
0.75
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
appearance_margins(cos)
¶
Top-1 minus top-2 cosine per row and per column over finite entries.
A row/column with a single finite entry has margin inf; with none, nan.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cos
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
Tuple[ndarray, ndarray]
|
|
Source code in sleap_nn/tracking/mot/association.py
centroid_similarity(c_a, c_b, scale)
¶
Gaussian similarity exp(-d^2 / (2 scale^2)) of (n, 2) vs (m, 2) points.
NaN points score 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
c_a
|
ndarray
|
|
required |
c_b
|
ndarray
|
|
required |
scale
|
float
|
Gaussian scale in px ( |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in sleap_nn/tracking/mot/association.py
cosine_matrix(e_a, ok_a, e_b, ok_b)
¶
Cosine similarity of L2-normalized vectors; NaN where either is missing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
e_a
|
ndarray
|
|
required |
ok_a
|
ndarray
|
|
required |
e_b
|
ndarray
|
|
required |
ok_b
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
decisive_cells(cos, admissible, margin=0.0)
¶
Cells where appearance decides a pair (per cell, not per row/column).
A cell is decisive when it is admissible and its cosine is the top admissible
cosine of its row AND of its column, with each top-1 minus top-2 margin
strictly positive and at least margin (a lone admissible cell has an
infinite margin). A row's runner-up is never decisive, even when the row's
margin is large: appearance ranks it below another candidate. Shared by
BoT-SORT's appearance discount (admissible: inside the proximity and
appearance gates) and Deep OC-SORT's rescue rule (admissible: geometrically
plausible).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cos
|
ndarray
|
|
required |
admissible
|
ndarray
|
|
required |
margin
|
float
|
Minimum row and column margin (the calibrated |
0.0
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
fuse_score(sim, det_scores)
¶
ByteTrack score fusion: sim * det_scores[None, :].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sim
|
ndarray
|
|
required |
det_scores
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
ioa_min_matrix(a, b)
¶
Intersection over the smaller area (duplicate detection); NaN boxes score 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
ndarray
|
|
required |
b
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
iou_matrix(a, b)
¶
IoU between (n, 4) and (m, 4) xyxy boxes; NaN boxes score 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
ndarray
|
|
required |
b
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
linear_assignment(cost, max_cost)
¶
Minimum-cost assignment with a cost cap.
Entries above max_cost or non-finite are infeasible: they are replaced by
max_cost + 1e-5 before solving with
:func:scipy.optimize.linear_sum_assignment, and matched pairs that were
infeasible are then dropped. Pricing a forbidden pair just above the cap
(DeepSORT's max_distance + 1e-5; equivalently ByteTrack/BoT-SORT's
lapjv(cost_limit=max_cost)) means leaving a row and a column unmatched
costs about max_cost: the solver never pulls a track off a confident
match just to squeeze in more matches. With an infinite max_cost only
non-finite entries are infeasible (priced INFEASIBLE_COST above the
largest finite cost). Empty matrices are handled; the result is
deterministic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cost
|
ndarray
|
|
required |
max_cost
|
float
|
Largest admissible cost of a matched pair (inclusive). |
required |
Returns:
| Type | Description |
|---|---|
Tuple[ndarray, ndarray, ndarray]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in sleap_nn/tracking/mot/association.py
linear_assignment_masked(score, valid)
¶
Maximum-score assignment, keeping only valid pairs.
OC-SORT semantics: validity is decided separately (on geometry alone) and the score (geometry + momentum + appearance) only orders the pairs. As in the OC-SORT / Deep OC-SORT reference, the assignment maximizes the score over the WHOLE matrix and pairs failing the validity test are then rejected: an invalid pair's own (low) score acts as the value of leaving that row and column unmatched, so a confident valid match is not traded for two weaker ones. A pair with a non-finite score is never matched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
score
|
ndarray
|
|
required |
valid
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
Tuple[ndarray, ndarray, ndarray]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in sleap_nn/tracking/mot/association.py
ocm_matrix(track_dirs, track_prev_obs, track_has_dir, det_boxes, det_scores, inertia)
¶
OC-SORT observation-centric momentum term.
For track i with unit velocity direction track_dirs[i] ((dy, dx),
from an observation delta_t steps back to its last observation) and the
direction from track_prev_obs[i] (that earlier observation) to each
detection: theta = |arccos(clip(dot, -1, 1))| and
ocm = inertia * ((pi/2 - theta) / pi) * has_dir[:, None] * det_scores[None, :].
A detection centered exactly on the earlier observation (no direction) has
dot = 0 and contributes 0, as in the reference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
track_dirs
|
ndarray
|
|
required |
track_prev_obs
|
ndarray
|
|
required |
track_has_dir
|
ndarray
|
|
required |
det_boxes
|
ndarray
|
|
required |
det_scores
|
ndarray
|
|
required |
inertia
|
float
|
Weight of the term (OC-SORT: 0.2). |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Source code in sleap_nn/tracking/mot/association.py
oks_matrix(kp_a, kp_b, area_b, sigma)
¶
Object keypoint similarity between two sets of poses.
Uses the COCO/cocoeval form, identical in constants to
:func:sleap_nn.evaluation.compute_oks with use_cocoeval=True:
e = d^2 / (2 sigma)^2 / (area + eps) / 2 and oks = mean(exp(-e)) over
the nodes visible in BOTH poses (symmetric visibility: tracking compares two
observations). Pairs sharing no visible node score 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp_a
|
ndarray
|
|
required |
kp_b
|
ndarray
|
|
required |
area_b
|
ndarray
|
|
required |
sigma
|
Scalar or |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the two pose sets have different node counts or
|
Source code in sleap_nn/tracking/mot/association.py
one_to_one_pattern(valid)
¶
OC-SORT/SORT shortcut: the valid pairs if they form a 1:1 pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
valid
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
Optional[ndarray]
|
|
Source code in sleap_nn/tracking/mot/association.py
speed_direction(prev_xyxy, cur_xyxy)
¶
Unit (dy, dx) direction between box centers, row-wise for (n, 4) inputs.
Zero-length motion gives (0, 0).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prev_xyxy
|
ndarray
|
|
required |
cur_xyxy
|
ndarray
|
|
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|