NMS(Non-Maximum Suppression,非极大值抑制)是目标检测中用来“去重”的后处理算法。它在模型输出的多重、重叠候选框中,保留最有可能的框(置信度最高),并移除与其高度重叠的其他框,从而让每个目标只留下一个检测结果。
定义与目的
- 在一片响应值分布中,只保留“局部峰值”(极大值),抑制附近较小响应,避免重复检测,提升稀疏性与稳定性。
- 核心思想:只留最有代表性的响应,去掉同一结构周围的冗余点/框。
常见应用
- 边缘检测(Canny):沿梯度方向比较,如果当前像素不是该方向的最大值则置零。
- 角点/关键点(Harris、FAST、ORB):对响应图做空间 NMS;ORB 还结合图像金字塔与网格分配,保证空间均匀。
- 目标检测:对候选框做 NMS,去除大量重叠的冗余框。
- 关键点热力图(姿态估计等):从热力图中取峰值点。
基本算法(两类)
- 像素/响应图上的 NMS:
- 对每个像素,取邻域(如 3×3 或半径 r)比较,若不是邻域最大,抑制;可先阈值筛掉弱响应。
- Canny 会沿梯度方向做插值比较,精度更高。
- 检测框 NMS:
- 按分数降序排序;取最高分框,删除与其 IoU 超阈值的框;循环直到耗尽。
关键参数与取舍
- 邻域窗口大小/半径:大了丢真阳,小了重复点多。
- 阈值:先过滤弱响应,降低噪声误检。
- 框 NMS 的 IoU 阈值:高阈值保留更多框(召回高、冗余多),低阈值更激进(更干净、但易漏检)。
- 跨尺度策略:在金字塔内可“同层 NMS”或“合并后再 NMS”。
基本流程(类内独立执行,常称 class-wise NMS)
- 按置信度从高到低排序候选框;
- 取当前置信度最高的框加入结果列表;
- 计算该框与其余框的 IoU(交并比),将 IoU 大于阈值(如 0.5)的框删除;
- 重复 2-3 步直到无框可处理。
补充概念
- IoU(Intersection over Union):两个框交集面积 / 并集面积。反映重叠程度。
- 关键超参数:
- 置信度阈值:先过滤低分框(如 >0.05 或 >0.25)。
- NMS IoU 阈值:越低越“严格”(更易删掉重叠框,可能漏检密集目标);常见范围 0.3–0.7。
- 每类/全局最大保留数:限制输出数量。
- 按类抑制(class-wise) vs. 跨类抑制(class-agnostic):一般按类进行,避免不同类别互相抑制。
伪代码
inputs: boxes B = {b_i}, scores S = {s_i}, iou_thresh
sort indices idx by S desc
keep = []
while idx not empty:
i = idx[0]
keep.append(i)
remove i from idx
for each j in idx:
if IoU(b_i, b_j) > iou_thresh:
remove j from idx
return keep
复杂度与优化
- 朴素实现约 O(N^2)。常见优化包括:在 GPU 上并行 NMS、按网格/块分割、先做强过滤降 N,再做 NMS。
常见变体
- Soft-NMS:不直接删除,而是按重叠程度衰减分数(线性/高斯),提高密集场景召回。
- DIoU-/CIoU-NMS:用距离/形状感知抑制准则,改善重叠严重时的区分。
- Matrix NMS、Fast NMS(如 YOLACT):矩阵化或近似加速。
- WBF(Weighted Boxes Fusion):在多模型融合中以加权平均合框,不属于严格的 NMS,但常与之对比。
实践建议
- 单目标大物体:阈值可略高(0.6–0.7)降低重复框。
- 密集小目标(人群、车辆密集):阈值适当降低或采用 Soft-NMS/DIoU-NMS,避免过度抑制。
- 保持按类 NMS,除非明确需要跨类竞争。
一句话总结 NMS 通过“选最优、抑相似”的策略,基于 IoU 阈值去除冗余检测框,是目标检测输出阶段最关键的去重步骤之一。