好的,我们来详细解释一下目标检测中非极大值抑制(Non-Maximum Suppression, NMS) 的相关概念和计算过程。
1. 为什么需要 NMS?
- 问题: 目标检测模型(如 Faster R-CNN, YOLO, SSD 等)在推理时,对于同一个目标物体,通常会预测出多个重叠的、不同置信度(confidence score)的候选边界框(Bounding Boxes) 。直接输出所有这些框会导致:
- 结果冗余:同一个物体被检测到多次。
- 结果不清晰:难以确定哪个框最能代表物体的位置。
- 影响下游任务:如目标跟踪、行为识别等需要精确目标位置的任务。
- 目标: 从众多重叠的候选框中,为每个实际存在的物体 选出一个 最优的(通常是置信度最高的)、最能代表该物体位置的边界框,同时抑制(删除) 掉那些与其高度重叠但置信度较低的冗余框。
2. NMS 的核心思想
NMS 的基本思想非常简单:"只留下最好的,抑制掉和它太像的(重叠度高的)但不是最好的"。
- 排序: 将所有候选框按照其置信度(Confidence Score) 从高到低进行排序。
- 选取与抑制:
- 选取当前置信度最高的框,将其加入到最终输出结果列表中。
- 计算这个最高分框与剩余所有框 的交并比(Intersection over Union, IoU)。
- 将所有 IoU 值超过预设阈值(NMS Threshold) 的框删除(抑制掉)。这些被删除的框被认为与当前最高分框检测的是同一个物体,只是不够好。
- 迭代: 在剩余的框(未被选取和未被抑制的)中,重复步骤 2(排序、选取最高分、抑制高 IoU 的框),直到没有剩余的框为止。
3. 关键概念
- 置信度(Confidence Score): 模型预测的该边界框内包含目标物体且位置准确的概率(或得分)。通常介于 0 到 1 之间,值越高表示模型越确信。
- 交并比(IoU): 衡量两个边界框重叠程度的指标。
- 计算:
IoU(A, B) = Area(A ∩ B) / Area(A ∪ B)
- 含义: IoU = 1 表示两个框完全重叠;IoU = 0 表示两个框完全不重叠。
- 作用: NMS 用它来判断两个框是否检测了同一个物体。如果 IoU 很高(超过阈值),则认为它们检测的是同一个物体。
- 计算:
- NMS 阈值(NMS Threshold): 一个预设的 IoU 阈值(通常设置在 0.3 到 0.7 之间,常见值为 0.5 或 0.45)。它是决定是否抑制一个框的关键参数。
- 阈值较高(如 0.7): 抑制更严格。只有当两个框重叠非常严重时,才会抑制掉一个。这可能导致对于靠得很近的物体保留多个框(漏抑制)。
- 阈值较低(如 0.3): 抑制更宽松。重叠稍多的框就会被抑制。这可能导致对于遮挡或部分重叠的物体只保留一个框(过度抑制)。
- 边界框(Bounding Box): 通常用
(x_min, y_min, x_max, y_max)
或(center_x, center_y, width, height)
表示目标的位置。
4. NMS 计算过程(步骤详解 + 示例)
假设场景: 模型对图像中的一个猫检测出了以下 5 个候选框(用 (x1, y1, x2, y2, score)
表示):
- Box A: (10, 10, 50, 50, 0.9)
- Box B: (15, 15, 55, 55, 0.85)
- Box C: (40, 40, 80, 80, 0.7)
- Box D: (12, 12, 52, 52, 0.6)
- Box E: (45, 45, 85, 85, 0.5)
设定: NMS 阈值 iou_threshold = 0.5
计算过程:
-
按置信度排序:
- 排序后:
A(0.9) > B(0.85) > C(0.7) > D(0.6) > E(0.5)
- 排序后:
-
第一轮迭代:
- 选取: 当前最高分框
A (0.9)
加入最终输出列表Output = [A]
。 - 计算 IoU(A, others):
IoU(A, B)
: A(10,10,50,50), B(15,15,55,55)- 交集:
x1_i = max(10,15)=15
,y1_i = max(10,15)=15
,x2_i = min(50,55)=50
,y2_i = min(50,55)=50
Area_i = (50-15) * (50-15) = 35*35 = 1225
Area_A = (50-10)*(50-10) = 40*40 = 1600
Area_B = (55-15)*(55-15) = 40*40 = 1600
Area_u = 1600 + 1600 - 1225 = 1975
IoU(A, B) = 1225 / 1975 ≈ 0.62
> 0.5 (抑制 B)
- 交集:
IoU(A, C)
: A(10,10,50,50), C(40,40,80,80)- 交集:
x1_i = max(10,40)=40
,y1_i = max(10,40)=40
,x2_i = min(50,80)=50
,y2_i = min(50,80)=50
Area_i = (50-40)*(50-40) = 10*10 = 100
Area_u = 1600 + (80-40)*(80-40) - 100 = 1600 + 1600 - 100 = 3100
(Area_C = 40*40=1600)IoU(A, C) = 100 / 3100 ≈ 0.032
< 0.5 (保留 C)
- 交集:
IoU(A, D)
: A(10,10,50,50), D(12,12,52,52) (类似 B 的计算,IoU 会很高,假设 ≈ 0.8 > 0.5) (抑制 D)IoU(A, E)
: A(10,10,50,50), E(45,45,85,85) (类似 C 的计算,IoU 会很低,假设 ≈ 0.02 < 0.5) (保留 E)
- 抑制后剩余框:
C(0.7)
,E(0.5)
(B 和 D 被抑制移除)。
- 选取: 当前最高分框
-
第二轮迭代:
- 选取: 当前剩余框中最高分框
C (0.7)
加入最终输出列表Output = [A, C]
。 - 计算 IoU(C, others): (剩余框只剩 E)
IoU(C, E)
: C(40,40,80,80), E(45,45,85,85)- 交集:
x1_i = max(40,45)=45
,y1_i = max(40,45)=45
,x2_i = min(80,85)=80
,y2_i = min(80,85)=80
Area_i = (80-45)*(80-45) = 35*35 = 1225
Area_C = (80-40)*(80-40) = 40*40 = 1600
Area_E = (85-45)*(85-45) = 40*40 = 1600
Area_u = 1600 + 1600 - 1225 = 1975
IoU(C, E) = 1225 / 1975 ≈ 0.62
> 0.5 (抑制 E)
- 交集:
- 抑制后剩余框: 无。
- 选取: 当前剩余框中最高分框
-
结束: 没有剩余框了。最终输出列表
Output = [A, C]
。
结果解释:
- 框
A
和框B
、D
高度重叠(IoU > 0.5),且A
置信度最高,所以只保留A
,抑制了B
和D
。 - 框
C
和框E
高度重叠(IoU > 0.5),且C
置信度更高,所以只保留C
,抑制了E
。 - 框
A
和框C
重叠很小(IoU < 0.5),被认为是两个不同的物体(或者同一个物体的两个不同部分,但通常我们认为是两只不同的猫),所以都被保留。
最终,图像中输出了两个边界框 A
和 C
,分别代表检测到的两个(可能不同的)目标。
5. 重要考虑与变体
- 按类别进行 NMS (Per-Class NMS): 这是最常见的做法。首先按物体类别分组,然后在每个类别内部独立地应用上述 NMS 算法。这是因为不同类别的目标即使重叠也不应该互相抑制(例如一只猫和它旁边的椅子)。
- Soft-NMS: 传统的 NMS 是"硬"抑制(直接删除)。Soft-NMS 则是对重叠框的置信度进行衰减而不是直接删除。如果一个框与高分框有较高的 IoU,它的置信度会按一个函数(如线性或高斯函数)降低。这种方法有助于缓解传统 NMS 在物体密集或遮挡场景下的问题(高分框抑制了旁边其实是正确但分数稍低的其他框)。
- 加权 NMS: 在抑制过程中,不是简单地删除框,而是将与被保留的高分框重叠度高的框的位置和置信度信息进行加权融合,生成一个更精确的新框。这有助于提升定位精度。
- IoU 计算优化: 在实际实现中,IoU 计算是性能瓶颈之一。有高效的计算库(如 NumPy, PyTorch, TensorFlow 中的向量化操作)和近似算法来加速。
- 阈值选择: NMS 阈值是一个超参数,需要根据具体任务(目标大小、密度)和数据集进行调整。在 COCO 等标准数据集的评估中,常报告不同 IoU 阈值(如 0.5:0.95)下的性能,这间接反映了模型和 NMS 阈值选择的综合效果。
6. 总结
NMS 是目标检测流程中不可或缺的后处理步骤,其核心是基于置信度排序和 IoU 阈值来消除冗余检测框,为每个真实目标只保留一个最优的边界框。理解其概念、计算过程和关键参数(尤其是 IoU 阈值)对于有效应用和调优目标检测模型至关重要。针对传统 NMS 的不足,也发展出了 Soft-NMS、Weighted NMS 等改进算法。