Skip to content

trackforge / trackers / ocsort


Module ocsort

OC-SORT: Observation-Centric SORT

This module implements OC-SORT (Observation-Centric SORT), a robust extension of SORT that addresses tracker drift during occlusions by anchoring motion estimation to raw detections rather than Kalman filter predictions.

Algorithm Overview

SORT accumulates prediction errors during occlusions because its Kalman filter integrates noisy velocity estimates when no observation is available. OC-SORT corrects this with two complementary mechanisms:

Observation-Centric Velocity (OCV) Velocity is computed directly from consecutive detections, not from the Kalman filter state. This produces a more reliable momentum signal because it is grounded in actual observations.

Observation-Centric Momentum (OCM) Before IoU matching, a direction-consistency bonus is added to each IoU score based on how well the observed velocity direction aligns with the vector from the track's last observation to each candidate detection. Matches that are consistent with the track's momentum receive a higher effective IoU, improving association after missed frames.

Observation-Centric Re-Update (ORU) When a lost track is re-matched after a gap, the Kalman filter is "re-wound" by replaying linearly interpolated observations between the last seen position and the current detection. This corrects the accumulated drift so that future predictions start from an accurate state.

Parameters

Parameter Default Description
max_age 30 Frames a lost track is kept alive before deletion
min_hits 3 Consecutive matched frames required to confirm a track
iou_threshold 0.3 IoU threshold for detection-to-track association
delta_t 3 Observation window (frames) used to compute velocity
inertia 0.2 Weight applied to the direction-consistency cost bonus (OCM)

Tuning Tips

  • Increase max_age (e.g. 60) when objects undergo long occlusions.
  • Increase delta_t for smoother velocity at the cost of responsiveness to rapid direction changes.
  • Increase inertia (max 1.0) if objects move at near-constant velocity; lower it for erratic motion.
  • min_hits=1 gives immediate track output — useful when detections are already filtered upstream.

References

Observation-Centric SORT: Rethinking SORT for Robust Multi-Object Tracking Jinkun Cao, Xinshuo Weng, Rawal Khirodkar, Jiangmiao Pang, Kris Kitani CVPR 2023 arXiv:2203.14360

Quick Reference

Item Kind Description
OcSort struct OC-SORT tracker.
OcSortTrack struct A single tracked object managed by OC-SORT.
OcSortTrackState type Track lifecycle state for OC-SORT.

Types

OcSort

struct OcSort {
    // [REDACTED: Private Fields]
}

OC-SORT tracker.

Extends SORT with observation-centric velocity, momentum-adjusted prediction, and Kalman re-update on re-association. The public API is identical to Sort: call [OcSort::update] once per frame with a list of detections.

Example

use trackforge::trackers::ocsort::OcSort;

// max_age=30, min_hits=3, iou_threshold=0.3, delta_t=3, inertia=0.2
let mut tracker = OcSort::new(30, 3, 0.3, 3, 0.2);

let detections = vec![
    ([100.0_f32, 100.0, 50.0, 100.0], 0.9_f32, 0_i64),
    ([200.0_f32, 200.0, 60.0, 120.0], 0.85_f32, 0_i64),
];

let tracks = tracker.update(detections);
for t in &tracks {
    println!("ID: {}, Box: {:?}", t.track_id, t.tlwh);
}

Implementations

fn new(max_age: usize, min_hits: usize, iou_threshold: f32, delta_t: usize, inertia: f32) -> Self

Create a new OC-SORT tracker.

# Arguments

Argument Description
max_age Frames a lost track survives before deletion (default: 30).
min_hits Consecutive matches required to confirm a track (default: 3).
iou_threshold Minimum IoU to associate a detection with a track (default: 0.3).
delta_t Observation window for velocity computation (default: 3).
inertia Weight for the OCM direction-consistency bonus in [0, 1] (default: 0.2).

fn update(&mut self, detections: Vec<([f32; 4], f32, i64)>) -> Vec<OcSortTrack>

Update the tracker with detections for the current frame.

# Arguments

Argument Description
detections (tlwh, score, class_id) tuples for all detections in the frame.

# Returns

Confirmed tracks active in this frame.

Trait Implementations

impl Default for OcSort

fn default() -> Self

impl Read<Exclusive, BecauseExclusive> for OcSort
impl<R> ReadPrimitive<R> for OcSort

fn to_subset(&self) -> Option<SS>

fn is_in_subset(&self) -> bool

fn to_subset_unchecked(&self) -> SS

fn from_subset(element: &SS) -> SP

impl Tracker for OcSort
  • type Track = OcSortTrack

fn update(&mut self, detections: Vec<crate::traits::Detection>) -> Vec<OcSortTrack>

OcSortTrack

struct OcSortTrack {
    pub tlwh: [f32; 4],
    pub score: f32,
    pub class_id: i64,
    pub track_id: u64,
    pub state: OcSortTrackState,
    pub hits: usize,
    pub hit_streak: usize,
    pub time_since_update: usize,
    pub age: usize,
    // [REDACTED: Private Fields]
}

A single tracked object managed by OC-SORT.

Fields

Name Type Description
tlwh [f32; 4] Bounding box in TLWH (top-left x, top-left y, width, height) format.
score f32 Detection confidence of the most recent match.
class_id i64 Class label of the most recent match.
track_id u64 Unique monotonically increasing track identifier.
state OcSortTrackState Current lifecycle state.
hits usize Total number of detection matches over the track lifetime.
hit_streak usize Consecutive detection matches without interruption (resets to 0 on any missed frame).
time_since_update usize Frames elapsed since the last detection match.
age usize Total frames since track creation.

Trait Implementations

impl Clone for OcSortTrack

fn clone(&self) -> OcSortTrack

impl Debug for OcSortTrack

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result

impl Read<Exclusive, BecauseExclusive> for OcSortTrack

fn to_subset(&self) -> Option<SS>

fn is_in_subset(&self) -> bool

fn to_subset_unchecked(&self) -> SS

fn from_subset(element: &SS) -> SP

OcSortTrackState

type OcSortTrackState = crate::trackers::common::TrackState;

Track lifecycle state for OC-SORT.

Alias of the shared TrackState.