算法面试(5)------NMS(非极大值抑制)原理 Soft-NMS、DIoU-NMS 是什么?
- 操作系统:ubuntu22.04
- IDE:Visual Studio Code
- 编程语言:C++11
这是一个目标检测领域的核心后处理问题,也是面试高频考点。我们从基础 NMS 原理 → 缺陷 → 改进版(Soft-NMS、DIoU-NMS) 三层递进,彻底讲透!
一、NMS(Non-Maximum Suppression,非极大值抑制)原理
✅ 核心思想:
“只保留置信度最高的框,抑制与其高度重叠的其他框。”
🧩 为什么需要 NMS?
目标检测模型(如 YOLO、Faster R-CNN)会在多个位置、多个尺度预测同一个目标,产生大量冗余框。NMS 用于去重,保留最优框。
📈 NMS 算法步骤(经典 Greedy-NMS):
假设你有一组检测框:boxes = [box1, box2, …, boxN],每个框有 (x1, y1, x2, y2, score, class)
- 按类别分组 → 对每个类别单独做 NMS
- 按置信度排序 → 从高到低:score[0] > score[1] > …
- 循环选择:
- 选当前最高分框 box_i,加入最终结果
- 计算 box_i 与剩余所有框的 IoU(交并比)
- 删除所有与 box_i 的 IoU > threshold(如 0.5)的框
- 重复步骤 3,直到无框可选
⚙️ IoU 计算公式:
IoU = Area(Intersection) / Area(Union)
🖼️ 举个栗子 🌰:
你检测到 5 个“狗”的框,置信度分别为:0.95, 0.9, 0.8, 0.7, 0.6
- 选 0.95 的框 → 计算它和剩下 4 个框的 IoU
- 假设 0.9 和 0.8 的框 IoU > 0.5 → 删除
- 剩下 0.7 和 0.6 → 选 0.7 → 计算 IoU → 删除 0.6(如果重叠)
- 最终保留:0.95 和 0.7 的框
二、经典 NMS 的缺陷
-
“一刀切”抑制:
- 只要 IoU > 阈值,不管置信度多高,一律删除 → 可能误删正确框
- 🌰 两个挨着的同类物体(如两匹并排的马),高分框可能抑制另一个高分框!
-
只考虑重叠,不考虑位置质量:
- 两个框 IoU 高,但一个定位准,一个定位偏 → 应该保留更准的,但 NMS 只看分数
-
阈值敏感:
- 阈值高 → 漏删(冗余框多)
- 阈值低 → 误删(漏检)
三、改进版 1:Soft-NMS(2017)
论文:Improving Object Detection With One Line of Code
✅ 核心思想:
不直接删除重叠框,而是“降低其置信度”,让它们在后续排序中自然被淘汰。
🧩 算法步骤:
- 同样按置信度排序
- 选最高分框 M,加入结果
- 对每个剩余框 bi:
- 计算 IoU(M, bi)
- 不删除,而是衰减其置信度:
# 线性衰减(原始论文)if IoU > threshold:score_bi = score_bi * (1 - IoU)# 高斯衰减(更常用)score_bi = score_bi * exp(-IoU² / sigma)
- 重新按新分数排序,重复
✅ 优势:
- 保留更多可能正确的框(尤其密集目标)
- 减少“高分框误删高分框”的问题
- 只需改一行代码!
📉 缺点:
- 不能完全解决定位不准的问题
- 衰减策略需调参(sigma)
四、改进版 2:DIoU-NMS(2020)
论文:Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression
✅ 核心思想:
在 NMS 阶段,不仅看 IoU,还看两个框“中心点距离” —— 定位更准的框应该被保留!
🧩 DIoU 公式回顾:
DIoU = IoU - (ρ² / c²)其中:
- ρ² = 中心点欧式距离的平方
- c² = 包围两个框的最小闭包矩形的对角线长度平方
→ DIoU 越大,表示两个框重叠高 + 中心点越近 → 越相似
🔄 DIoU-NMS 做法:
在 NMS 的抑制判断中,用 DIoU 替代 IoU:
if DIoU(box_i, box_j) > threshold:delete box_j
或者更常见的是:
用 DIoU 作为排序或加权依据,结合置信度
例如 YOLOv5/v7 中的 DIoU-NMS:
# 用 DIoU 加权分数,再排序
score_j = score_j * (1 - DIoU(box_i, box_j)) # DIoU越大,惩罚越大
✅ 优势:
- 抑制时考虑定位质量(中心点距离)
- 对遮挡、密集目标更友好
- 与 DIoU Loss 配套使用,端到端优化
🆚 五、三种 NMS 对比表
方法 | 核心机制 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
NMS | IoU > 阈值 → 直接删除 | 简单高效 | 误删高分框,密集目标差 | 通用,实时系统 |
Soft-NMS | IoU > 阈值 → 衰减分数 | 保留更多正确框,密集目标好 | 需调参,计算略增 | 医疗、遥感、密集检测 |
DIoU-NMS | 用 DIoU 衡量相似度 → 抑制 | 考虑定位质量,更合理 | 依赖 DIoU 计算 | 高精度检测(YOLOv5/v7 默认) |
📌 YOLOv8 默认使用 CIoU-NMS(类似 DIoU,增加长宽比约束),进一步优化定位。
💡 六、面试加分回答(STAR 法则)
“在我们的密集人流检测项目中,使用传统 NMS 导致相邻行人框被误删,漏检率达 12%。改用 Soft-NMS
后,通过高斯衰减保留重叠高分框,漏检率降至 5%。后续升级 YOLOv7 后,采用
DIoU-NMS,综合考虑重叠度和中心点距离,漏检率进一步降至 2%,且无额外调参。”
✅ 总结一句话:
NMS 用 IoU 去重,Soft-NMS 用“衰减分数”更温柔,DIoU-NMS 用“距离惩罚”更聪明 ——
三者演进的核心是从“暴力删除”到“智能筛选”。