> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/workflows/blocks/blocks/video-processing/ocsort-tracker.md).

# OC-SORT Tracker

Track objects across video frames using the **OC-SORT** algorithm from the roboflow/trackers package.

OC-SORT extends SORT with two key mechanisms:

1. **Observation-Centric Re-Update (OCR):** When a track reappears after occlusion, OC-SORT retroactively corrects the Kalman filter using the real observations before and after the gap, reducing accumulated drift.
2. **Observation-Centric Momentum (OCM):** A direction-consistency cost is blended with IoU during association, penalising matches where the candidate detection lies in a direction inconsistent with the track's recent motion.

This makes OC-SORT significantly more robust than SORT in scenes with heavy occlusion, erratic motion, and uniform appearance.

**When to use OC-SORT:**

* Crowded scenes with frequent and prolonged occlusions (e.g. pedestrians, warehouse workers).
* Non-linear or erratic motion patterns (e.g. dancing, sports with abrupt direction changes).
* When identity consistency over long sequences is more important than raw speed.

**When to consider alternatives:**

* For general-purpose tracking with mixed-confidence detections, try **ByteTrack**.
* For maximum simplicity and speed with a strong detector, try **SORT**.

Outputs three detection sets:

* **tracked\_detections**: All confirmed tracked detections with assigned track IDs.
* **new\_instances**: Detections whose track ID appears for the first time.
* **already\_seen\_instances**: Detections whose track ID has been seen in a prior frame.

The block maintains separate tracker state and instance cache per `video_identifier`, enabling multi-stream tracking within a single workflow.

### Type identifier

Use the following identifier in step `"type"` field: `roboflow_core/trackers_ocsort@v1` to add the block as a step in your workflow.

### Properties

| **Name**                       | **Type** | **Description**                                                                                                                                                                                                | Refs |
| ------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| `name`                         | `str`    | Enter a unique identifier for this step..                                                                                                                                                                      | ❌    |
| `minimum_iou_threshold`        | `float`  | Minimum IoU required to associate a detection with an existing track. Default: 0.3..                                                                                                                           | ✅    |
| `minimum_consecutive_frames`   | `int`    | Number of consecutive frames a track must be matched before it is emitted as a confirmed track (tracker\_id != -1). Default: 3..                                                                               | ✅    |
| `lost_track_buffer`            | `int`    | Number of frames to keep a track alive after it loses its matched detection. Higher values improve occlusion recovery. Default: 30..                                                                           | ✅    |
| `high_conf_det_threshold`      | `float`  | Confidence threshold for high-confidence detections used in association. Default: 0.6..                                                                                                                        | ✅    |
| `direction_consistency_weight` | `float`  | Weight for the direction consistency term in the OC-SORT association cost. Higher values prioritise alignment between historical motion direction and the direction to the candidate detection. Default: 0.2.. | ✅    |
| `delta_t`                      | `int`    | Number of past frames used by OC-SORT to estimate per-track velocity for direction consistency momentum. Default: 3..                                                                                          | ✅    |
| `instances_cache_size`         | `int`    | Maximum number of track IDs retained in the instance cache for new/already-seen categorisation. Uses FIFO eviction. Default: 16384..                                                                           | ❌    |

The **Refs** column marks possibility to parametrise the property with dynamic values available in `workflow` runtime. See *Bindings* for more info.

### :material-shield-half-full:{ style="color: #5e6c75" } Runtime compatibility

:material-alert-circle-outline:{ style="color: #f57c00" } `soft` - runtime `hosted_serverless`, `dedicated_deployment`; execution `remote`; input `video` : Block keeps per-video state in process memory (keyed by video\_metadata.video\_identifier). With remote step execution on stateless or multi-replica HTTP runtimes, successive requests may be served by different worker processes, so the state resets between calls and the output is meaningless for tracking / counting / aggregation. Use local step execution in an InferencePipeline for stable cross-frame results.

:material-alert-circle-outline:{ style="color: #f57c00" } `soft` - input `image` : Block depends on temporal context from video or repeated-frame workflows. With a still image/photo, there is no meaningful history to track, compare, aggregate, or visualize, so the block provides little or no benefit.

### Input and Output Bindings

The available connections depend on its binding kinds. Check what binding kinds `OC-SORT Tracker` in version `v1` has.

<details>

<summary>Input and output bindings</summary>

* input
  * `image` ([*`image`*](https://inference.roboflow.com/workflows/kinds/image/)): Input image with embedded video metadata (fps and video\_identifier). Used to initialise and retrieve per-video tracker state..
  * `detections` (*Union\[*[*`rle_instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/rle_instance_segmentation_prediction/)*,* [*`object_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/object_detection_prediction/)*,* [*`instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/instance_segmentation_prediction/)*,* [*`keypoint_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/keypoint_detection_prediction/)*]*): Detection predictions for the current frame to track..
  * `minimum_iou_threshold` ([*`float_zero_to_one`*](https://inference.roboflow.com/workflows/kinds/float_zero_to_one/)): Minimum IoU required to associate a detection with an existing track. Default: 0.3..
  * `minimum_consecutive_frames` ([*`integer`*](https://inference.roboflow.com/workflows/kinds/integer/)): Number of consecutive frames a track must be matched before it is emitted as a confirmed track (tracker\_id != -1). Default: 3..
  * `lost_track_buffer` ([*`integer`*](https://inference.roboflow.com/workflows/kinds/integer/)): Number of frames to keep a track alive after it loses its matched detection. Higher values improve occlusion recovery. Default: 30..
  * `high_conf_det_threshold` ([*`float_zero_to_one`*](https://inference.roboflow.com/workflows/kinds/float_zero_to_one/)): Confidence threshold for high-confidence detections used in association. Default: 0.6..
  * `direction_consistency_weight` ([*`float_zero_to_one`*](https://inference.roboflow.com/workflows/kinds/float_zero_to_one/)): Weight for the direction consistency term in the OC-SORT association cost. Higher values prioritise alignment between historical motion direction and the direction to the candidate detection. Default: 0.2..
  * `delta_t` ([*`integer`*](https://inference.roboflow.com/workflows/kinds/integer/)): Number of past frames used by OC-SORT to estimate per-track velocity for direction consistency momentum. Default: 3..
* output
  * `tracked_detections` (*Union\[*[*`object_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/object_detection_prediction/)*,* [*`instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/instance_segmentation_prediction/)*,* [*`keypoint_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/keypoint_detection_prediction/)*,* [*`rle_instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/rle_instance_segmentation_prediction/)*]*): Prediction with detected bounding boxes in form of sv.Detections(...) object if `object_detection_prediction` or Prediction with detected bounding boxes and segmentation masks in form of sv.Detections(...) object if `instance_segmentation_prediction` or Prediction with detected bounding boxes and detected keypoints in form of sv.Detections(...) object if `keypoint_detection_prediction` or Prediction with detected bounding boxes and RLE-encoded segmentation masks in form of sv.Detections(...) object if `rle_instance_segmentation_prediction`.
  * `new_instances` (*Union\[*[*`object_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/object_detection_prediction/)*,* [*`instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/instance_segmentation_prediction/)*,* [*`keypoint_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/keypoint_detection_prediction/)*,* [*`rle_instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/rle_instance_segmentation_prediction/)*]*): Prediction with detected bounding boxes in form of sv.Detections(...) object if `object_detection_prediction` or Prediction with detected bounding boxes and segmentation masks in form of sv.Detections(...) object if `instance_segmentation_prediction` or Prediction with detected bounding boxes and detected keypoints in form of sv.Detections(...) object if `keypoint_detection_prediction` or Prediction with detected bounding boxes and RLE-encoded segmentation masks in form of sv.Detections(...) object if `rle_instance_segmentation_prediction`.
  * `already_seen_instances` (*Union\[*[*`object_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/object_detection_prediction/)*,* [*`instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/instance_segmentation_prediction/)*,* [*`keypoint_detection_prediction`*](https://inference.roboflow.com/workflows/kinds/keypoint_detection_prediction/)*,* [*`rle_instance_segmentation_prediction`*](https://inference.roboflow.com/workflows/kinds/rle_instance_segmentation_prediction/)*]*): Prediction with detected bounding boxes in form of sv.Detections(...) object if `object_detection_prediction` or Prediction with detected bounding boxes and segmentation masks in form of sv.Detections(...) object if `instance_segmentation_prediction` or Prediction with detected bounding boxes and detected keypoints in form of sv.Detections(...) object if `keypoint_detection_prediction` or Prediction with detected bounding boxes and RLE-encoded segmentation masks in form of sv.Detections(...) object if `rle_instance_segmentation_prediction`.

</details>

<details>

<summary>Example JSON definition</summary>

```json
{
	    "name": "<your_step_name_here>",
	    "type": "roboflow_core/trackers_ocsort@v1",
	    "image": "<block_does_not_provide_example>",
	    "detections": "$steps.object_detection_model.predictions",
	    "minimum_iou_threshold": 0.3,
	    "minimum_consecutive_frames": 3,
	    "lost_track_buffer": 30,
	    "high_conf_det_threshold": 0.6,
	    "direction_consistency_weight": 0.2,
	    "delta_t": 3,
	    "instances_cache_size": "<block_does_not_provide_example>"
	}
```

</details>
