• 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=Dcup 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 直接丢弃
  • 相关阅读:
    面试题 16.07. 最大数值
    461. 汉明距离
    1290. 二进制链表转整数
    1486. 数组异或操作
    1480. 一维数组的动态和
    面试题 17.04. 消失的数字
    626. 换座位
    125. 验证回文串
    530. 二叉搜索树的最小绝对差
    ASP.NET页面之间传递值的几种方式
  • 原文地址:https://www.cnblogs.com/wjy-lulu/p/13885070.html
Copyright © 2020-2023  润新知