Skip to main content

merge_tiled_detections

Function merge_tiled_detections 

Source
pub fn merge_tiled_detections(
    dets: Vec<DetectBox>,
    cfg: &MergeConfig,
) -> Vec<DetectBox>
Expand description

Greedy Non-Max Merge of lifted full-frame detections. Mirrors metrics/tiled.py::merge_tiled_detections:

  1. Sort descending by score (ties broken by ascending original index so the result is deterministic — this differs from NumPy’s unstable argsort only on exact ties).
  2. For each unused base in order, find later unused boxes (same class unless class_agnostic) whose metric.value(base, cand) >= threshold — matched against the original base box. Replace the group with its enclosing union carrying the group’s max score and the base’s label.
  3. Drop groups below score_threshold and truncate to max_det.

Operates in pixel space (the metric’s 1e-9 epsilon is calibrated to pixel areas).

§Examples

use edgefirst_decoder::tiling::{merge_tiled_detections, MatchMetric, MergeConfig};
use edgefirst_decoder::{BoundingBox, DetectBox};

// A fragment (B) fully inside the full detection (A): IoS=1.0, IoU≈0.17.
let a = DetectBox { bbox: BoundingBox::new(100.0, 100.0, 400.0, 300.0), score: 0.9, label: 0 };
let b = DetectBox { bbox: BoundingBox::new(350.0, 100.0, 400.0, 300.0), score: 0.7, label: 0 };

// IOS merges the fragment into one box carrying the group's max score…
let ios = merge_tiled_detections(vec![a, b], &MergeConfig::default());
assert_eq!(ios.len(), 1);
assert_eq!(ios[0].score, 0.9);

// …while IOU leaves the two separate.
let cfg = MergeConfig { metric: MatchMetric::Iou, ..MergeConfig::default() };
assert_eq!(merge_tiled_detections(vec![a, b], &cfg).len(), 2);