Heuristic:Tencent Ncnn NMS Threshold Tuning
| Knowledge Sources | |
|---|---|
| Domains | Computer_Vision, Object_Detection |
| Last Updated | 2026-02-09 19:00 GMT |
Overview
Tuning guide for Non-Maximum Suppression confidence and IoU thresholds in ncnn detection models, balancing detection recall against false positive rate and inference speed.
Description
Non-Maximum Suppression (NMS) in ncnn detection examples uses two thresholds: a confidence threshold (filters detections below a minimum score) and an IoU (Intersection over Union) threshold (merges overlapping boxes). These thresholds directly control the trade-off between detection quality and post-processing speed. Lower confidence thresholds increase recall but also increase false positives and NMS computation time (more boxes to compare). Higher IoU thresholds produce more overlapping detections (useful for crowded scenes) but may create duplicate detections.
Usage
Use this heuristic when deploying object detection models and the detection output has too many false positives, missed detections, or duplicate boxes. Also relevant when post-processing is a performance bottleneck (many candidate boxes).
The Insight (Rule of Thumb)
- Action: Tune `prob_threshold` (confidence) and `nms_threshold` (IoU) based on application needs.
- Value: Standard defaults in ncnn examples: `prob_threshold = 0.25`, `nms_threshold = 0.45`. For higher precision: raise confidence to 0.5-0.7. For higher recall: lower confidence to 0.1-0.15.
- Trade-off: Lower confidence = more detections but more false positives and slower NMS. Higher IoU threshold = more overlapping boxes kept (good for crowds) but potential duplicates.
- Speed Impact: NMS is O(n^2) in the number of candidate boxes. Aggressive confidence filtering (higher threshold) dramatically reduces n, making NMS faster.
Reasoning
The ncnn examples consistently use 0.25 confidence and 0.45 IoU as defaults across YOLOv5, YOLOv7, YOLOv8, and YOLO11. These values represent the YOLO family's standard trade-off. The confidence threshold acts as a pre-filter: the more boxes it removes, the fewer pairwise IoU comparisons NMS must perform. Since NMS uses `qsort_descent_inplace` followed by pairwise IoU computation, reducing candidates from 1000 to 100 reduces comparisons from ~500K to ~5K. For real-time applications on mobile devices, aggressive confidence filtering is often more impactful than model optimization.
Default thresholds from `examples/yolov8.cpp:256-258`:
const float prob_threshold = 0.25f;
const float nms_threshold = 0.45f;
NMS implementation pattern from `examples/yolov8.cpp:73-157`:
static void qsort_descent_inplace(std::vector<Object>& objects) { ... }
static void nms_sorted_bboxes(const std::vector<Object>& faceobjects,
std::vector<int>& picked, float nms_threshold)
{
// For each candidate, compare IoU with all already-picked boxes
// Suppress if IoU > nms_threshold
}