use std::collections::HashMap;
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct TrackingBox {
pub frame_id: usize,
pub track_id: u64,
pub x1: f64,
pub y1: f64,
pub x2: f64,
pub y2: f64,
pub confidence: f64,
}
impl TrackingBox {
pub fn new(
frame_id: usize,
track_id: u64,
x1: f64,
y1: f64,
x2: f64,
y2: f64,
confidence: f64,
) -> Self {
Self {
frame_id,
track_id,
x1,
y1,
x2,
y2,
confidence,
}
}
pub fn area(&self) -> f64 {
let w = (self.x2 - self.x1).max(0.0);
let h = (self.y2 - self.y1).max(0.0);
w * h
}
pub fn iou(&self, other: &TrackingBox) -> f64 {
let ix1 = self.x1.max(other.x1);
let iy1 = self.y1.max(other.y1);
let ix2 = self.x2.min(other.x2);
let iy2 = self.y2.min(other.y2);
let iw = (ix2 - ix1).max(0.0);
let ih = (iy2 - iy1).max(0.0);
let intersection = iw * ih;
if intersection <= 0.0 {
return 0.0;
}
let union = self.area() + other.area() - intersection;
if union <= 0.0 {
0.0
} else {
intersection / union
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MatchAlg {
Hungarian,
Greedy,
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct TrackingMetricsConfig {
pub iou_threshold: f64,
pub match_alg: MatchAlg,
}
impl Default for TrackingMetricsConfig {
fn default() -> Self {
Self {
iou_threshold: 0.5,
match_alg: MatchAlg::Hungarian,
}
}
}
#[derive(Debug, Clone)]
pub struct TrackingMetrics {
pub mota: f64,
pub motp: f64,
pub idf1: f64,
pub id_switches: usize,
pub false_positives: usize,
pub false_negatives: usize,
pub mostly_tracked: usize,
pub mostly_lost: usize,
pub tp: usize,
pub n_gt: usize,
}
#[derive(Debug, Default)]
pub struct GtTrackStats {
pub total_frames: usize,
pub matched_frames: usize,
}
#[derive(Debug, Default)]
pub struct FrameMatchResult {
pub tp: usize,
pub fp: usize,
pub fn_: usize,
pub id_switches: usize,
pub total_iou: f64,
pub gt_to_pred: HashMap<u64, u64>,
}