关注上方深度学习技术前沿”,选择“星标公众号”

技术干货,第一时间送达!

【导读】前面已经先后为大家详细介绍过了目标检测领域的基础知识:【目标检测基础积累】常用的评价指标 和 目标检测算法基础概念:边框回归和NMS。

所以本文针对目标检测中的NMS作进一步研究,基本的NMS方法,利用得分高的边框抑制得分低且重叠程度高的边框。NMS方法虽然简单有效,但在更高的目标检测需求下,也存在如下缺点

  • 将得分较低的边框强制性地去掉,如果物体出现较为密集时,本身属于两个物体的边框,其中得分较低的也有可能被抑制掉,降低了模型的召回率

  • 速度:NMS的实现存在较多的循环步骤,GPU的并行化实现不是特别容易,尤其是预测框较多时,耗时较多

  • 将得分作为衡量指标。NMS简单地将得分作为一个边框的置信度,但在一些情况下,得分高的边框不一定位置更准

  • 阈值难以确定。过高的阈值容易出现大量误检,而过低的阈值则容易降低模型的召回率,超参很难确定。

针对这些问题陆续产生了一系列改进的方法,具体有:Soft NMS、Softer NMS、Adaptive NMS、IoUNet等

标准的NMS

首先我们还是来简要回顾一下NMS的算法流程:

标准的NMS流程:

(1)将所有的框按类别划分,并剔除背景类,因为无需NMS。(2)对每个物体类中的边界框(B_BOX),按照分类置信度降序排列。(3)在某一类中,选择置信度最高的边界框B_BOX1,将B_BOX1从输入列表中去除,并加入输出列表。(4)逐个计算B_BOX1与其余B_BOX2的交并比IoU,若IoU(B_BOX1,B_BOX2) > 阈值TH,则在输入去除B_BOX2。(5)重复步骤3~4,直到输入列表为空,完成一个物体类的遍历。 (6)重复2~5,直到所有物体类的NMS处理完成。 (7)输出列表,算法结束

在这里,我们再来回顾一下交并比,并附上它的代码实现:

交并比(Intersection over Union)是目标检测NMS的依据,衡量边界框位置,常用交并比指标,交并比(Injection Over Union,IOU)发展于集合论的雅卡尔指数(Jaccard Index),被用于计算真实边界框Bgt(数据集的标注)以及预测边界框Bp(模型预测结果)的重叠程度。IoU是预测框或者是检测结果(DetectionResult)与Ground truth的交集和并集的比值。

  • 交并比的代码实现:

import numpy as npdef compute_iou(box1, box2, wh=False):        """        compute the iou of two boxes.        Args:                box1, box2: [xmin, ymin, xmax, ymax] (wh=False) or [xcenter, ycenter, w, h] (wh=True)                wh: the format of coordinate.        Return:                iou: iou of box1 and box2.        """        if wh == False:                xmin1, ymin1, xmax1, ymax1 = box1                xmin2, ymin2, xmax2, ymax2 = box2        else:                xmin1, ymin1 = int(box1[0]-box1[2]/2.0), int(box1[1]-box1[3]/2.0)                xmax1, ymax1 = int(box1[0]+box1[2]/2.0), int(box1[1]+box1[3]/2.0)                xmin2, ymin2 = int(box2[0]-box2[2]/2.0), int(box2[1]-box2[3]/2.0)                xmax2, ymax2 = int(box2[0]+box2[2]/2.0), int(box2[1]+box2[3]/2.0)

        ## 获取矩形框交集对应的左上角和右下角的坐标(intersection)        xx1 = np.max([xmin1, xmin2])        yy1 = np.max([ymin1, ymin2])        xx2 = np.min([xmax1, xmax2])        yy2 = np.min([ymax1, ymax2])

        ## 计算两个矩形框面积        area1 = (xmax1-xmin1) * (ymax1-ymin1)        area2 = (xmax2-xmin2) * (ymax2-ymin2)

        inter_area = (np.max([0, xx2-xx1])) * (np.max([0, yy2-yy1]))#计算交集面积        iou = inter_area / (area1+area2-inter_area+1e-6)#计算交并比       return iou

Soft NMS

Soft NMS,只靠改进一行代码,便登上ICCV舞台,其核心思想值得思考,有时候一些比较有创新的细微改动,也可以带来很好的效果。

基本思想->改进基本NMS计算公式

基本NMS计算公式:公式中Si代表了每个边框的得分,M为当前得分最高的框,bi为剩余框的某一个,Nt为设定的阈值,可以看到,当IoU大于Nt时,该边框的得分直接置0,相当于被舍弃掉了,从而有可能造成边框的漏检。而SoftNMS算法对于IoU大于阈值的边框,没有将其得分直接置0,而是降低该边框的得分,线性Soft NMS计算方法是:从公式中可以看出,利用边框的得分与IoU来确定新的边框得分,如果当前边框与边框M的IoU超过设定阈值Nt时,边框的得分呈线性的衰减。但是,上式并不是一个连续的函数,当一个边框与M的重叠IoU超过阈值Nt时,其得分会发生跳变,这种跳变会对检测结果产生较大的波动。因此还需要寻找一个更为稳定、连续的得分重置函数,最终Soft NMS给出了如下式所示的重置函数。高斯Soft NMS计算公式:采用这种得分衰减方式,对于某些得分很高的边框,在后续计算中还有可能被作为正确检测框,而不像NMS那样“一棒子打死”,因此可以有效地提升模型召回率。

  • Soft NMS代码实现:

def box_soft_nms(bboxes, scores, labels, nms_threshold=0.3, soft_threshold=0.3, sigma=0.5, mode='union'):    """    soft-nms implentation according the soft-nms paper    :param bboxes: all pred bbox    :param scores: all pred cls    :param labels: all detect class label,注:scores只是单纯的得分,需配合label才知道具体对应的是哪个类    :param nms_threshold: origin nms thres, for judging to reduce the cls score of high IoU pred bbox    :param soft_threshold: after cls score of high IoU pred bbox been reduced, soft_thres further filtering low score pred bbox    :return:    """    unique_labels = labels.cpu().unique().cuda() # 获取pascal voc 20类标签    box_keep = []    labels_keep = []    scores_keep = []    for c in unique_labels: # 相当于NMS中对每一类的操作,对应step-1        c_boxes = bboxes[labels == c] # bboxes、scores、labels一一对应,按照label == c就可以取出对应类别 c 的c_boxes、c_scores        c_scores = scores[labels == c]        weights = c_scores.clone()        x1 = c_boxes[:, 0]        y1 = c_boxes[:, 1]        x2 = c_boxes[:, 2]        y2 = c_boxes[:, 3]        areas = (x2 - x1 + 1) * (y2 - y1 + 1) # bbox面积        _, order = weights.sort(0, descending=True) # bbox根据score降序排序,对应NMS中step-2        while order.numel() > 0: # 对应NMS中step-5            i = order[0] # 当前order中的top-1,保存之            box_keep.append(c_boxes[i]) # 保存bbox            labels_keep.append(c) # 保存cls_id            scores_keep.append(c_scores[i]) # 保存cls_score            if order.numel() == 1: # 当前order就这么一个bbox了,那不玩了,下一个类的bbox操作吧                break            xx1 = x1[order[1:]].clamp(min=x1[i]) # 别忘了x1[i]对应x1[order[0]],也即top-1,寻找Insection区域的坐标            yy1 = y1[order[1:]].clamp(min=y1[i])            xx2 = x2[order[1:]].clamp(max=x2[i])            yy2 = y2[order[1:]].clamp(max=y2[i])            w = (xx2 - xx1 + 1).clamp(min=0) # Insection区域的宽、高、面积            h = (yy2 - yy1 + 1).clamp(min=0)            inter = w * h            ovr = inter / (areas[i] + areas[order[1:]] - inter)            # 经过origin NMS thres,得到高IoU的bboxes index,            # origin NMS操作就直接剔除掉这些bbox了,soft-NMS就是对这些bbox对应的score做权重降低            ids_t= (ovr>=nms_threshold).nonzero().squeeze() # 高IoU的bbox,与inds = np.where(ovr >= nms_threshold)[0]功能类似            weights[[order[ids_t+1]]] *= torch.exp(-(ovr[ids_t] * ovr[ids_t]) / sigma)            # soft-nms对高IoU pred bbox的score调整了一次,soft_threshold仅用于对score抑制,score太小就不考虑了            ids = (weights[order[1:]] >= soft_threshold).nonzero().squeeze() # 这一轮未被抑制的bbox            if ids.numel() == 0: # 竟然全被干掉了,下一个类的bbox操作吧                break            c_boxes = c_boxes[order[1:]][ids] # 先取得c_boxes[order[1:]],再在其基础之上操作[ids],获得这一轮未被抑制的bbox            c_scores = weights[order[1:]][ids]            _, order = c_scores.sort(0, descending=True)            if c_boxes.dim()==1:                c_boxes=c_boxes.unsqueeze(0)                c_scores=c_scores.unsqueeze(0)            x1 = c_boxes[:, 0] # 因为bbox已经做了筛选了,areas需要重新计算一遍,抑制的bbox剔除掉            y1 = c_boxes[:, 1            x2 = c_boxes[:, 2]            y2 = c_boxes[:, 3]            areas = (x2 - x1 + 1) * (y2 - y1 + 1)    return box_keep, labels_keep, scores_keep # scores_keep保存的是未做权重降低的score,降低权重的score仅用于soft-nms操作

加权平均:Softer NMS

基本思想

来自于NMS时用到的score仅仅是分类置信度得分,不能反映Bounding box的定位精准度,既分类置信度和定位置信非正相关的。NMS只能解决分类置信度和定位置信度都很高的,但是对其它三种类型:“分类置信度低-定位置信度低”,“分类置信度高-定位置信度低”,“分类置信度低-定位置信度高“都无法解决。基于此现象,Softer NMS进一步改进了NMS的方法,新增加了一个定位置信度的预测,使得高分类置信度的边框位置变得更加准确,从而有效提升了检测的性能。论文首先假设Bounding box的是高斯分布,ground truth bounding box是狄拉克delta分布(即标准方差为0的高斯分布极限)。KL 散度用来衡量两个概率分布的非对称性度量,KL散度越接近0代表两个概率分布越相似。论文提出了一种基于KL(Kullback-Leibler)散度的边框回归损失函数(KL loss),即为最小化Bounding box regression loss - 预测边框分布越接近于真实物体分布,损失越小。既Bounding box的高斯分布和ground truth的狄拉克delta分布的KL散度。直观上解释,KL Loss使得Bounding box预测呈高斯分布,且与ground truth相近。而将包围框预测的标准差看作置信度。论文提出的Softer-NMS,基于soft-NMS,具体过程与NMS大体相同,只是对预测标注方差范围内的候选框加权平均,使其更精准,在多个数据集上提高了检测边框的位置精度Softer NMS的实现过程,其实很简单,预测的四个顶点坐标,分别对IoU>Nt的预测加权平均计算,得到新的4个坐标点。第i个box的x1计算公式如下(j表示所有IoU>Nt的box):

可以看出,Softer NMS对于IoU大于设定阈值的边框坐标进行了加权平均,希望分类得分高的边框能够利用到周围边框的信息,从而提升其位置的准确度。

Adaptive NMS

研究背景

为了解决行人检测任务中目标过于密集的问题,本文对soft-NMS又进行了优化,提出了一种自适应的非极大值抑制(Adaptive NMS)的行人检测后处理方法,通过网络预测目标周边的密集和稀疏的程度,采用不同的去重策略。该方法对于双阶段和单阶段的检测器都有效果,在密集行人数据库CityPersons和CrowdHuman上都能提升现有的检测器的效果。本文已被CVPR2019接受为Oral。Adaptive NMS算法流程:

我们要使得在人群密集的地方,NMS阈值较大,而人群稀疏的地方NMS阈值较小。但是问题在于怎么判断人群是否密集,又怎么根据密集程度定NMS阈值呢?对于第一个问题。。。当然是用CNN啦!于是文章就定义了第i个物体处的密度如下:

有了密度之后,soft-NMS就改进成了:

其中Nm代表adptive-NMS中M的抑制阈值,dM是M的目标密度将抑制策略分成三类进行讨论:(1)当邻框远离M时(即IoU(2)当M处于密集区域时(即Nm>Nt),目标密度dM作为NMS的抑制阈值;(3)当M处于稀疏区域时(即Nm≤Nt),初始阈值Nt作为NMS的抑制阈值。由于在训练CNN时,每次还需要求出密度作为监督信号,训练网络能够拟合这个密度函数,即输入一张图片,能输出每个位置的物体密度,因此adaptive-NMS保持着greedy-NMS和soft-NMS的效率,还多了一步目标密度的预测,论文设计了一个Density-subnet对目标密度进行回归预测。模型如下:

IoU-Net:定位置信度

研究背景介绍

目标检测的分类与定位通常被两个分支预测。对于候选框的类别,模型给出了一个类别预测,可以作为分类置信度,然而对于定位而言,回归模块通常只预测了一个边框的转换系数,而缺失了定位的置信度,即框的位置准不准,并没有一个预测结果。定位置信度的缺失也导致了在前面的NMS方法中,只能将分类的预测值作为边框排序的依据,然而在某些场景下,分类预测值高的边框不一定拥有与真实框最接近的位置,因此这种标准不平衡可能会导致更为准确的边框被抑制掉。基于此,旷视提出了IoU-Net,增加了一个预测候选框与真实物体之间的IoU分支,并基于此改善了NMS过程,进一步提升了检测器的性能。

IoU-Net的基础架构与原始的Faster RCNN类似,使用了FPN方法作为基础特征提取模块,然后经过RoI的Pooling得到固定大小的特征图,利用全连接网络完成最后的多任务预测。同时,IoU-Net与Faster RCNN也有不同之处,主要有3点:1. 在Head处增加了一个IoU预测的分支,与分类回归分支并行。图中的Jittered RoIs模块用于IoU分支的训练。2. 基于IoU分支的预测值,改善了NMS的处理过程。3. 提出了PrRoI-Pooling(Precise RoI Pooling)方法,进一步提升了感兴趣区域池化的精度。

IoU预测分支

IoU分支用于预测每一个候选框的定位置信度。需要注意的是,在训练时IoU-Net通过自动生成候选框的方式来训练IoU分支,而不是从RPN获取。具体来讲,Jittered RoIs在训练集的真实物体框上增加随机扰动,生成了一系列候选框,并移除与真实物体框IoU小于0.5的边框。实验证明这种方法来训练IoU分支可以带来更高的性能与稳健性。IoU分支也可以方便地集成到当前的物体检测算法中。在整个模型的联合训练时,IoU预测分支的训练数据需要从每一批的输入图像中单独生成。此外,还需要对IoU分支的标签进行归一化,保证其分布在[-1,1]区间中。

基于定位置信度的NMS

由于IoU预测值可以作为边框定位的置信度,因此可以利用其来改善NMS过程。IoU-Net利用IoU的预测值作为边框排列的依据,并抑制掉与当前框IoU超过设定阈值的其他候选框。此外,在NMS过程中,IoU-Net还做了置信度的聚类,即对于匹配到同一真实物体的边框,类别也需要拥有一致的预测值。具体做法是,在NMS过程中,当边框A抑制边框B时,通过下式来更新边框A的分类置信度。

PrRoI-Pooling方法

RoI Align的方法,通过采样的方法有效避免了量化操作,减小了RoIPooling的误差,如图下图所示。但Align的方法也存在一个缺点,即对每一个区域都采取固定数量的采样点,但区域有大有小,都采取同一个数量点,显然不是最优的方法。以此为出发点,IoU-Net提出了PrRoI Pooling方法,采用积分的方式实现了更为精准的感兴趣区域池化,如下图中的右图所示。

与RoI Align只采样4个点不同,PrRoI Pooling方法将整个区域看做是连续的,采用积分公式求解每一个区域的池化输出值,区域内的每一个点(x, y)都可以通过双线性插值的方法得到。这种方法还有一个好处是其反向传播是连续可导的,因此避免了任何的量化过程。

总体上,IoU-Net提出了一个IoU的预测分支,解决了NMS过程中分类置信度与定位置信度之间的不一致,可以与当前的物体检测框架一起端到端地训练,在几乎不影响前向速度的前提下,有效提升了物体检测的精度。

参考链接:

1. https://zhuanlan.zhihu.com/p/1174177892. https://www.jianshu.com/p/86ce2bf3a0133. https://mp.weixin.qq.com/s/y5IQNmS5ZuIuafQQeL3nfw4. https://zhuanlan.zhihu.com/p/686778805. https://zhuanlan.zhihu.com/p/78504109

重磅!DLer-目标检测交流群已成立!

为了能给大家提供一个更好的交流学习平台!针对特定研究方向,我建立了目标检测微信交流群,目前群里已有百余人!本群旨在交流目标检测、密集人群检测、关键点检测、人脸检测、人体姿态估计等内容。

进群请备注:研究方向+学校/公司+昵称(如目标检测+上交+小明)

长按识别添加,邀请您进群!

原创不易,在看鼓励!比心哟!

非极大值抑制_【目标检测系列】非极大值抑制(NMS)的各类变体汇总相关推荐

  1. 【目标检测系列】非极大值抑制(NMS)的各类变体汇总

    关注上方"深度学习技术前沿",选择"星标公众号", 技术干货,第一时间送达! [导读]前面已经先后为大家详细介绍过了目标检测领域的基础知识:[目标检测基础积累] ...

  2. 非极大值抑制_【计算机视觉——RCNN目标检测系列】三、IoU与非极大抑制

    写在前面 在上一篇博客:[计算机视觉-RCNN目标检测系列]二.边界框回归(Bounding-Box Regression)( 戴璞微:[计算机视觉-RCNN目标检测系列]二.边界框回归(Boundi ...

  3. 【R-CNN目标检测系列】三、IoU与非极大抑制

    写在前面 在上一篇博客:[计算机视觉--RCNN目标检测系列]二.边界框回归(Bounding-Box Regression)中我们主要讲解了R-CNN中边界框回归,接下来我们在这篇博客我们讲解R-C ...

  4. 睿智的目标检测31——非极大抑制NMS与Soft-NMS

    睿智的目标检测31--非极大抑制NMS与Soft-NMS 注意事项 学习前言 什么是非极大抑制NMS 1.非极大抑制NMS的实现过程 2.柔性非极大抑制Soft-NMS的实现过程 注意事项 Soft- ...

  5. python目标识别算法_深度学习目标检测系列:一文弄懂YOLO算法|附Python源码

    摘要: 本文是目标检测系列文章--YOLO算法,介绍其基本原理及实现细节,并用python实现,方便读者上手体验目标检测的乐趣. 在之前的文章中,介绍了计算机视觉领域中目标检测的相关方法--RCNN系 ...

  6. 3d max用不同目标做关键帧_基于光流的视频目标检测系列文章解读

    作者:平凡的外卖小哥 全文5747字,预计阅读时间15分钟 1 简介 目前针对于图片的目标检测的方法大致分为两类: faster R-CNN/R-FCN一类: 此类方法在进行bbox回归和分类之前,必 ...

  7. tensorflow2 目标检测_基于光流的视频目标检测系列文章解读

    作者:平凡的外卖小哥 全文5747字,预计阅读时间15分钟 1 简介 目前针对于图片的目标检测的方法大致分为两类: faster R-CNN/R-FCN一类: 此类方法在进行bbox回归和分类之前,必 ...

  8. php大作业含代码_目标检测 | 目标检测技巧大汇总(含代码与解读)

    点击上方"AI算法修炼营",选择加星标或"置顶" 标题以下,全是干货 来自 | 知乎作者丨初识CV来源丨https://zhuanlan.zhihu.com/p ...

  9. 论文阅读 || 目标检测系列 —— RCNN详解

    目录 1. 相关概念 2 R-CNN的结构 2.1 候选框的提取 2.2 缩放候选区域 2.3 通过CNN提取特征向量 2.4 目标种类分类器 2.5 修正bbox 1) 候选框P 到预测框G'的平移 ...

  10. 目标检测系列(七)——CornerNet:detecting objects as paired keypoints

    文章目录 摘要 1.引言 2.相关工作 3.CornerNet 3.1 概况 3.2 检测角点 3.3 角点的分组 3.4 Corner Pooling 3.5 沙漏网络 论文链接: https:// ...

最新文章

  1. C++ protobuf 不仅仅是序列化……
  2. 2009最后一天,为了期盼而祝福
  3. 数据结构(java语言描述)顺序栈的使用
  4. LeetCode 506. 相对名次(map)
  5. python从0到1_Python学习,从0到1
  6. python认证考试mac_Mac OS 平台使用 Python 和 Docker 创建测试用 Https Server
  7. 前端开发的模块化和组件化的定义,以及两者的关系?
  8. 再见Navicat! IDEA的这个兄弟真的很香!我粉了...
  9. Asp.net MVC中如何实现依赖注入(DI)(二)
  10. idea开发java前端_Web前端开发神器 Intellij IDEA
  11. 2020德勤面试开始了吗_刚去四大(德勤)面试,我只说了三个字,就拿到了offer!...
  12. P4568 飞行路线 分层图最短路
  13. 三菱FX2N:PC与PLC建立通讯的几种方式(SC-09通讯电缆+FX2N-485-BD通讯板)
  14. RL真的很简单 手把手带你入门强化学习
  15. MOOS-ivp 实验十四(2)behavior简要概述
  16. unraid安装黑群晖虚拟机开机显示 Starting Kernel with USB boot
  17. Allegro 绘图参数的设置-设置图纸尺寸
  18. NLP-文本处理:词性标注【使用成熟的第三方工具包:中文(哈工大LTP)、英文()】【对分词后得到的“词语列表”进行词性标注,词性标注的结果用于依存句法分析、语义角色标注】
  19. Java语言程序设计 例题9.8(Fan类)
  20. MySQL 一条语句实现若记录存在则更新,不存在则插入

热门文章

  1. 4.剑指Offer --- 解决面试题的思路
  2. 11.Kong入门与实战 基于Nginx和OpenResty的云原生微服务网关 --- 自定义插件
  3. 13.性能之巅 洞悉系统、企业与云计算 --- 案例研究
  4. 6.性能之巅 洞悉系统、企业与云计算 --- CPU
  5. 13.企业应用架构模式 --- 对象-关系元数据映射模式
  6. P2665 [USACO08FEB]连线游戏Game of Lines
  7. [Javascript]把html内容复制到剪贴板
  8. Android中的Can't create handler inside thread that has not called Looper.prepare()异常
  9. 解析WINDOWS中的DLL文件---经典DLL解读
  10. Springboot集成Quartz和RabbitMQ时设置为不自动运行