Skip to main content

Fast object tracking library - Rust implementation of norfair

Project description

norfair-rs

Real-time multi-object tracking for Rust

License Crates.io PyPI Python Rust Version


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: 289+ Rust tests + 98 Python tests ensuring correctness and equivalence with the original norfair library
  • Drop-In-Replacement: Python bindings with uv add norfair_rs and import 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
  • Re-identification (ReID): Full support for object re-identification with reid_hit_counter lifecycle
  • Thread-safe: Concurrent-safe ID generation and tracking
  • Python Callable Support: Use custom Python distance functions directly with the Tracker

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.

Comparison

Play around with the norfair (python) vs norfair-rs (rust) comparison tool using:

uv run examples/compare_norfair_py_rs.py


Installation

Rust

Add to your Cargo.toml:

[dependencies]
norfair-rs = "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:

uv add norfair-rs
# or: pip install norfair-rs

Then simply change your import:

# Before (original norfair)
from norfair import Detection, Tracker

# After (norfair-rs - same API, much faster!)
from norfair_rs import Detection, Tracker

Most of your existing norfair code should work unchanged. See the benchmark results for performance comparisons.

Python API Compatibility

Compatible with norfair:

  • Detection, TrackedObject, Tracker - Same API
  • ✅ Custom Python callable distance functions
  • ✅ Custom Python callable reid_distance_function
  • create_keypoints_voting_distance(), create_normalized_mean_euclidean_distance()
  • ✅ All built-in distance functions via get_distance_by_name()
  • ✅ Full ReID support with reid_hit_counter lifecycle
  • ✅ Filter factories: OptimizedKalmanFilterFactory, FilterPyKalmanFilterFactory, NoFilterFactory
  • TranslationTransformation for camera motion

Not yet implemented: The following features from Python norfair are not available in norfair-rs:

  • Video I/O - Video class (requires OpenCV)
  • Drawing - draw_boxes(), draw_points(), draw_tracked_objects(), Drawer, Paths (requires OpenCV)
  • Homography - HomographyTransformation, MotionEstimator (requires OpenCV)
  • Utilities - FixedCamera, get_cutout(), print_objects_as_table()
  • Scipy - Scipy vectorised distance functions and some other features.

Most of these features require OpenCV bindings which are not yet implemented. Core tracking works fully.

Quick Start (Rust)

use norfair_rs::{Detection, Tracker, TrackerConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Create tracker with IoU distance function
    let mut config = TrackerConfig::from_distance_name("iou", 0.5);
    config.hit_counter_max = 30;
    config.initialization_delay = 3;

    let mut tracker = Tracker::new(config)?;

    // 2. For each frame
    for frame in iter_video_frames() {
        // 2.1 Generate detections from your object detector
        let detections: Vec<Detection> = detect_objects(&frame)
            .iter()
            .map(|bbox| {
                // Bounding box format: [x1, y1, x2, y2]
                Detection::from_slice(
                    &[bbox.x, bbox.y, bbox.x + bbox.w, bbox.y + bbox.h],
                    1, 4  // 1 row, 4 columns
                ).unwrap()
            })
            .collect();

        // 2.2 Update tracker, returning current tracked objects with stable IDs
        let tracked_objects = tracker.update(detections, 1, None);

        // 2.3 Use tracked objects (draw, analyze, etc.)
        for obj in tracked_objects {
            if let Some(id) = obj.id {
                draw_box(&frame, &obj.estimate, id);
            }
        }
    }

    Ok(())
}
Python Norfair Equivalent

Here's how the same tracking workflow looks in the original Python norfair library:

Python:

# OLD: from norfair import Detection, Tracker
from norfair_rs import Detection, Tracker

# Create tracker
tracker = Tracker(
    distance_function="iou",
    distance_threshold=0.5,
    hit_counter_max=30,
    initialization_delay=3,
)

# Process frames
for frame in iter_video_frames():
    # Get detections from your detector
    detections = [
        Detection(points=np.array([[x1, y1, x2, y2]]))
        for x1, y1, x2, y2 in detect_objects(frame)
    ]

    # Update tracker
    tracked_objects = tracker.update(detections=detections)

    # Use tracked objects
    for obj in tracked_objects:
        draw_box(frame, obj.estimate, obj.id)

Key Differences:

  • Rust: Explicit configuration structs vs Python kwargs
  • Rust: Error handling with Result<T, E> returns
  • Rust: Uses nalgebra matrices 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 norfair_rs::{TrackerConfig, filter::OptimizedKalmanFilterFactory};
use norfair_rs::distances::distance_by_name;

let mut config = TrackerConfig::new(distance_by_name("euclidean"), 50.0);

// 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(distance_by_name("euclidean"));
config.reid_distance_threshold = 100.0;
config.reid_hit_counter_max = Some(50);

// Kalman filter
config.filter_factory = Box::new(OptimizedKalmanFilterFactory::new(
    4.0,   // R (measurement noise)
    0.1,   // Q (process noise)
    10.0,  // P (initial covariance)
    0.0,   // pos_variance
    1.0,   // vel_variance
));

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 norfair_rs::filter::{
    OptimizedKalmanFilterFactory,  // Fast, simplified Kalman (default)
    FilterPyKalmanFilterFactory,    // Full filterpy-compatible Kalman
    NoFilterFactory,                // No prediction (detection-only)
};

API Documentation

Core Types

  • Tracker - Main tracking engine that maintains object identities across frames
  • Detection - Input from object detector (bounding boxes, keypoints, or arbitrary points)
  • TrackedObject - Output object with stable ID, position estimate, and tracking metadata
  • TrackerConfig - Configuration for tracker behavior
  • TrackedObjectFactory - Thread-safe ID generation

Camera Motion

use norfair_rs::camera_motion::TranslationTransformation;

// Compensate for camera movement
let transform = TranslationTransformation::new([dx, dy]);
let tracked = tracker.update(detections, 1, Some(&transform));

Feature Flags

[dependencies]
norfair = { git = "...", features = ["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!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

norfair_rs-0.4.2.tar.gz (2.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

norfair_rs-0.4.2-cp312-abi3-win_amd64.whl (316.6 kB view details)

Uploaded CPython 3.12+Windows x86-64

norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (436.2 kB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ x86-64

norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (417.3 kB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ ARM64

norfair_rs-0.4.2-cp312-abi3-macosx_11_0_arm64.whl (395.0 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

norfair_rs-0.4.2-cp312-abi3-macosx_10_12_x86_64.whl (420.3 kB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

Details for the file norfair_rs-0.4.2.tar.gz.

File metadata

  • Download URL: norfair_rs-0.4.2.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for norfair_rs-0.4.2.tar.gz
Algorithm Hash digest
SHA256 947be802d3bd49192965bba8de7182a62bf782aa1aa815d5b327075d90bba34d
MD5 b852f846fd7f4c8af58be35551fa8afc
BLAKE2b-256 de449872ec1be8889262df8c82dc1d1d2ee9a7b9b751176293f34cda01a06f92

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2.tar.gz:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norfair_rs-0.4.2-cp312-abi3-win_amd64.whl.

File metadata

  • Download URL: norfair_rs-0.4.2-cp312-abi3-win_amd64.whl
  • Upload date:
  • Size: 316.6 kB
  • Tags: CPython 3.12+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for norfair_rs-0.4.2-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 cae3eefd158be111b916a638adf143bd1a13093fb7ad43aaa9354806b2047d3c
MD5 02b2e34ba3231a6a222d3561bb2299c0
BLAKE2b-256 440049aeaacfd5dffc26c34eec3600700edeeba5da39647f960f5fc5831d18b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2-cp312-abi3-win_amd64.whl:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3beaf3940e5e6f87ee09dbc663cc0997c9f0510c2445ff0a195eb8afd49f214e
MD5 278aafd0a3ceed43fbcd290b5915ecf0
BLAKE2b-256 057ab05c3c6c560d05fc330a5fd2545cd10675ae6a5cf37967f64bbc42945ecf

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1b3c2bee29191a1e335d83f6414f4052772768df78fe46e188b72f672c201e85
MD5 35c7442c1ebf315a9a3ce03d98f91b65
BLAKE2b-256 032a32f61cae00818376dc869e1e14ca6378b1ad9e09ae26f4e3555c9e80f25e

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norfair_rs-0.4.2-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for norfair_rs-0.4.2-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6429dd91eaa818ca0022714e8bb499a58f99d0e6b7444d0cfc39852c96d24dab
MD5 ecfeeef2f4222147b86f3e06fb7409fa
BLAKE2b-256 c3d1be3791870f1963d1ce69e2798fca54303d6230b0d36bea80568d93118033

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2-cp312-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file norfair_rs-0.4.2-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for norfair_rs-0.4.2-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c94cd8a088a7caa854ec21a2c78e1f3878c0c064d825e188e6bac1a82af0f34b
MD5 89f142af4b804f0139cd4202289ed30c
BLAKE2b-256 1f67776877cfc04222b8d4efeb95c21dc79075245e57983368d59fba5d5fd9ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for norfair_rs-0.4.2-cp312-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on nmichlo/norfair-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page