Architecture¶
This document describes the internal architecture of motcpp.
System Overview¶
┌─────────────────────────────────────────────────────────────────────────┐
│ motcpp │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Input │ │ Tracker │ │ Output │ │
│ │ Detections │───▶│ Engine │───▶│ Tracks │ │
│ │ (N×6) │ │ │ │ (M×8) │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Motion │ │ Association │ │ Appearance │ │
│ │ Model │ │ Module │ │ Model │ │
│ │ (Kalman) │ │ (Hungarian) │ │ (ReID) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Core Components¶
1. BaseTracker¶
The abstract base class that all trackers inherit from.
namespace motcpp {
class BaseTracker {
public:
// Main interface
virtual Eigen::MatrixXf update(
const Eigen::MatrixXf& dets,
const cv::Mat& img,
const Eigen::MatrixXf& embs = Eigen::MatrixXf()) = 0;
virtual void reset() = 0;
protected:
TrackerConfig config_;
int frame_count_;
std::vector<Track> tracks_;
};
}
2. Motion Models¶
Kalman filters for state estimation and prediction.
┌────────────────────────────────────────────────────────┐
│ Motion Models │
├────────────────────────────────────────────────────────┤
│ │
│ KalmanFilterXYSR KalmanFilterXYAH │
│ ├─ State: [x,y,s,r, ├─ State: [x,y,a,h, │
│ │ vx,vy,vs] │ vx,vy,va,vh] │
│ ├─ Obs: [x,y,s,r] ├─ Obs: [x,y,a,h] │
│ └─ Used by: SORT, └─ Used by: StrongSORT, │
│ OC-SORT ByteTrack │
│ │
│ UCMCKalmanFilter │
│ ├─ State: [x,vx,y,vy] (ground plane) │
│ └─ Used by: UCMCTrack │
│ │
└────────────────────────────────────────────────────────┘
3. Association Module¶
Data association using various cost functions.
namespace motcpp::utils {
// Cost matrices
Eigen::MatrixXf iou_batch(bboxes1, bboxes2); // Standard IoU
Eigen::MatrixXf giou_batch(bboxes1, bboxes2); // Generalized IoU
Eigen::MatrixXf diou_batch(bboxes1, bboxes2); // Distance IoU
Eigen::MatrixXf ciou_batch(bboxes1, bboxes2); // Complete IoU
// Linear assignment (Hungarian algorithm)
LinearAssignmentResult linear_assignment(
const Eigen::MatrixXf& cost_matrix,
float threshold
);
}
4. Appearance Model (ReID)¶
ONNX-based appearance feature extraction.
┌────────────────────────────────────────────────────────┐
│ Appearance Pipeline │
├────────────────────────────────────────────────────────┤
│ │
│ Input Image ──▶ Crop Detections ──▶ ReID Model ──▶ │
│ │
│ ┌─────────────┐ │
│ │ OSNet │ │
│ │ ResNet │ │
│ │ CLIP │ ──▶ Embeddings │
│ │ ... │ (N × 512) │
│ └─────────────┘ │
│ │
└────────────────────────────────────────────────────────┘
Data Flow¶
Input Format¶
Detections: Eigen::MatrixXf with shape (N, 6)
| Column | Description |
|---|---|
| 0 | x1 (left) |
| 1 | y1 (top) |
| 2 | x2 (right) |
| 3 | y2 (bottom) |
| 4 | confidence |
| 5 | class_id |
Output Format¶
Tracks: Eigen::MatrixXf with shape (M, 8)
| Column | Description |
|---|---|
| 0 | x1 (left) |
| 1 | y1 (top) |
| 2 | x2 (right) |
| 3 | y2 (bottom) |
| 4 | track_id |
| 5 | confidence |
| 6 | class_id |
| 7 | detection_index |
Tracking Pipeline¶
Frame t
│
▼
┌──────────────────┐
│ 1. Predict │ ← Kalman filter prediction
│ tracks[t-1] │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 2. Associate │ ← Hungarian matching
│ dets[t] ↔ │
│ tracks[t-1] │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 3. Update │ ← Kalman filter update
│ matched │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 4. Initialize │ ← New tracks for
│ unmatched │ unmatched dets
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 5. Delete │ ← Remove lost
│ old tracks │ tracks
└────────┬─────────┘
│
▼
tracks[t]
Track Lifecycle¶
┌─────────┐
│ NEW │
└────┬────┘
│
│ hits >= min_hits
▼
┌─────────────────────────────────────┐
│ │
│ TRACKED │◀──┐
│ │ │
└─────────────────┬───────────────────┘ │
│ │
│ time_since_update > 0 │ matched
▼ │
┌─────────┐ │
│ LOST │───────────────────┘
└────┬────┘
│
│ age > max_age
▼
┌─────────┐
│ REMOVED │
└─────────┘
Memory Management¶
motcpp uses modern C++ memory management:
- Unique pointers for tracker ownership
- Eigen matrices for efficient linear algebra
- Move semantics for zero-copy data transfer
- RAII for resource management
// Example: Efficient track creation
auto tracker = std::make_unique<ByteTrack>(config);
// Zero-copy update
Eigen::MatrixXf tracks = tracker->update(dets, frame);
// Move semantics
process_tracks(std::move(tracks));
Thread Safety¶
- Single tracker instances are NOT thread-safe
- Create separate tracker instances for parallel processing
- Shared data (e.g., ReID model) uses internal synchronization
// Parallel video processing
#pragma omp parallel for
for (int i = 0; i < num_videos; ++i) {
auto tracker = create_tracker("bytetrack"); // Thread-local
process_video(videos[i], tracker.get());
}
Extension Points¶
Custom Tracker¶
class MyTracker : public motcpp::BaseTracker {
public:
MyTracker(const TrackerConfig& config)
: BaseTracker(config) {}
Eigen::MatrixXf update(
const Eigen::MatrixXf& dets,
const cv::Mat& img,
const Eigen::MatrixXf& embs) override {
// Your tracking logic here
}
void reset() override {
// Reset state
}
};