# TrackForgex
[](https://github.com/monoflow-ayvu/track_forgex/actions/workflows/elixir.yml)
[](https://hexdocs.pm/track_forgex)
[](https://opensource.org/licenses/MIT)
A port of [trackforge](https://docs.rs/trackforge/latest/trackforge/) from Rust to Elixir using Rustler. An open-source multi-object tracking library for real-time video analysis, currently implementing the ByteTrack algorithm.
## Features
- **Port of trackforge**: Direct port of the Rust tracking library to Elixir, maintaining feature parity and performance characteristics
- **ByteTrack implementation**: Currently implements only the ByteTrack algorithm
- **High performance**: Rust-based NIF implementation ensuring low overhead and fast execution
- **Elixir-friendly API**: Clean, idiomatic Elixir interface with comprehensive types and documentation
- **Flexible configuration**: Configurable thresholds for track initialization, matching, and confidence scoring
- **Extensible architecture**: Designed to, in the future, support additional trackers from trackforge (e.g., DeepSORT, FairMOT)
## Installation
Add `track_forgex` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:track_forgex, "~> 0.1.0"}
]
end
```
After installing, you need to compile the NIF:
```bash
mix deps.compile
```
## Quick Start
### Basic Usage
```elixir
import TrackForgex.Trackers.ByteTrack
import TrackForgex.Utils
# Create a ByteTracker instance with custom settings
settings = %TrackForgex.Trackers.ByteTrack.Settings{
track_thresh: 0.5,
track_buffer: 30,
match_thresh: 0.8,
det_thresh: 0.6
}
tracker = new(settings)
# Process detections from a detector
detections = [
%TrackForgex.Utils.Detection{
bbox: %TrackForgex.Utils.BBox{x: 10.0, y: 20.0, w: 100.0, h: 50.0},
score: 0.9,
class_id: 0
},
%TrackForgex.Utils.Detection{
bbox: %TrackForgex.Utils.BBox{x: 150.0, y: 30.0, w: 80.0, h: 60.0},
score: 0.85,
class_id: 0
}
]
# Update tracker and get results
results = update(tracker, detections)
# Results contain track IDs, states, and trajectories
results
# => [
# %TrackForgex.Trackers.ByteTrack.DetectionResult{
# bbox: %TrackForgex.Utils.BBox{x: 10.0, y: 20.0, w: 100.0, h: 50.0},
# score: 0.9,
# class_id: 0,
# track_id: 1,
# state: :tracked,
# is_activated: true,
# frame_id: 10,
# start_frame: 8,
# tracklet_len: 3
# },
# %TrackForgex.Trackers.ByteTrack.DetectionResult{
# bbox: %TrackForgex.Utils.BBox{x: 150.0, y: 30.0, w: 80.0, h: 60.0},
# score: 0.85,
# class_id: 0,
# track_id: 2,
# state: :tracked,
# is_activated: true,
# frame_id: 10,
# start_frame: 10,
# tracklet_len: 1
# }
# ]
```
### Configuration
The `Settings` struct allows you to tune the tracking behavior:
```elixir
settings = %TrackForgex.Trackers.ByteTrack.Settings{
track_thresh: 0.5, # Threshold for high-confidence detections
track_buffer: 30, # Frames to keep a lost track alive
match_thresh: 0.8, # IoU threshold for matching
det_thresh: 0.6 # Detection threshold for new tracks
}
```
### Detection States
Each detection result includes the current tracking state:
- `:new` - New track that hasn't been confirmed yet
- `:tracked` - Confirmed track being actively tracked
- `:lost` - Track that has been lost but preserved
- `:removed` - Track that has been removed
## Development
### Prerequisites
- Elixir 1.18+
- Rust stable
- [Devenv](https://devenv.sh) (optional, for reproducible environments)
### Setup
```bash
# Install dependencies
mix deps.get
# Compile the NIF
mix deps.compile
# Run tests
mix test
# Run code quality checks
mix check
```
### Project Structure
```
track_forgex/
├── lib/
│ ├── track_forgex.ex # Main module with common utilities
│ ├── native.ex # NIF interface (Rustler) for trackforge bindings
│ ├── utils.ex # BBox and Detection structs
│ └── trackers/
│ ├── byte_track.ex # ByteTrack implementation (currently available)
│ └── [other_trackers] # Additional trackers from trackforge (future)
├── native/
│ └── track_forgex/
│ └── src/
│ └── lib.rs # Rust NIF implementation wrapping trackforge
├── test/
│ └── test_helper.exs
├── mix.exs
└── README.md
```
### Architecture
TrackForgex is a thin Elixir wrapper around the [trackforge](https://github.com/onuralpszr/trackforge/) Rust library. The architecture follows the Rustler pattern:
1. **Native Module** (`lib/native.ex`): Defines the Elixir-side NIF interface that marshals data between Elixir and Rust
2. **Rust Layer** (`native/track_forgex/src/lib.rs`): Implements the trackforge library functions, converting between Rust and Elixir types
3. **Elixir API** (`lib/trackers/byte_track.ex`): Provides a clean, idiomatic Elixir interface to the tracker functionality
4. **Data Models** (`lib/utils.ex`): Defines Elixir structs for bounding boxes, detections, and tracker results
This design allows for maximum performance (via Rust) while maintaining the benefits of Elixir's Ecosystem.
### Rust Development
For Rust-specific development:
```bash
cd native/track_forgex
cargo build
```
## License
MIT License - see LICENSE file for details
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for a list of changes.
## Contributing
Contributions are welcome! Please ensure all tests pass before submitting a pull request.
```bash
# Format code
mix format
# Run checks
mix check
# Run tests with coverage
mix test --cover
```
## Acknowledgments
- **[trackforge](https://github.com/onuralpszr/trackforge/)** - The Rust multi-object tracking library that TrackForgex is based on
- **ByteTrack algorithm** from [ByteTrack: High Performance Multi-Object Tracking by Associating Every Detection Box](https://arxiv.org/abs/2211.04563)
- **Rustler** for seamless Elixir-Rust interop
- The Elixir and Rust communities for excellent tooling and support