Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Obss Sahi Match Threshold Tuning

From Leeroopedia




Knowledge Sources
Domains Computer_Vision, Object_Detection, Optimization
Last Updated 2026-02-08 12:00 GMT

Overview

Guidelines for tuning the postprocess match threshold and selecting between IOU and IOS match metrics to balance duplicate removal against object retention.

Description

After sliced inference, overlapping tiles produce duplicate detections for objects near tile boundaries. SAHI's postprocessing step merges or suppresses these duplicates using a match threshold — two predictions are considered duplicates if their overlap metric exceeds this threshold. The choice of match metric (IOU vs IOS) fundamentally changes how "overlap" is measured.

IOU (Intersection Over Union) = `intersection / (area1 + area2 - intersection)` — strict, penalizes size differences.

IOS (Intersection Over Smaller) = `intersection / min(area1, area2)` — lenient, better for contained/partial overlaps typical of sliced inference.

Usage

Use this heuristic when tuning `postprocess_match_threshold` and `postprocess_match_metric` in `get_sliced_prediction()`. Consider adjusting when:

  • Duplicate detections persist in the output (lower the threshold)
  • Valid distinct objects are being incorrectly merged (raise the threshold)
  • Small objects near boundaries are being suppressed (switch to IOS)
  • Low-confidence predictions cause excessive false merges (see Confidence_Threshold_Setting)

The Insight (Rule of Thumb)

  • Default Metric: `postprocess_match_metric="IOS"` — recommended for sliced inference because it handles the asymmetric overlaps typical at tile boundaries.
  • Default Threshold: `postprocess_match_threshold=0.5` — 50% overlap required to consider predictions as duplicates.
  • Default Algorithm: `postprocess_type="GREEDYNMM"` — Greedy Non-Maximum Merging, which merges overlapping predictions (keeping both contributions) rather than suppressing one.
  • Auto-Switch Rule: When `model_confidence_threshold < 0.1`, SAHI automatically switches to `NMS + IOU` regardless of user settings, because low-confidence predictions with GREEDYNMM/IOS produce too many false positives.
  • Trade-off: Lower threshold = more aggressive merging (fewer duplicates, risk of losing distinct objects). Higher threshold = more conservative (more duplicates, but distinct objects preserved).

Reasoning

IOS is the default because sliced inference creates a specific pattern of overlaps: the same object detected in two adjacent tiles will have bounding boxes offset by the tile boundary, creating an asymmetric overlap where one box may fully contain the other. IOU penalizes this asymmetry (the union is large relative to the intersection), while IOS correctly identifies it as a match.

The 0.5 threshold is empirically balanced: most true duplicates from overlapping tiles will have IOS > 0.5, while distinct adjacent objects will have IOS < 0.5. This was validated across diverse datasets by the SAHI community.

The auto-switch to NMS/IOU at low confidence prevents a pathological case: when the model outputs many low-confidence predictions, the merging behavior of NMM/GREEDYNMM can combine these noisy predictions into phantom detections. NMS with IOU is more conservative, suppressing rather than merging.

Code evidence from `sahi/predict.py:44,548-554`:

LOW_MODEL_CONFIDENCE = 0.1

if not force_postprocess_type and model_confidence_threshold < LOW_MODEL_CONFIDENCE and postprocess_type != "NMS":
    logger.warning(
        f"Switching postprocess type/metric to NMS/IOU since confidence "
        f"threshold is low ({model_confidence_threshold})."
    )
    postprocess_type = "NMS"
    postprocess_match_metric = "IOU"

Merge logic from `sahi/postprocess/utils.py:265-288`:

def merge_object_prediction_pair(pred1, pred2):
    merged_bbox = get_merged_bbox(pred1, pred2)      # Union of boxes
    merged_score = get_merged_score(pred1, pred2)     # Max score
    merged_category = get_merged_category(pred1, pred2)  # Category of higher-scoring pred

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment