norfair-rs
Real-time multi-object tracking for Rust
Disclaimer: This is an unofficial Rust port of Python's norfair object tracking library. This project is NOT affiliated with, endorsed by, or associated with Tryolabs or the original norfair development team. All credit for the original design and algorithms goes to the original norfair authors.
Overview
norfair-rs is a Rust implementation of the norfair multi-object tracking library, bringing real-time object tracking capabilities to Rust applications with:
- Detector-agnostic design: Works with any object detector (YOLO, Faster R-CNN, custom models)
- Rust-native performance: Zero-cost abstractions, no GC, maximum speed
- Type-safe API: Compile-time validation of tracking configurations
- Comprehensive Tests: 278 tests ensuring correctness and equivalence with the original norfair library
- Drop-In-Replacement: Python bindings with
uv add norfair_rsandimport norfair_rs as norfair
Related Projects
- norfair - Original Python implementation by Tryolabs
- norfair-go - Go port of norfair (sibling project)
Features
- Flexible Distance Functions: IoU, Euclidean, Manhattan, Frobenius, Keypoint Voting, and more
- Multiple Filtering Options: Optimized Kalman filter, full filterpy-equivalent Kalman, or no filtering
- Camera Motion Compensation: Support for translation transformations (homography with opencv feature)
- Re-identification: Optional feature embedding for robust identity matching
- Thread-safe: Concurrent-safe ID generation and tracking
Benchmarks
Cross-language performance comparison (IoU distance, OptimizedKalmanFilter):
| Scenario | Frames | Detections | norfair | norfair-go | norfair-rs (python) | norfair-rs (rust) |
|---|---|---|---|---|---|---|
| Small | 100 | 446 | 4,700 fps | 243,000 fps | 107,000 fps | 296,000 fps |
| Medium | 500 | 9,015 | 540 fps | 31,000 fps | 27,000 fps | 89,000 fps |
| Large | 1,000 | 44,996 | 101 fps | 3,800 fps | 11,000 fps | 41,000 fps |
| Stress | 2,000 | 179,789 | — | 547 fps | 5,200 fps | 18,500 fps |
Speedup norfair-rs (rust) vs norfair: 60-180x depending on scenario complexity Speedup norfair-rs (python) vs norfair: 20-50x (drop-in replacement)
Benchmarks run on Apple M3 Pro. See examples/benchmark/ for reproduction scripts.
Installation
Rust
Add to your Cargo.toml:
[]
= "0.3"
Python (Drop-in Replacement)
norfair-rs provides Python bindings that work as a drop-in replacement for the original norfair library, with 20-50x better performance:
# or: pip install norfair-rs
Then simply change your import:
# Before (original norfair)
# After (norfair-rs - same API, much faster!)
Most of your existing norfair code should work unchanged. See the benchmark results for performance comparisons.
The following norfair features are not yet available in norfair-rs Python bindings:
- Custom Python callable distance functions - Use built-in distance functions (
"iou","euclidean","frobenius", etc.) instead - Custom Python callable reid_distance_function - Re-identification with custom distance functions
create_keypoints_voting_distance()- Use"keypoints_voting"string or built-in implementationcreate_normalized_mean_euclidean_distance()- Use"mean_euclidean"or implement normalization separately- scipy distance functions - Use the equivalent built-in functions via
get_distance_by_name()
All core tracking functionality works identically to the original norfair.
Quick Start (Rust)
use ;
Here's how the same tracking workflow looks in the original Python norfair library:
Python:
# OLD: from norfair import Detection, Tracker
# Create tracker
=
# Process frames
# Get detections from your detector
=
# Update tracker
=
# Use tracked objects
Key Differences:
- Rust: Explicit configuration structs vs Python kwargs
- Rust: Error handling with
Result<T, E>returns - Rust: Uses
nalgebramatrices instead of numpy arrays - Rust: Zero-cost abstractions with compile-time guarantees
Both implementations provide the same core functionality with Rust offering better performance.
Configuration Options
use ;
use distance_by_name;
let mut config = new;
// Tracking behavior
config.hit_counter_max = 15; // Frames to keep tracking without detection
config.initialization_delay = 3; // Detections required to initialize
config.pointwise_hit_counter_max = 4; // Per-point tracking threshold
config.detection_threshold = 0.5; // Minimum detection confidence
config.past_detections_length = 4; // History for re-identification
// Re-identification (optional)
config.reid_distance_function = Some;
config.reid_distance_threshold = 100.0;
config.reid_hit_counter_max = Some;
// Kalman filter
config.filter_factory = Boxnew;
Distance Functions
Built-in distance functions available via distance_by_name():
| Name | Description | Use Case |
|---|---|---|
"euclidean" |
L2 distance between points | Single-point tracking |
"iou" |
1 - Intersection over Union | Bounding box tracking |
"mean_euclidean" |
Average L2 across all points | Multi-keypoint tracking |
"mean_manhattan" |
Average L1 across all points | Grid-aligned tracking |
"frobenius" |
Frobenius norm of difference | Matrix comparison |
Custom distance functions can be implemented via the Distance trait.
Filter Options
Three filter types are available:
use ;
API Documentation
Core Types
Tracker- Main tracking engine that maintains object identities across framesDetection- Input from object detector (bounding boxes, keypoints, or arbitrary points)TrackedObject- Output object with stable ID, position estimate, and tracking metadataTrackerConfig- Configuration for tracker behaviorTrackedObjectFactory- Thread-safe ID generation
Camera Motion
use TranslationTransformation;
// Compensate for camera movement
let transform = new;
let tracked = tracker.update;
Feature Flags
[]
= { = "...", = ["opencv"] }
| Feature | Description |
|---|---|
opencv |
Enable video I/O, drawing, and homography transforms |
License & Attribution
norfair-rs is licensed under the BSD 3-Clause License.
This Rust port is based on the original norfair by Tryolabs (BSD 3-Clause). Their well-designed, detector-agnostic architecture made this port possible. Internal modules include code adapted from several Python libraries—see THIRD_PARTY_LICENSES.md for complete attribution.
Citation: If using this library in research, please cite the original norfair paper as described here.
Contributing: Issues and pull requests welcome!