Tic商业评论

关注微信公众号【站长自定义模块】,定时推送前沿、专业、深度的商业资讯。

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

  • QQ空间
  • 回复
  • 收藏

非极大值抑制 (NMS)

lijingle 深度学习 2022-1-3 14:12 2510人围观

什么是非最大抑制,为什么要使用它?
非最大抑制是一种主要用于目标检测的技术,旨在从一组重叠框中选择最佳边界框。 在下图中,非最大抑制的目的是去除黄色和蓝色框,这样我们就只剩下绿色框了。

图 1:同一对象的多个重叠框


计算 NMS 的过程:

为了大致了解什么是边界框,以及 IOU 的含义,我在同一个帖子上发了两篇文章。(边界框和 IOU)。 这两篇文章中描述的术语和参数在这篇文章中得到了继承。 我将首先继续描述这个特定示例的 NMS 过程,然后解释一个更通用的算法,将它扩展到不同的类。

解释使用的术语:

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

  1. bbox = [x1, y1, x2, y2, 类别, 置信度]。
  2. 让我们假设对于这个特定的图像,我们有一个列表 3 个边界框; 即 bbox_list = [blue_box, Yellow_box, green_box]。
  3. green_box = [x1, y1, x2, y2, ”Cat”, 0.9]  yellow_box = [x5, y5, x6, y6, ”Cat”, 0.75]  blue_box = [x3, y3, x4, y4, ”Cat”, 0.85]!
Stage 1(最初移除boxes):

作为 NMS 的第一步,我们按置信度的降序对框进行排序。 这给了我们:
bbox_list = [green_box,blue_box,yellow_box]

然后我们定义一个置信度阈值。 任何置信度低于此阈值的框都将被删除。 对于此示例,让我们假设置信阈值为 0.8。 使用此阈值,我们将删除黄色框,因为其置信度 < 0.8。 这给我们留下了:
bbox_list = [green_box, blue_box]

图 2:移除黄色框


Stage 2(boxes的 IOU 比较):

  1. 由于框按置信度降序排列,我们知道列表中的第一个框具有最高的置信度。我们从列表中删除第一个框并将其添加到新列表中。 在我们的例子中,我们将删除绿色框,并将其放入一个新列表中,例如 bbox_list_new。
  2. 在这个阶段,我们为 IOU 定义了一个额外的阈值。 此阈值用于删除具有高重叠的框。 其推理如下:如果两个框有大量重叠,并且它们也属于同一类,则两个框很可能覆盖同一对象(我们可以从图 2 中验证这一点)。 由于目标是每个对象有一个框,我们尝试删除置信度较低的框。
  3. 对于我们的例子,假设我们的 IOU 阈值为 0.5
  4. 我们现在开始计算 bbox_list 中每个剩余框也具有相同类的绿色框的 IOU。 在我们的例子中,我们将只用蓝色框计算绿色框的 IOU。
  5. 如果绿框和蓝框的 IOU 大于我们定义的阈值 0.5,我们将移除蓝框,因为它具有较低的置信度,并且也有显着的重叠。
  6. 对图像中的每个框重复此过程,最终只得到具有高置信度的唯一框。

图 3:非最大抑制的结果


算法:

  1. 为 Confidence_Threshold 和 IOU_Threshold 定义一个值。
  2. 按置信度的降序对边界框进行排序。
  3. 删除置信度 < Confidence_Threshold 的框
  4. 循环所有剩余的框,首先从置信度最高的框开始。
  5. 计算当前框的 IOU,剩余的所有框都属于同一类。
  6. 如果 2 个框的 IOU > IOU_Threshold,则从我们的框列表中删除置信度较低的框。
  7. 重复此操作,直到我们遍历完列表中的所有框。

代码:

下面的代码是执行非最大抑制的基本功能。 以下代码段中使用的 IOU 函数与上一篇文章中使用的函数相同(代码可在此处找到)。 

可以优化以下用于计算 NMS 的代码以提高性能。


def nms(boxes, conf_threshold=0.7, iou_threshold=0.4):
该函数将特定图像的框列表、置信阈值和 iou 阈值作为输入。 (我已将它们的默认值分别设置为 0.7 和 0.4)
bbox_list_thresholded = []
bbox_list_new = []
我们创建了 2 个名为 bbox_list_thresholded 和 bbox_list_new 的列表。
bbox_list_thresholded:包含过滤低置信度框后的新框列表
bbox_list_new:包含执行NMS后的最终box列表
boxes_sorted = sorted(boxes, reverse=True, key = lambda x : x[5])
我们通过按置信度降序对框列表进行排序来开始阶段 1,并将新列表存储在变量 box_sorted 中。 称为 sorted 的内置 Python 函数遍历我们的框列表,
并根据我们指定的关键字对其进行排序。 在我们的例子中,我们指定关键字 reverse=True 以降序对列表进行排序。 第二个关键字 key 指定我们要用于
排序的约束。 我们使用的 lambda 函数提供了一个映射,该映射返回每个边界框的第 5 个元素(置信度)。 sorted 函数在迭代每个框时,
会查看 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 阶段,我们将阈值框列表(bbox_list_thresholded)中的所有框一一循环,直到列表被清空。
我们首先从这个列表(current_box)中删除(弹出)第一个框,因为它具有最高的置信度,并将其附加到我们的最终列表(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_thresholded 中所有剩余的框,并检查它们是否与当前框属于同一类。 (box[4] 对应类)
如果两个框属于同一类,我们计算这些框之间的 IOU(我们将 box[:4] 传递给 IOU 函数,因为它对应于 (x1, y1, x2, y2) 的值,
因为我们的 IOU 函数不需要class和 confidence)。如果 IOU > iou_threshold,我们从列表 bbox_list_thresholded 中删除该框,
因为该框是置信度较低的框。
return bbox_list_new
在非最大抑制之后,我们返回更新的框列表。

最终总结:
可以根据应用修改非最大值抑制的此过程。 例如,模型 YOLOV3 使用两组置信度作为阈值度量。 对该算法的另一个修改称为soft NMS,我将在另一篇文章中解释。
我创建了一个代码,该代码针对具有 2 个不同类别的图像执行 NMS 阈值的整个过程。 我将在下面附上它的结果。 完整的代码可以在这里找到。


路过

雷人

握手

鲜花

鸡蛋
我有话说......
电话咨询: 135xxxxxxx
关注微信