Keypoint-based multi-object tracking using OKS similarity and OCM cost.
- Full pose geometry via Object Keypoint Similarity (OKS) — not bounding-box IoU
- Orientation-Corrected Motion (OCM) cost for heading-aware association
- Works with arbitrary keypoint skeletons (any K)
- Zero deep-learning dependencies in core (numpy + scipy only)
- Two-phase matching with ORU/OCR occlusion recovery
- Merger detection for overlapping targets
pip install oksortWith benchmark extras (for running comparisons against other trackers):
pip install "oksort[benchmark]"import numpy as np
from oksort import Detection, KeypointTracker
# Create tracker for 6-keypoint skeletons
tracker = KeypointTracker(n_keypoints=6)
# Each frame: wrap your detections and call update()
detections = [
Detection(
keypoints=np.random.rand(6, 2) * 640,
keypoint_conf=np.random.rand(6),
scale=150.0,
)
]
tracks = tracker.update(detections)
for track in tracks:
print(f"Track {track.track_id}: state={track.state.name}")Performance on the AquaPose dataset (all trackers use identical detections):
| Tracker | HOTA | MOTA | IDF1 |
|---|---|---|---|
| OKSort | 0.5626 | 0.9625 | 0.4579 |
| BotSort | 0.5453 | 0.9586 | 0.4492 |
| KeySORT | 0.5319 | 0.9585 | 0.4233 |
| OC-SORT | 0.5263 | 0.9091 | 0.4401 |
| StrongSORT | 0.4778 | 0.9482 | 0.3778 |
| ByteTrack | 0.4348 | 0.9201 | 0.3908 |
| SFSORT | 0.3707 | 0.9244 | 0.2754 |
OKSort's advantage comes from pose-geometry association rather than bounding-box IoU.
pip install hatch
hatch env create
hatch run test # run tests
hatch run lint # ruff check
hatch run typecheck # basedpyright