目标检测(后处理):从 NMS 到 Soft-NMS 到 Softer NMS

目标检测(后处理):从 NMS 到 Soft-NMS 到 Softer NMS

1、NMS

非最大抑制(NMS)主要用于基于深度学习的目标检测模型输出的后处理,从而去除冗余的检测框,获得正确的检测结果。示意图如下:
在这里插入图片描述

算法流程:

  1. 将网络输出框集合 B B B 按照置信度分数 S S S 从高到低的顺序排序,定义 D D D 为最终检测框集合, N t N_t Nt N M S NMS NMS 阈值。
  2. B B B 不为空集时:
    • m m m 为置信度分数最高的框,将 m m m 放入 D D D,并将它从 B B B 中删除
    • 对于 B B B 中余下的每个框 b i b_i bi
      如果 i o u ( m , b i ) ≥ N t iou(m, b_i)\ge N_t iou(m,bi)Nt,则将 b i b_i bi B B B 中删除
  3. 返回检测结果 D D D

通过分析可以发现 N M S NMS NMS 存在以下几个缺陷:

  1. 稠密场景下漏检多:如下图 1 1 1 所示,当两个目标距离较近存在部分重叠时,置信度较小的目标漏检的可能性较大。
    在这里插入图片描述
    图 1: 红色框的置信度比绿色框的置信度高,两个框重叠较多,NMS 会将绿色框过滤
  2. N M S NMS NMS 默认置信度分数较高的框,定位更精确,由于分类和回归任务没有直接相关性,因此这个条件并不总是成立。比如图 2 2 2 中,置信度分数高的边界框并不总是比置信度低的框更可靠。
    在这里插入图片描述
    图 2: ( a ) (a) (a) 中两个边界框位置都不够精确; ( b ) (b) (b) 中置信度较高的边界框的左边界精确度较低
  3. G r o u n d   T r u t h Ground~Truth Ground Truth 的标注可能并不可靠。
    代码:
import numpy as np

def nms(dets, Nt):

    x1 = dets[:,0]
    y1 = dets[:,1]
    x2 = dets[:,2]
    y2 = dets[:,3]
    scores = dets[:,4]

    order = scores.argsort()[::-1]
    #计算面积
    areas = (x2 - x1 + 1)*(y2 - y1 + 1)

    #保留最后需要保留的边框的索引
    keep = []
    while order.size > 0:
        # order[0]是目前置信度最大的,肯定保留
        i = order[0]
        keep.append(i)
        
        #计算窗口i与其他窗口的交叠的面积
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])

        #计算相交框的面积,不相交时用0代替
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h

        #计算IOU:相交的面积/相并的面积
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
        
        inds = np.where(ovr < thresh)[0]
        order = order[inds + 1]

    return keep

# test
if __name__ == "__main__":
    dets = np.array([[30, 20, 230, 200, 1],
                     [50, 50, 260, 220, 0.9],
                     [210, 30, 420, 5, 0.8],
                     [430, 280, 460, 360, 0.7]])
    thresh = 0.35
    keep_dets = nms(dets, thresh)
    print(keep_dets)
    print(dets[keep_dets])

时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 为待筛选检测框数量


2、Soft-NMS

针对 N M S NMS NMS 存在的第一个问题,通过分析发现主要是因为在 N M S NMS NMS 算法中每次直接将与 m m m i o u iou iou 大于等于 N t N_t Nt 的检测框直接删除导致的。 因此基于 N M S NMS NMS 算法, S o f t − N M S Soft-NMS SoftNMS 进行了如下改进:

将于 m m m 重叠的检测框置信度降低,而不是直接删除。

这样可能存在另一个问题,同一目标的其他检测框也可能被保留下来。因此需要设计合适的策略,既保留相近的其他目标,又删除重复检测的目标。直觉上可以发现通常重复的检测框具有更高的重叠,因此可以根据 i o u iou iou 大小来设计置信度分数下降的程度。置信度修正策略如下:
s i = { s i , iou ⁡ ( M , b i ) &lt; N t s i ( 1 − iou ⁡ ( M , b i ) ) , iou ⁡ ( M , b i ) ≥ N t s_{i}=\left\{\begin{array}{ll}{s_{i},} &amp; {\operatorname{iou}\left(\mathcal{M}, b_{i}\right)&lt;N_{t}} \\ {s_{i}\left(1-\operatorname{iou}\left(\mathcal{M}, b_{i}\right)\right),} &amp; {\operatorname{iou}\left(\mathcal{M}, b_{i}\right) \geq N_{t}}\end{array}\right. si={si,si(1iou(M,bi)),iou(M,bi)<Ntiou(M,bi)Nt
该策略为 i o u iou iou 的线性函数,同样可以使用高斯惩罚函数
s i = s i ∗ e − i  ou  ( M , b i ) 2 σ , ∀ b i ∉ D s_{i}=s_{i}*e^{-\frac{\mathrm{i} \text { ou }\left(\mathcal{M}, b_{i}\right)^{2}}{\sigma}}, \forall b_{i} \notin \mathcal{D} si=sieσi ou (M,bi)2,bi/D
算法流程如下图所示:
在这里插入图片描述

图 3: 红色框中的代码是 NMS 的方法,绿色框中的代码为 Soft-NMS 的实现—NMS等价于Soft-NMS的特殊情况(使用0/1惩罚项代替线性或高斯惩罚函数)

代码:

# -*- coding:utf-8 -*-
import numpy as np
def py_cpu_softnms(dets, Nt=0.3, sigma=0.5, thresh=0.5, method=2):
    """
    py_cpu_softnms
    :param dets:   boexs 坐标矩阵 format [x1, y1, x2, y2, score]
    :param Nt:     iou 交叠阈值
    :param sigma:  使用 gaussian 函数的方差
    :param thresh: 最后的分数阈值
    :param method: 使用的方法,1:线性惩罚;2:高斯惩罚;3:原始 NMS
    :return:       留下的 boxes 的 index
    """

    N = dets.shape[0]
    # the order of boxes coordinate is [x1,y1,x2,y2]
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)

    for i in range(N):
        # intermediate parameters for later parameters exchange
        tB = dets[i, :4]
        ts = dets[i, 4]
        ta = areas[i]
        pos = i + 1

        if i != N-1:
            maxscore = np.max(dets[:, 4][pos:])
            maxpos = np.argmax(dets[:, 4][pos:])
        else:
            maxscore = dets[:, 4][-1]
            maxpos = -1

        if ts < maxscore:
            dets[i, :] = dets[maxpos + i + 1, :]
            dets[maxpos + i + 1, :4] = tB

            dets[:, 4][i] = dets[:, 4][maxpos + i + 1]
            dets[:, 4][maxpos + i + 1] = ts

            areas[i] = areas[maxpos + i + 1]
            areas[maxpos + i + 1] = ta

        # IoU calculate
        xx1 = np.maximum(dets[i, 0], dets[pos:, 0])
        yy1 = np.maximum(dets[i, 1], dets[pos:, 1])
        xx2 = np.minimum(dets[i, 2], dets[pos:, 2])
        yy2 = np.minimum(dets[i, 3], dets[pos:, 3])

        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
        ovr = inter / (areas[i] + areas[pos:] - inter)
        
        # Three methods: 1.linear 2.gaussian 3.original NMS
        if method == 1:  # linear
            weight = np.ones(ovr.shape)
            weight[ovr > Nt] = weight[ovr > Nt] - ovr[ovr > Nt]
        elif method == 2:  # gaussian
            weight = np.exp(-(ovr * ovr) / sigma)
        else:  # original NMS
            weight = np.ones(ovr.shape)
            weight[ovr > Nt] = 0

        dets[:, 4][pos:] = weight * dets[:, 4][pos:]

    # select the boxes and keep the corresponding indexes
    inds = np.argwhere(dets[:, 4] > thresh)
    keep = inds.astype(int).T[0]

    return keep

算法时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 为待筛选检测框数量

注意:

通过对比可以看出,原始 N M S NMS NMS S o f t − N M S Soft-NMS SoftNMS 算法中的模式 3 3 3 等价,也就是说,删除 i o u iou iou 过高的重叠框等价于将该重叠框置信度分数置 0 0 0


3、Softer-NMS

S o f t − N M S Soft-NMS SoftNMS 只解决了三个问题中的第一个问题。对于第二个问题,分类置信度分数和框的 i o u iou iou 不是强相关,因此需要一种新的方法来衡量框的位置置信度

作者假设边界框的 4 4 4 个坐标值之间相互独立,并使用单变量高斯分布来预测位置置信度。
P Θ ( x ) = 1 2 π σ 2 e − ( x − x e ) 2 2 σ 2 P_{\Theta}(x)=\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{\left(x-x_{e}\right)^{2}}{2 \sigma^{2}}} PΘ(x)=2πσ2 1e2σ2(xxe)2
其中 Θ \Theta Θ 为可学习参数的集合, x e x_e xe 为被估计的边界框位置。标准差 σ \sigma σ 衡量预测的不确定性,当 σ → 0 \sigma \rightarrow0 σ0 时,表示网络对预测的位置的置信度很高。

G T GT GT 边界框置信度也可以使用高斯分布来表示,当 σ → 0 \sigma \rightarrow0 σ0 时,变成 D i r a c   d e l t a Dirac~delta Dirac delta 函数:
P D ( x ) = δ ( x − x g ) P_{D}(x)=\delta\left(x-x_{g}\right) PD(x)=δ(xxg)
其中, x g x_g xg G T GT GT 边界框位置。


KL 损失函数

目标定位的目标是估计参数 Θ ^ \hat{\Theta} Θ^,使 N N N 个样本的 P Θ ( x ) P_{\Theta}(x) PΘ(x) P D ( x ) P_{D}(x) PD(x) 之间的 K L KL KL 散度最小。
Θ ^ = arg ⁡ min ⁡ Θ 1 N ∑ D K L ( P D ( x ) ∥ P Θ ( x ) ) \hat{\Theta}=\underset{\Theta}{\arg \min } \frac{1}{N} \sum D_{K L}\left(P_{D}(x) \| P_{\Theta}(x)\right) Θ^=ΘargminN1DKL(PD(x)PΘ(x))
使用 K L KL KL 散度作为回归损失函数,对于单个样本:
L r e g = D K L ( P D ( x ) ∥ P Θ ( x ) ) = ∫ P D ( x ) log ⁡ P D ( x ) d x − ∫ P D ( x ) log ⁡ P Θ ( x ) d x = ( x g − x e ) 2 2 σ 2 + log ⁡ ( σ 2 ) 2 + log ⁡ ( 2 π ) 2 − H ( P D ( x ) ) \begin{aligned} L_{r e g} &amp;=D_{K L}\left(P_{D}(x) \| P_{\Theta}(x)\right) \\ &amp;=\int P_{D}(x) \log P_{D}(x) \mathrm{d} x-\int P_{D}(x) \log P_{\Theta}(x) \mathrm{d} x \\ &amp;=\frac{\left(x_{g}-x_{e}\right)^{2}}{2 \sigma^{2}}+\frac{\log \left(\sigma^{2}\right)}{2}+\frac{\log (2 \pi)}{2}-H\left(P_{D}(x)\right) \end{aligned} Lreg=DKL(PD(x)PΘ(x))=PD(x)logPD(x)dxPD(x)logPΘ(x)dx=2σ2(xgxe)2+2log(σ2)+2log(2π)H(PD(x))
分析可知,当 x e x_e xe 预测不准确时,网络预测更大的 σ 2 \sigma^2 σ2 使 L r e g L_{reg} Lreg 更小。 l o g ( 2 π ) 2 \frac{log(2\pi)}{2} 2log(2π) H ( P D ( x ) ) H(P_D(x)) H(PD(x)) 与估计参数 Θ \Theta Θ 无关,因此
L r e g ∝ ( x g − x e ) 2 2 σ 2 + 1 2 log ⁡ ( σ 2 ) L_{r e g} \propto \frac{\left(x_{g}-x_{e}\right)^{2}}{2 \sigma^{2}}+\frac{1}{2} \log \left(\sigma^{2}\right) Lreg2σ2(xgxe)2+21log(σ2)
在这里插入图片描述

图 4: 灰色曲线为估计的分布,橙色曲线为 G T GT GT D i r a c   d e l t a Dirac~delta Dirac delta 分布。当位置 x e x_e xe 估计不准确时,网络预测更大的 σ 2 \sigma^2 σ2 使 L r e g L_{reg} Lreg 更小,蓝色曲线。

由于 σ \sigma σ 位于分母,为了防止梯度爆炸,网络预测 α = l o g ( σ 2 ) \alpha=log(\sigma^2) α=log(σ2) 代替直接预测 σ \sigma σ
L r e g ∝ e − α 2 ( x g − x e ) 2 + 1 2 α L_{r e g} \propto \frac{e^{-\alpha}}{2}\left(x_{g}-x_{e}\right)^{2}+\frac{1}{2} \alpha Lreg2eα(xgxe)2+21α
对于 ∣ x g − x e ∣ &gt; 1 |x_g-x_e|&gt;1 xgxe>1 使用类似于 s m o o t h   L 1 smooth~L_1 smooth L1 损失。
L r e g = e − α ( ∣ x g − x e ∣ − 1 2 ) + 1 2 α L_{r e g}=e^{-\alpha}\left(\left|x_{g}-x_{e}\right|-\frac{1}{2}\right)+\frac{1}{2} \alpha Lreg=eα(xgxe21)+21α


方差投票

获取预测框位置方差后,根据相邻边界框位置方差来对候选框投票。 s o f t e r − N M S softer-NMS softerNMS 算法如下。
在这里插入图片描述

图 5: Softer-NMS 算法。蓝色和绿色分别为 S o f t − N M S Soft-NMS SoftNMS S o f t e r − N M S Softer-NMS SofterNMS

位置更新规则如下:
p i = e − ( 1 − I o U ( b i , b ) ) 2 / σ t x = ∑ i p i x i / σ x , i 2 ∑ i p i / σ x , i 2  subject to  IoU ⁡ ( b i , b ) &gt; 0 \begin{aligned} p_{i} &amp;=e^{-\left(1-I o U\left(b_{i}, b\right)\right)^{2} / \sigma_{t}} \\ x &amp;=\frac{\sum_{i} p_{i} x_{i} / \sigma_{x, i}^{2}}{\sum_{i} p_{i} / \sigma_{x, i}^{2}} \\ &amp; \text { subject to } \operatorname{IoU}\left(b_{i}, b\right)&gt;0 \end{aligned} pix=e(1IoU(bi,b))2/σt=ipi/σx,i2ipixi/σx,i2 subject to IoU(bi,b)>0

通过分析发现,有两类邻近框权重较低:

  1. 位置方差较大的检测框
  2. 和选中框的 i o u iou iou 小的框

由于分类分数较低的框可能有较高的位置置信度,因此分类置信度不参与位置投票。


4、总结

本文主要介绍了 N M S NMS NMS S o f t − N M S Soft-NMS SoftNMS S o f t e r − N M S Softer-NMS SofterNMS 算法,及其主要改进的方向。

  1. N M S NMS NMS 主要用于去除重复的检测框。
  2. S o f t − N M S Soft-NMS SoftNMS N M S NMS NMS 的基础上,不再直接去除重叠较高的检测框,而是将重叠的检测框的分类置信度分数降低。最终去除重复的检测框,而保留存在一定程度重叠的不同目标的检测框,该方法比较适用于稠密目标的检测。
  3. 在前两者的基础上, S o f t e r − N M S Softer-NMS SofterNMS 算法对检测框的位置概率分布进行建模。对于重叠的检测框,根据重叠程度和位置不确定性进行投票,重叠程度高,位置分布方差小的检测框权重大,从而获得更精确的检测框
  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值