影醉阏轩窗

衣带渐宽终不悔,为伊消得人憔悴。
扩大
缩小

NMS总结

NMS总结

一. NMS

目标检测:同一个类别中,以置信度为首选,置信度高的,抑制(删除)周围交集大的置信度低的框。

这里直接以Soft-NMS论文中的一幅图为例子:

  • 输入:
    • 每次输入一个类,类内进行NMS
    • \(B={b_1,...,b_N}\) :检测到的bounding box
    • \(S={s_1,...,s_N}\) :置信度
    • \(N_t\) :NMS的阈值
  • 设置一个 \(D = \{\}\) 为空,用于存储最终的框BBOX
  • 开始循环(直到 \(B\) 为空结束:
    • \(m=argmax(S)\) :排序置信度,获得index
    • \(M=B[m[0]]\) :这里原论文表述有点歧义,\(M\) 表示当前最大置信度的BBOX
    • \(D=D\cup M, B=B-M,S=S-M[m[0]]\) :将 \(M\) 添加进 \(D\) 中,因为当前置信度最大值一定是最终BBOX。将 \(M\)\(B\) 中移除,获得一个少一个。其实也应该将 \(S\) 进行同等 \(B\) 的操作。
    • 对剩下的 \(B\) 进行循环:
      • 获得当前 \(b_i\)
      • 计算当前 \(IOU(M,b_i)\)
        • 大于阈值:\(B=B-b_i,S=S-s_i\) 直接移除即可,肯定不是最终BBOX
  • 获得 \(D\) 最终的BBOX,如果你想得到置信度,直接类似 \(D\) 操作建立一个空白数组即可。

Paper

部分代码修改,如有BUG请参考源码

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
# 
import numpy as np
 
def py_cpu_nms(dets, thresh):
    """Pure Python NMS baseline."""
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]

    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    order = scores.argsort()[::-1]

    keep = []
    while order.size > 0:
        i = order[0]
        keep.append(i)
        xx1 = np.maximum(x1[i], x1[order])
        yy1 = np.maximum(y1[i], y1[order])
        xx2 = np.minimum(x2[i], x2[order])
        yy2 = np.minimum(y2[i], y2[order])

        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
        ovr = inter / (areas[i] + areas[order] - inter + 1e-9)

        inds = np.where(ovr <= thresh)[0]
        order = order[inds]
        pass

    return keep


if __name__ == "__main__":
    result = py_cpu_nms(np.array([[1,2,3,4,0.5],
                                [1,2,3,4,0.6],
                                [1,2,3,4,0.7],
                                [10,40,30,40,0.8]]), 0.8)
    print(f'NMS Index: {result}')

二. Soft-NMS

NMS直接使用一个固定的阈值进行判断,Soft-NMS顾名思义是利用一个软化的判断条件:

一句话带过:使用一个函数代替 \(IOU\) 的结果,把结果当做置信度,最后进行集中判断。

Paper

三. IOU-Guided NMS

上面两种NMS、Soft-NMS都是使用 \(Score\) 作为最终指标,使用IOU作为抑制指标。

下面这幅图可以看出,\(Score\) 和 IOU 不成正比,进一步提出使用IOU作为最终指标,同时使用IOU也作为抑制指标

伪代码已注释,源代码未开源且需要IOU分支,无法直接剥离出来,所以使用的人基本没有。

Paper

四. Softer-NMS

思想和IOU-NMS差不多,都是解决 \(Score\) 作为最终指标的缺陷

论文主要分为两个部分;

  • 分布估计

这部分可以参考:GFocal

根据上面参考,这篇论文的思路就很简单了。

论文假设Location属于高斯分布(类似Gaussian-YOLO),实际的值属于Delta分布(因为是单一值)

很明显的想到使用分布相似度估计(KL散度等),看下面的图,理想状态是方差为0高斯分布趋向于一条直线

考虑一下,当中心点偏差较大时,方差越大Loss就越大(带入几个数算一下),这里可以当做NMS中的计算,确定好最大置信度,旁边的框方差越大越好

中心点:预测的位置坐标,方差=标准差:高斯分布的参数。在Loss公式,这两个值不是正比例关系,当位置正好等于label时,方差越小越好。其它情况得看公式作图了。

具体公式参考原论文,建议先看懂GFocal,那对于这篇文章就很简单

结果是我们获得了位置方差,同时Cls分支也得到了置信度

  • NMS操作

NMS是直接将大于阈值的框置信度设置为0(对周围框处理)

Soft-NMS是降低大于阈值的框置信度(对周围框处理)

IOU-NMS是将置信度换成IOU,其它和NMS一样(对置信度处理)

Softer-NMS是给予周围框一定权重,影响置信度最大的框(对当前框进行处理)

伪代码如下图所示,最大值按照置信度排序,最终的值是根据周围IOU和方差进行计算的权值,加权到最大置信度框上。笔者未具体看源码

五. DIOU-NMS

这里涉及到目标检测的Loss函数,IOU、GIOU、CIOU、DIOU等,当前使用DIOU作为Loss,效果确实有提升。

该方法直接使用DIOU代替置信度,没什么好说的

六. 总结

下面对方法进行一下总结:

方法 置信度 最大值操作 邻居大于阈值 邻居丢弃情况
NMS 分类score 直接使用 直接抑制为0 直接丢弃
Soft-NMS 分类score 直接使用 按IOU抑制 可能丢弃
IOU-NMS IOU 直接使用 直接抑制为0 直接丢弃
Softer-NMS 分类score 结合邻居使用 按iOU抑制 可能丢弃
DIOU-NMS DIOU 直接使用 直接抑制为0 直接丢弃

posted on 2020-10-27 15:21  影醉阏轩窗  阅读(476)  评论(0编辑  收藏  举报

导航

/* 线条鼠标集合 */ /* 鼠标点击求赞文字特效 */ //带头像评论