目标检测入门之非最大值抑制(NMS)算法

1 引言

非最大值抑制是一种主要用于目标检测的技术,旨在从一组重叠框中选择最佳边界框。在下图中,非最大值抑制的目的是删除黄色和蓝色框,这样我们只剩下绿色框作为最终的预测结果。

闲话少说,我们直接进入NMS算法的介绍中.

在这里插入图片描述

2. 计算NMS的步骤

为了了解什么是boundingbox,以及IOU的含义,我在前篇发表了关于IOU的文章。前篇文章中描述的术语将在本文中继续介绍。我将首先描述NMS在这个特定示例中的工作过程,然后解释一个更通用的算法,将其扩展到不同的场景下。
术语定义:

  • 我们将使用的每个边界框的格式如下:

    b

    o

    x

    _

    l

    i

    s

    t

    =

    [

    x

    1

    y

    1

    x

    2

    y

    2

    c

    l

    a

    s

    s

    c

    o

    n

    f

    i

    d

    e

    n

    c

    e

    ]

    box\_list=[x1,y1,x2,y2,class,confidence]

    box_list=[x1y1x2y2classconfidence]

  • 让我们假设,对于上述这个特定的图像我们有3个边界框,即:

    b

    b

    o

    x

    _

    l

    i

    s

    t

    =

    [

    b

    l

    u

    e

    _

    b

    o

    x

    ,

    y

    e

    l

    l

    o

    w

    _

    b

    o

    x

    ,

    g

    r

    e

    e

    n

    _

    b

    o

    x

    ]

    bbox\_list=[blue\_box,yellow\_box,green\_box]

    bbox_list=[blue_box,yellow_box,green_box]

  • 对于每个框,相关定义如下:

    b

    l

    u

    e

    _

    b

    o

    x

    =

    [

    x

    3

    y

    3

    x

    4

    y

    4

    "

    C

    a

    t

    "

    0.85

    ]

    y

    e

    l

    l

    o

    w

    _

    b

    o

    x

    =

    [

    x

    5

    y

    5

    x

    6

    y

    6

    "

    C

    a

    t

    "

    0.75

    ]

    g

    r

    e

    e

    n

    _

    b

    o

    x

    =

    [

    x

    1

    y

    1

    x

    2

    y

    2

    "

    C

    a

    t

    "

    0.9

    ]

    \begin{aligned} blue\_box &= [x3,y3,x4,y4,"Cat",0.85] \\ yellow\_box &= [x5,y5,x6,y6,"Cat",0.75] \\ green\_box & = [x1,y1,x2,y2,"Cat",0.9] \\ \end{aligned}

    blue_boxyellow_boxgreen_box=[x3y3x4y4"Cat"0.85]=[x5y5x6y6"Cat"0.75]=[x1y1x2y2"Cat"0.9]

2.1 根据置信度过滤候选框

  • 作为NMS中的第一步,我们按照置信度降序对框进行排序。排序后我们得到结果为:

    b

    b

    o

    x

    _

    l

    i

    s

    t

    =

    [

    g

    r

    e

    e

    n

    _

    b

    o

    x

    ,

    b

    l

    u

    e

    _

    b

    o

    x

    ,

    y

    e

    l

    l

    o

    w

    _

    b

    o

    x

    ]

    bbox\_list = [green\_box, blue\_box, yellow\_box]

    bbox_list=[green_box,blue_box,yellow_box]

  • 然后我们定义一个置信度阈值。任何置信度低于此阈值的框都将被删除。对于本例,假设置信度阈值为0.8。使用该阈值,我们将删除黄色框,因为其置信度<0.8。这就给我们留下了:

    b

    b

    o

    x

    _

    l

    i

    s

    t

    =

    [

    g

    r

    e

    e

    n

    _

    b

    o

    x

    ,

    b

    l

    u

    e

    _

    b

    o

    x

    ]

    bbox\_list = [green\_box, blue\_box]

    bbox_list=[green_box,blue_box]

  • 这一步操作后的结果图如下所示:

在这里插入图片描述

2.2 根据IOU过滤

  • 由于框的置信度按降序排列,我们知道列表中的第一个框的置信度最高。我们从列表中删除第一个框,并将其添加到新列表中。在我们的例子中,我们将删除绿色框,并将其放入一个新列表中,比如bbox_list_new。
  • 在这个阶段,我们为IOU定义了一个额外的阈值。此阈值用于删除具有高重叠度的框。其原因如下:如果两个框有大量重叠,并且它们也属于同一类,则很可能两个框都覆盖了同一对象(我们可以从上图验证这一点)。由于真实情况是每个对象只有一个框,因此我们尝试删除置信度较低的框。
  • 在上述示例中,假设我们的IOU阈值为0.5
  • 我们现在开始计算绿框的IOU,其中bbox_list中剩余的每个框也具有相同的类。在我们的例子中,我们将只使用蓝色框来计算绿色框的IOU。
  • 如果绿框和蓝框的IOU大于我们定义的阈值0.5,我们将删除蓝框,因为它的置信度较低,并且有明显的重叠。
  • 对图像中的每个框重复此过程,上述示例中最终只生成具有高置信度的唯一框。如下所示:

在这里插入图片描述

3. NMS算法

总结上述过程,我们可以得到NMS的计算过程如下:

  • 定义置信度阈值和IOU阈值取值。
  • 按置信度降序排列边界框bounding_box
  • 从bbox_list中删除置信度小于阈值的预测框
  • 循环遍历剩余框,首先挑选置信度最高的框作为候选框.
  • 接着计算其他和候选框属于同一类的所有预测框和当前候选框的IOU。
  • 如果上述任两个框的IOU的值大于IOU阈值,那么从box_list中移除置信度较低的预测框
  • 重复此操作,直到遍历完列表中的所有预测框。

代码实现如下:

在这里插入图片描述
相关解释如下:

def nms(boxes, conf_threshold=0.7, iou_threshold=0.4):

此函数将图像候选框列表、置信阈值和iou阈值作为输入。(这里将相应的默认值分别设置为0.7和0.4)

bbox_list_thresholded = []
bbox_list_new = []

接着我们创建了两个名为bbox_list_threshold和bbox_list_new的列表。

  • bbox_list_threshold:包含筛选低置信度框后的新框列表
  • bbox_list_new:包含执行NMS后的最终框列表

boxes_sorted = sorted(boxes, reverse=True, key = lambda x : x[5])

在上述2.1节中,按照置信度的降序对框列表进行排序,并将新列表存储在变量boxes_sorted中.
这里我们采用python的内置sorted函数对其进行排序,该函数根据key字段指定排序规则.
在我们的例子中,我们指定一个关键字reverse=True来按降序对列表进行排序,同时指定第二个关键字用于排序的约束。这里我们使用的lambda函数提供了一个映射,返回每个边界框的第5个元素(置信度)。
经过上述两个参数的设定,在遍历每个框时,排序函数将按照置信度对候选框按照降序排序。

for box in boxes_sorted:
 if box[5] > conf_threshold:
   bbox_list_thresholded.append(box)
 else:
  pass

我们遍历所有已排序的框,并移除置信度低于我们设置的阈值(conf_threshold=0.7)的框

while len(bbox_list_thresholded) > 0:
  current_box = bbox_list_thresholded.pop(0)
  bbox_list_new.append(current_box)

在上述2.2节,我们逐个循环遍历阈值框列表(bbox_list_threshold)中的所有框,直到列表清空。
我们首先从这个列表中删除(弹出)第一个框(当前框),因为它具有最高的可信度,然后将它附加到我们的最终列表中(bbox_list_new)。

for box in bbox_list_thresholded:
 if current_box[4] == box[4]:
    iou = IOU(current_box[:4], box[:4])
    if iou > iou_threshold:
      bbox_list_thresholded.remove(box)

然后,我们迭代列表bbox_list_threshold中所有剩余的框,并检查它们是否与当前框类别相同。(box[4]对应于类别)
如果两个框属于同一类,我们计算这些框之间的IOU, 如果IOU>IOU_threshold,我们将从列表bbox_list_thresholded中移除置信度较低的框。

return bbox_list_new

在非最大移植之后,我们返回更新后的框的列表bbox_list_new。

4. 总结

上述非最大抑制过程可根据具体应用进行相应的修改。本文从非最大抑制算法的原理开始讲起,并将其详细步骤用代码逐一实现,并针对相应的代码做了详细的解释.

您学废了吗?

在这里插入图片描述

关注公众号,后台回复 NMS , 即可获取源码.
在这里插入图片描述
关注公众号《AI算法之道》,获取更多AI算法资讯。

版权声明:本文为CSDN博主「赵卓不凡」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sgzqc/article/details/121500218

赵卓不凡

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

YOLOv3 YOLOv4 YOLOv5老鼠识别检测告警

前言 在食品安全众多环节中,后厨安全无疑是重中之重。俗话说“民以食为天,食以安为先”,食材新鲜程度如何、加工过程规不规范、厨具是否经过清洁消毒等问题,备受大家关注。 一、为什么需要AI检

【目标检测】YOLO、SSD、CornerNet原理介绍

目标检测是计算机视觉中比较简单的任务,用来在一张图篇中找到某些特定的物体,目标检测不仅要求我们识别这些物体的种类,同时要求我们标出这些物体的位置。其中类别是离散数据,位置是连续数据。 目