目标检测后处理核心:NMS非极大值抑制详解

文章目录


在目标检测算法中,模型输出的原始预测框往往数量庞大且高度重叠。为了得到清晰、准确的最终检测结果,NMS非极大值抑制是必不可少的关键步骤。

摘要:NMS(非极大值抑制)是目标检测后处理中的关键步骤,用于从大量高度重叠的候选框中筛选出清晰、准确的最终检测结果。本文先介绍 NMS 的核心思想,再通过一个包含 4 个候选框的完整数值示例,逐步演示"按置信度排序 → 迭代选择 → 计算 IoU → 抑制冗余框"的全过程,并解释多类别目标为何要按类别分组执行 NMS,最后给出完整的执行流程与 Python 伪代码参考。

核心概念

NMS的核心思想非常直观:面对大量可能指向同一目标的候选框,我们只需要保留最佳的那一个,并抑制掉其他冗余的框。

但需要纠正一个常见的误解:NMS的最终结果并不一定是只保留一个候选框。 它保留的数量取决于图像中实际存在的独立目标数量。如果图中存在多个互不重叠的目标,算法会为每个目标各保留一个最佳候选框。

数值计算过程示例

假设在图像中的同一个目标上,算法生成了4个候选框,同时我们对另一个远处目标也生成了一个框:

  • 预设IoU阈值:0.5(判定框与框之间是否"高度重叠"的标准)
  • 输入检测框
置信度 坐标格式 x1, y1, x2, y2
A 0.95 0, 0, 100, 100
B 0.90 10, 10, 90, 90
C 0.85 20, 20, 80, 80
D 0.80 200, 200, 300, 300

步骤1:按置信度排序

将所有候选框按照置信度从高到低排序:

A(0.95) > B(0.90) > C(0.85) > D(0.80)

步骤2:迭代选择(第1轮)

取出当前置信度最高的框 A,并直接将其加入到最终结果集中。

  • 最终结果集A
  • 剩余待处理框:B, C, D

步骤3:计算IoU重叠度

IoU即"交并比",计算公式为:IoU = 交集面积 / 并集面积。

框 A 与其余各框的IoU计算:

  • A与B的IoU

    • 框B完全被框A包含,交集面积就是B的面积:80 × 80 = 6400
    • 并集面积 = 框A面积 + 框B面积 - 交集面积 = 10000 + 6400 - 6400 = 10000
    • IoU = 6400 / 10000 = 0.64
  • A与C的IoU

    • 过计算可得交集面积为3600,并集面积为14400
    • IoU = 3600 / 14400 = 0.36
  • A与D的IoU

    • 两个框距离较远,没有交集
    • IoU = 0

步骤4:抑制冗余候选框

将计算得到的IoU值与预设阈值0.5进行比较:

对比项 IoU值 结论
A与B 0.64 > 0.5,判定为重复框,将B移除(抑制)
A与C 0.36 < 0.5,重叠度不高,保留C
A与D 0.00 < 0.5,完全不同的目标,保留D

经过本轮处理,剩余待处理框为:C, D

步骤5:重复迭代(第2轮)

  1. 从剩余框中取出置信度最高的 C ,加入最终结果集。
    • 最终结果集A, C
    • 剩余待处理框:D
  2. 计算C与D的IoU:由于两个框相距很远,IoU = 0
  3. 0 < 0.5,因此保留D。
    • 剩余待处理框:D

步骤6:重复迭代(第3轮)

取出剩余框中最后的 D,加入最终结果集。

  • 最终结果集A, C, D
  • 剩余待处理框:无

最终结论: 本次NMS操作保留了3个候选框(A、C、D)。框B由于与最高置信度的框A高度重叠而被成功抑制;而框D因为代表不同的目标,被正确保留了下来。

多类别目标如何处理?

在实际的目标检测应用中,图像中往往包含多个类别的目标。此时的处理方式是在每个类别内部单独循环执行NMS

具体流程为:

  1. 按类别分组:将所有候选框根据其预测的类别标签进行分组,例如所有"猫"的框在一组,所有"狗"的框在另一组。
  2. 组内执行NMS:依次对每个类别组独立执行上述的NMS数值计算过程。
  3. 合并结果:将每个类别组最终保留的框汇总起来,作为整体的检测输出。

这样做的原因是为了避免跨类别的误抑制。例如,一只猫和一只狗紧紧挨着,两个框高度重叠。如果不区分类别地全局执行NMS,算法会误认为这是同一个目标的重复框,从而强行移除其中一个,导致漏检。按类别分开处理,就可确保高置信度的"猫"框永远不会去抑制属于"狗"类的候选框。

完整的执行流程

整个目标检测后处理NMS过程的完整流程如下:

复制代码
1. 按类别对所有候选框进行分组
2. 对每个类别依次执行:
   a. 按置信度排序
   b. 选择分数最高的框,加入结果集
   c. 计算该框与其他所有框的IoU
   d. 移除所有IoU大于预设阈值(如0.5)的框
   e. 重复步骤b-d,直至候选框为空
3. 合并所有类别结果,输出最终检测结果

代码参考

NMS的Python伪代码实现如下:

python 复制代码
def nms(bboxes, scores, iou_threshold=0.5):
    # bboxes: 候选框坐标列表,形式为[[x1,y1,x2,y2],...]
    # scores: 对应的置信度列表,形式为[score1, score2,...]

    # 1. 按置信度从大到小排序
    order = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)
    keep = []

    while order:
        # 2. 取出当前最高分的索引
        i = order[0]
        keep.append(i)

        # 3. 计算当前框与其余所有框的IoU
        ious = [compute_iou(bboxes[i], bboxes[j]) for j in order[1:]]

        # 4. 保留IoU < 阈值的框,移除IoU > 阈值的框
        order = [order[j+1] for j, iou in enumerate(ious) if iou < iou_threshold]

    return keep

实践中的补充说明

  • IoU阈值:通常设为0.4~0.6之间,值过高会导致重叠框残留较多,值过低则容易误删邻近的不同目标。
  • 置信度阈值:通常先过滤掉打分过低的候选框(如小于0.5),减少NMS的计算量。
  • 跨类别NMS:特定场景下,若不同类别在语义上互斥,可全局应用NMS以获得更好的性能。

相关推荐
C^h7 小时前
pytorch 适合初学者 0基础学习
人工智能·pytorch·python
charlie1145141917 小时前
现代Qt开发之图像处理进阶:像素操作与格式转换
开发语言·图像处理·qt
Rocky Ding*7 小时前
【三年面试五年模拟】2026-09-06 拼多多 AI Agent研发岗秋招笔试4道算法题完整题解
论文阅读·人工智能·深度学习·机器学习·aigc·ai-native·拼多多
小柯南敲键盘7 小时前
跨马翻译:AI批量图片翻译工具,跨境电商视频字幕翻译与智能抠图一体搞定
人工智能·python·音视频
luckystar513~7 小时前
Geo + AI:【时空智能体】技术剖析
人工智能·ai·gis·geoai·空间智能体·时空智能体
吨吨ai8 小时前
2026年9月8日|GPT‑6 Astra + Codex:Pro 开发者的 AI Agent 工具链
人工智能·gpt
leoZ2318 小时前
2026-09-09-springboot-cloud-deploy-pitfalls
java·前端·javascript·vue.js·人工智能·spring boot·后端
dozenyaoyida8 小时前
AI与大模型新闻日报 | 2026-09-09
人工智能·ai·chatgpt·大模型·新闻
xqqxqxxq8 小时前
AI Agent学习:主动工具发现(李博杰《深入理解 AI Agent》4.8观后总结)
人工智能·学习
海上彼尚9 小时前
Cursor 模型的强度实测排行
前端·人工智能·后端