JamTrack-rs is a Rust crate that provides multi-object tracking algorithms including ByteTrack, FastTracker, BoT-SORT, BoostTrack, and OC-SORT.
- ByteTracker: Simple and efficient tracking using IoU-based association
- FastTracker: Occlusion-aware association with optional road-region and direction-cone constraints
- Motion reset, bounding-box enlargement, and dampening during occlusion
- Duplicate-track initialization suppression and recently-occluded lifetime extension
- Four-point ROI trajectory repair and direction refinement
- BotSort: BoT-SORT tracking with BYTE-style association,
xywhKalman filter, optional ECC camera compensation, and optional external ReID embeddings - BoostTracker: Advanced tracking with confidence boosting techniques
- BoostTrack: Basic DLO/DUO confidence boost
- BoostTrack+: Rich similarity (Mahalanobis distance + shape + soft BIoU)
- BoostTrack++: Rich similarity + soft boost + varying threshold
- OC-SORT: Observation-Centric SORT with online smoothing
- IoU + VDC (Velocity Direction Consistency) association
- BYTE association for low-confidence detections
- OCR (Observation-Centric Re-association) with last observation
- Kalman filter freeze/unfreeze for online smoothing
output-best-test.mp4
Individual tracker demos: ByteTracker | FastTracker | BoT-SORT | BoostTracker | BoostTracker+ | BoostTracker++
Videos use YOLOX-X detections and footage from the NHK Creative Library.
Add the following to your Cargo.toml:
[dependencies]
jamtrack-rs = { git = "https://github.com/kadu-v/jamtrack-rs.git" }The Swift package is distributed as JTrackers. Add it in Xcode via File > Add Package Dependencies with the URL:
https://github.com/kadu-v/JTrackers.git
Or add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/kadu-v/JTrackers.git", from: "0.5.1"),
]use jamtrack_rs::byte_tracker::ByteTracker;
use jamtrack_rs::object::Object;
use jamtrack_rs::rect::Rect;
// Create tracker: track_thresh, track_buffer, match_thresh
let mut tracker = ByteTracker::new(0.5, 30, 0.8);
// Create detections
let detections = vec![
Object::new(Rect::new(100.0, 100.0, 50.0, 80.0), 0.9, None),
Object::new(Rect::new(200.0, 150.0, 60.0, 90.0), 0.85, None),
];
// Update tracker
let tracks = tracker.update(&detections);
for track in tracks {
println!("Track ID: {:?}, Rect: {:?}", track.get_track_id(), track.get_rect());
}use jamtrack_rs::boost_tracker::BoostTracker;
use jamtrack_rs::object::Object;
use jamtrack_rs::rect::Rect;
// Create tracker: det_thresh, iou_threshold, max_age, min_hits
let mut tracker = BoostTracker::new(0.5, 0.3, 30, 3);
// Create detections
let detections = vec![
Object::new(Rect::new(100.0, 100.0, 50.0, 80.0), 0.9, None),
Object::new(Rect::new(200.0, 150.0, 60.0, 90.0), 0.85, None),
];
// Update tracker
let tracks = tracker.update(&detections).unwrap();
for track in tracks {
println!("Track ID: {:?}, Rect: {:?}", track.get_track_id(), track.get_rect());
}use jamtrack_rs::{FastTracker, Object, Rect};
// frame_rate, track_buffer, track_thresh, match_thresh
let mut tracker = FastTracker::new(30, 30, 0.6, 0.7);
let detections = vec![Object::new(
Rect::new(100.0, 100.0, 50.0, 80.0),
0.9,
None,
)];
let tracks = tracker.update(&detections)?;
# Ok::<(), jamtrack_rs::TrackError>(())FastTracker expects detection rectangles in original-image coordinates. Its occlusion handling is enabled by the standard constructor; RoI constraints are optional.
An RoI is a camera-specific, four-point polygon. Upstream FastTracker does not detect it automatically and does not use it to discard detections outside the polygon. It repairs short trajectory excursions after a track returns to the RoI, and refines motion that falls outside the direction cone derived from the four points. Configure it only when fixed pixel coordinates for the scene are known:
use jamtrack_rs::{FastTracker, FastTrackerRoi};
// Point order follows upstream FastTracker: (E1, E2, O2, O1).
let road = FastTrackerRoi::new([
[312.0, 196.0],
[422.0, 188.0],
[1399.0, 694.0],
[152.0, 697.0],
]);
let mut tracker = FastTracker::new(30, 30, 0.6, 0.7)
.with_rois(vec![road], 15, 10, 2.0);FastTrackerRoi is the Rust value that owns these four points. Multiple RoIs
may be supplied; the first polygon containing the current track center is used.
Without with_rois, behavior matches upstream with no ROIs configuration.
The same tracker is available from Swift:
let tracker = FastTracker(
frameRate: 30,
trackBuffer: 30,
trackThresh: 0.6,
matchThresh: 0.7
)
switch tracker.update(detections) {
case .success(let tracks):
print(tracks)
case .failure(let error):
print(error)
}use jamtrack_rs::bot_sort_tracker::BotSort;
use jamtrack_rs::object::Object;
use jamtrack_rs::rect::Rect;
let mut tracker = BotSort::new(30, 30, 0.6, 0.1, 0.7, 0.8);
let detections = vec![
Object::new(Rect::new(100.0, 100.0, 50.0, 80.0), 0.9, None),
];
let tracks = tracker.update(&detections).unwrap();BoT-SORT can also run ECC camera motion compensation when the caller provides grayscale frames:
use image::GrayImage;
let mut tracker = BotSort::new(30, 30, 0.6, 0.1, 0.7, 0.8)
.with_ecc();
let frame = GrayImage::new(640, 480);
let tracks = tracker.update_with_frame(&detections, &frame).unwrap();BoT-SORT ReID matching is optional and expects embeddings from the caller:
let mut tracker = BotSort::new(30, 30, 0.6, 0.1, 0.7, 0.8)
.with_reid(true);
let features = vec![vec![1.0, 0.0, 0.0]];
let tracks = tracker.update_with_features(&detections, &features).unwrap();use jamtrack_rs::boost_tracker::BoostTracker;
// BoostTrack+ (rich similarity)
let mut tracker_plus = BoostTracker::new(0.5, 0.3, 30, 3)
.with_boost_plus();
// BoostTrack++ (rich similarity + soft boost + varying threshold)
let mut tracker_plus_plus = BoostTracker::new(0.5, 0.3, 30, 3)
.with_boost_plus_plus();
// Custom configuration
let mut custom_tracker = BoostTracker::new(0.5, 0.3, 30, 3)
.with_lambdas(0.6, 0.2, 0.2) // lambda_iou, lambda_mhd, lambda_shape
.with_boost(true, false) // use_dlo_boost, use_duo_boost
.with_boost_plus_plus();use jamtrack_rs::oc_sort_tracker::OCSort;
use jamtrack_rs::object::Object;
use jamtrack_rs::rect::Rect;
// Create tracker with detection threshold
let mut tracker = OCSort::new(0.5)
.with_max_age(30)
.with_min_hits(3)
.with_iou_threshold(0.3)
.with_delta_t(3)
.with_inertia(0.2)
.with_byte(false); // enable BYTE association for low-score detections
// Create detections
let detections = vec![
Object::new(Rect::new(100.0, 100.0, 50.0, 80.0), 0.9, None),
Object::new(Rect::new(200.0, 150.0, 60.0, 90.0), 0.85, None),
];
// Update tracker
let tracks = tracker.update(&detections).unwrap();
for track in tracks {
println!("Track ID: {:?}, Rect: {:?}", track.get_track_id(), track.get_rect());
}Tested on M3 MacBook Pro with 1627 frames from detection_results.json.
Lower is better. Each bar is the time required to process all 1627 frames.
BoostTrack++ performs more computation per frame (soft boost + varying threshold), but maintains fewer active tracks due to better matching:
| Tracker | Avg Tracks | Max Tracks |
|---|---|---|
| BoostTrack | 32.12 | 46 |
| BoostTrack+ | 30.94 | 45 |
| BoostTrack++ | 28.97 | 43 |
Fewer tracks = smaller similarity matrices = faster downstream computation.
cargo benchThe values used by the charts are stored by tracker family in
data/benchmarks. After updating those JSON files,
regenerate every benchmark chart with:
uv run --project python python scripts/gen_charts.pyEvaluation results on MOT17 train set using YOLOX-X detector. The left panel compares tracking quality with identity switches; its vertical axis is inverted, so points toward the upper right are better. The right panel compares detection accuracy with identity preservation. Dashed lines show the Pareto frontier.
Note
- ECC variants show significant improvement in HOTA/IDF1/IDSW due to camera motion compensation
- Rust BoostTrack and BoT-SORT support ECC camera motion compensation
- BoT-SORT ReID matching is implemented, but the MOT17 benchmark above uses the non-ReID path for fair comparison with non-embedding tracker variants
- MOTA is determined by the core algorithm, so Rust and Python versions achieve nearly identical values
- Tuned variants use optimized hyperparameters of a tracker for MOT17 dataset
- FastTracker was evaluated with
track_thresh=0.6,track_buffer=30,match_thresh=0.7, and no RoI constraints - Rust and official Python FastTracker produced identical frame/ID assignments and TrackEval results: HOTA 64.56, MOTA 74.26, IDF1 72.44, and 1,171 ID switches
Run the examples with detection data:
# ByteTracker
cargo run --example example_byte_tracker
# FastTracker
cargo run --example example_fast_tracker
# BoostTracker (basic)
cargo run --example example_boost_tracker
# BoostTracker with mode selection
cargo run --example example_boost_tracker_modes basic
cargo run --example example_boost_tracker_modes plus
cargo run --example example_boost_tracker_modes plusplus
# BoT-SORT
cargo run --example example_bot_sort| Feature | ByteTracker | FastTracker | BoT-SORT | BoostTrack | BoostTrack+ | BoostTrack++ | OC-SORT |
|---|---|---|---|---|---|---|---|
| IoU Association | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Occlusion Handling | No | Yes | No | No | No | No | No |
| RoI Constraints | No | Yes | No | No | No | No | No |
| Mahalanobis Distance | No | No | No | Yes | Yes | Yes | No |
| Shape Similarity | No | No | No | No | Yes | Yes | No |
| DLO Confidence Boost | No | No | No | Yes | Yes | Yes | No |
| DUO Confidence Boost | No | No | No | Yes | Yes | Yes | No |
| Rich Similarity | No | No | No | No | Yes | Yes | No |
| Soft Boost | No | No | No | No | No | Yes | No |
| Varying Threshold | No | No | No | No | No | Yes | No |
| VDC (Velocity Direction Consistency) | No | No | No | No | No | No | Yes |
| OCR (Re-association) | No | No | No | No | No | No | Yes |
| Online Smoothing (Freeze/Unfreeze) | No | No | No | No | No | No | Yes |
| BYTE Association | Yes | Yes | Yes | No | No | No | Yes |
| Embedding (Re-ID) | No | No | Optional | No | No | No | No |
| ECC (Camera Motion Compensation) | No | No | Yes | Yes | Yes | Yes | No |
- ByteTrack: Multi-Object Tracking by Associating Every Detection Box
- FastTracker: Real-Time and Accurate Visual Tracking
- BoT-SORT: Robust Associations Multi-Pedestrian Tracking
- BoostTrack: Boosting the Similarity Measure and Detection Confidence for Improved Multiple Object Tracking
- OC-SORT: Observation-Centric SORT on video Multi-Object Tracking
MIT License


