目标检测后处理核心: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以获得更好的性能。

相关推荐
枫叶丹417 分钟前
实时语音 Agent:从语音机器人到连续协作界面
人工智能·chatgpt·机器人·语音识别·agent·codex
戴西软件29 分钟前
戴西iDWS.3DViz Suite数据轻量化可视化软件,从传统桌面软件向云端协同的重大突破
大数据·运维·网络·人工智能·机器学习·3d
AIkk8631 分钟前
2026年AI证件照工具功能速览:三款实用方案对比
人工智能
ReleaseU32 分钟前
Harness + MCP:打通企业工具链的最后一步
人工智能·大模型
衡石科技1 小时前
衡石科技携手超聚变联合发布HENGSHI BOX,引领私域ChatBI规模化落地
大数据·人工智能·科技
新知图书1 小时前
10.4 交互优化与用户体验提升
人工智能·多模态·智能体
IT_陈寒1 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端
敢敢是只喵i1 小时前
一个本地 AI Agent 要操作多个门店或 SaaS 账号,应该怎样安全切换身份?
人工智能·安全·ai·系统架构·业界资讯