NMS

非最大值抑制算法,诞生至少50年了。

在经典的两阶段目标检测算法中,为了提高对于目标的召回率,在anchor阶段会生成密密麻麻的anchor框。

所以在后处理的时候,会存在着很多冗余框对应着同一个目标。

因此NMS就是后处理中去除冗余框的必不可少的步骤。

NMS算法的具体流程:
输入 boxes,scores, iou_threshold

  • step-1:将所有检出的output_bbox按cls score划分(如pascal voc分20个类,也即将output_bbox按照其对应的cls score划分为21个集合,1个bg类,背景类直接剔除);

  • step-2:在每个类集合内根据各个bbox的cls score做降序排列,得到一个降序的list_k;

  • step-3:对所有的list_k进行遍历,如有20个类,就得对这20个list都进行遍历。从list_k中top1 cls score开始,计算该bbox_x与list中其他bbox_y的IoU,若IoU大于阈值T,则剔除该bbox_y,最终保留bbox_x,从list_k中取出,保存在output_k中最后作为结果输出;

  • step-4:继续选择list_k中top1 cls score,重复step-3中的迭代操作,直至list_k中所有bbox都完成筛选;

  • step-5:对每个集合的list_k,重复step-3、4中的迭代操作,直至所有list_k都完成筛选;

import torch
from torch import Tensor
from typing import Tuple
from ._box_convert import _box_cxcywh_to_xyxy, _box_xyxy_to_cxcywh, _box_xywh_to_xyxy, _box_xyxy_to_xywh
import torchvision
from torchvision.extension import _assert_has_ops[docs]def nms(boxes: Tensor, scores: Tensor, iou_threshold: float) -> Tensor:"""Performs non-maximum suppression (NMS) on the boxes accordingto their intersection-over-union (IoU).NMS iteratively removes lower scoring boxes which have anIoU greater than iou_threshold with another (higher scoring)box.If multiple boxes have the exact same score and satisfy the IoUcriterion with respect to a reference box, the selected box isnot guaranteed to be the same between CPU and GPU. This is similarto the behavior of argsort in PyTorch when repeated values are present.Args:boxes (Tensor[N, 4])): boxes to perform NMS on. Theyare expected to be in ``(x1, y1, x2, y2)`` format with ``0 <= x1 < x2`` and``0 <= y1 < y2``.scores (Tensor[N]): scores for each one of the boxesiou_threshold (float): discards all overlapping boxes with IoU > iou_thresholdReturns:keep (Tensor): int64 tensor with the indicesof the elements that have been keptby NMS, sorted in decreasing order of scores"""_assert_has_ops()return torch.ops.torchvision.nms(boxes, scores, iou_threshold)

NMS存在的一些问题

  • 物体重叠:如下面第一张图,会有一个最高分数的框,如果使用nms的话就会把其他置信度稍低,但是表示另一个物体的预测框删掉(由于和最高置信度的框overlap过大)

  • 存在一些,所有的bbox都预测不准,不是所有的框都那么精准,有时甚至会出现某个物体周围的所有框都标出来了,但是都不准的情况

  • 传统的NMS方法是基于分类分数的,只有最高分数的预测框能留下来,但是大多数情况下IoU和分类分数不是强相关,很多分类标签置信度高的框都位置都不是很准

Soft NMS

Improving Object Detection With One Line of Code

论文发表于 ICCV 2017

http://arxiv.org/abs/1704.04503

传统NMS的不足之处:

  • 为了尽可能较小的增加假阳性率,临近检测的分数应该被抑制,同时要保证其得分在所有检测结果中明显高于假阳性样本;
  • 在使用较低的NMS阈值来去除临近检测冗余的时候效果是sub-optimal,当使用高阈值的时候又会产生漏检率;
  • 当使用比较高的NMS阈值的时候,在测量有重叠阈值范围内的mAP效果会下降;

引入soft NMS的核心就是不会直接通过一个NMS阈值去去除冗余检测,而是对于高度冗余的检测结果通过惩罚函数进行抑制,使得其得分下降;

IOU冗余的越厉害,其得分下降的越厉害;

论文中描述了两种惩罚函数,一种线性函数,一种高斯函数

线性函数,最简单的 就是 f = 1- iou()

高斯函数


惩罚函数的自变量是冗余样本与最大得分样本之间的IOU。

Soft-NMS也是一种贪婪算法,没有找到检测盒的全局最优重新评分。 检测盒的重新评分是以贪婪的方式进行的,因此那些具有较高局部评分的检测不会被抑制。

在soft NMS流程的最后也是有一个阈值,对于列表中所有检测结果的置信度低于阈值的检测结果 进行淘汰;

它仅需要对传统的NMS算法进行简单的改动且不增额外的参数。该Soft-NMS算法在标准数据集PASCAL
VOC2007(较R-FCN和Faster-RCNN提升1.7%)和MS-COCO(较R-FCN提升1.3%,较Faster-RCNN提升1.1%)上均有提升。 Soft-NMS具有与传统NMS相同的算法复杂度,使用高效。
Soft-NMS不需要额外的训练,并易于实现,它可以轻松的被集成到任何物体检测流程中。

优点:

1、Soft-NMS可以很方便地引入到object detection算法中,不需要重新训练原有的模型、代码容易实现,不增加计算量(计算量相比整个object detection算法可忽略)。并且很容易集成到目前所有使用NMS的目标检测算法。

2、soft-NMS在训练中采用传统的NMS方法,仅在推断代码中实现soft-NMS。 作者应该做过对比试验,在训练过程中采用soft-NMS没有显著提高。

3、NMS是Soft-NMS特殊形式,当得分重置函数采用二值化函数时,Soft-NMS和NMS是相同的。soft-NMS算法是一种更加通用的非最大抑制算法。

缺点:

soft-NMS也是一种贪心算法,并不能保证找到全局最优的检测框分数重置。除了以上这两种分数重置函数,我们也可以考虑开发其他包含更多参数的分数重置函数,比如Gompertz函数等。但是它们在完成分数重置的过程中增加了额外的参数。

soft NMS的pytorch代码实现

在Pytorch版本的Faster RCNN当中,roi_head.py文件中执行了nms处理,

所以我要做的是基于pytorch官方实现的nms函数的参数构建复现soft_nms函数。

#= 计算面积
def area_of(left_top, right_bottom):"""Compute the areas of rectangles given two corners.Args:left_top (N, 2): left top corner.right_bottom (N, 2): right bottom corner.Returns:area (N): return the area.return types: torch.Tensor"""hw = torch.clamp(right_bottom - left_top, min=0.0)return hw[..., 0] * hw[..., 1]
# 计算IOU
def iou_of(boxes0, boxes1, eps=1e-5):"""Return intersection-over-union (Jaccard index) of boxes.Args:boxes0 (N, 4): ground truth boxes.boxes1 (N or 1, 4): predicted boxes.eps: a small number to avoid 0 as denominator.Returns:iou (N): IoU values."""overlap_left_top = torch.max(boxes0[..., :2], boxes1[..., :2])overlap_right_bottom = torch.min(boxes0[..., 2:], boxes1[..., 2:])overlap_area = area_of(overlap_left_top, overlap_right_bottom)area0 = area_of(boxes0[..., :2], boxes0[..., 2:])area1 = area_of(boxes1[..., :2], boxes1[..., 2:])return overlap_area / (area0 + area1 - overlap_area)
# 自定义复现 soft_nms函数
def soft_nms(boxes, scores, score_threshold=0.001, sigma=0.5, top_k=-1):"""Soft NMS implementation.References:https://arxiv.org/abs/1704.04503https://github.com/facebookresearch/Detectron/blob/master/detectron/utils/cython_nms.pyxArgs:pytorch 官方实现的nms当中传入的是boxes:Tensor[N,4] scores:Tensor[N], N表示的是每张图片所有检测框的数量box_scores (N, 5): boxes in corner-form and probabilities.score_threshold: boxes with scores less than value are not considered.sigma: the parameter in score re-computation.scores[i] = scores[i] * exp(-(iou_i)^2 / simga)top_k: keep top_k results. If k <= 0, keep all the results.Returns:keep : Tensor    1维的tensor  保存的是boxes中保留下来的框的序号  比如 [2,1,0]int64 tensor with the indicesof the elements that have been keptby NMS, sorted in decreasing order of scores#picked_box_scores (K, 5): results of NMS.sc"""scores = scores.unsqueeze(1)box_scores = torch.cat((boxes,scores), dim=1)  # 将boxes和scores合并为[N,5]的tensorpicked_box_scores = []while box_scores.size(0) > 0:max_score_index = torch.argmax(box_scores[:, 4])  # 取出得分最高的框的索引#print(box_scores[:, 4])cur_box_prob = box_scores[max_score_index, :].clone() # 拷贝得到cur_box_prob:得分最高框的x1,y1,x2,y2和score#print(cur_box_prob)picked_box_scores.append(cur_box_prob)  # 将其填入到框中if len(picked_box_scores) == top_k > 0 or box_scores.size(0) == 1:  # 所有框都遍历则退出breakcur_box = cur_box_prob[:-1]   # 取出当前得分最高的框的四维坐标 x1,y1,x2,y2#print(cur_box)box_scores[max_score_index, :] = box_scores[-1, :]#print("box_scores[-1, :]")#print(box_scores[-1,:])box_scores = box_scores[:-1, :]ious = iou_of(cur_box.unsqueeze(0), box_scores[:, :-1])box_scores[:, -1] = box_scores[:, -1] * torch.exp(-(ious * ious) / sigma)   # 用的是soft NMS论文中的高斯函数box_scores = box_scores[box_scores[:, -1] > score_threshold, :]if len(picked_box_scores) > 0:end_socre = torch.stack(picked_box_scores)[:,-1] # 先转为tensor,然后取出最后的得分一列keep = end_socre.sort(descending = True).indices  # 根据降序排序 并取得排序前的indicesreturn keep  # 返回所有检测框的得分排名,不进行淘汰#return torch.stack(picked_box_scores)else:return torch.tensor([])

softer NMS

论文:Bounding Box Regression with Uncertainty for Accurate Object Detection

地址:https://arxiv.org/abs/1809.08545

Comments: CVPR 2019

WBF

论文:Weighted Boxes Fusion: ensembling boxes for object detection models

论文 :Weighted boxes fusion: Ensembling boxes from different object detection models

地址:https://arxiv.org/abs/1910.13302

Comments: CVPR 2019、CVPR2021

NMS和Soft-NMS都排除了一些框,而WBF则使用了所有框。因此,它可以修复所有模型都预测不准确的情况。本案例如下图所示。NMS/Soft-NMS将只留下一个不准确的框,而WBF将使用所有预测的框来融合它。

代码已开源:https://github.com/ZFTurbo/Weighted-Boxes-Fusion

在这里插入代码片

目标检测中的NMS,soft NMS,softer NMS,Weighted Boxes Fusion相关推荐

  1. 目标检测中的LOU(交并比)和NMS(非极大值抑制)代码实现

    1.LOU, 两个box框的交集比上并集,示意图如下所示: 代码如下所示: #假设box1的维度为[N,4] box2的维度为[M,4] def Lou(box1, box2):N = box1.si ...

  2. 目标检测中NMS和mAP指标中的的IoU阈值和置信度阈值

    有时候路走的太远,会忘了为什么要出发. 学习亦如是 在目标检测中,经常看到置信度阈值和IoU阈值这两个关键参数,且NMS计算和mAP计算中都会有这两个,那它们的区别是什么?本文就这个问题做一次总结. ...

  3. 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法

    ↑ 点击蓝字 关注极市平台作者丨SFXiang来源丨AI算法修炼营编辑丨极市平台 极市导读 本文从降低下采样率与空洞卷积.多尺度训练.优化Anchor尺寸设计.深层和浅层特征融合等多个方面入手,对目标 ...

  4. 综述 | 目标检测中的多尺度检测方法

    本文从降低下采样率与空洞卷积.多尺度训练.优化Anchor尺寸设计.深层和浅层特征融合等多个方面入手,对目标检测中的多尺度检测方法进行了全面概述,并介绍了多尺度检测相关方法. 前面的话 传统卷积网络通 ...

  5. 目标检测中的样本不平衡处理方法——OHEM, Focal Loss, GHM, PISA

    GitHub 简书 CSDN 文章目录 1. 前言 2. OHEM 3. Focal Loss 3.1 Cross Entropy 3.2 Balanced Cross Entropy 3.3 Foc ...

  6. 目标检测中的Label Assignment

    ©PaperWeekly 原创 · 作者|燕皖 单位|渊亭科技 研究方向|计算机视觉.CNN Label Assignment Label assignment 主要是指检测算法在训练阶段,如何给特征 ...

  7. 目标检测中的性能提升方法综述

    文章目录 一.多尺度检测 1.什么是多尺度检测? 2.降低下采样率与空洞卷积 3.多尺度训练 4.优化Anchor尺寸训练 5.深层与浅层特征融合 6.SNIP,尺度归一化 7.TridentNet, ...

  8. 目标检测中特征融合技术(YOLO v4)(上)

    目标检测中特征融合技术(YOLO v4)(上) 论文链接:https://arxiv.org/abs/1612.03144 Feature Pyramid Networks for Object De ...

  9. 目标检测中的Tricks

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 来自 | 知乎    作者 | roger 链接 | https: ...

最新文章

  1. 表达式树 java_Linq表达式树编译非平凡的对象常量,并以某种方式引用它们
  2. 任意角度人脸检测pcn
  3. 什么是延迟?怎样解决?—Vecloud微云
  4. python交互界面用图片当背景_wxPython实现窗口用图片做背景
  5. 当.NET遇到机器学习
  6. 架构师必须掌握的 10 条设计原则
  7. snapchat_我刚刚在Snapchat获得开发人员职位。
  8. 国科大高级人工智能-总结
  9. python调用ping命令_python调用系统命令ping
  10. OpenShift 4 - 在控制台中安装使用 Web Terminal
  11. Dart基础第10篇:类 静态成员 操作符 类的继承
  12. 这个教授的观点颇犀利
  13. Atitit 软件运行环境平台的变迁 attilax大总结 1.1.Native os时代 1.2.Vm时代 java net php 1.3.Script时代 js node。js 1.4.B
  14. Cisco2811配置Qos实现带宽分流
  15. unity3d的下载与安装
  16. android手机内存越来越小,手机内存越来越小怎么办 手机内存清理方法【步骤】...
  17. 技术中的形而上(一)----Linux下的usb四大家族
  18. ietester测试本地html,网站浏览器兼容测试软件–IETester
  19. 含论文基于JAVA户籍信息管理系统【数据库设计、论文、源码、开题报告】
  20. 在Word2019中,如何让回车符消失

热门文章

  1. 总有人会偷看你的朋友圈
  2. f2fs学习笔记 - 5. f2fs基本类图
  3. Dynamics 365 on-premises9.0版本开放下载,附上8.2升级9.0过程
  4. 大型仪器一般都是用计算机,问题:大型仪器一般都使用计算机进行控制,对该计算机除了在性能上能满足要求,在使用方面原则上有何要求。...
  5. 2020-09-07-中国人寿两年java岗位一面
  6. python-docx 不改变原文件调整段落行间距的问题
  7. springboot 模块引用_Spring Boot(三):SpringBoot多模块(module)项目搭建
  8. VB封装的WebSocket模块,拿来即用
  9. Storyboard Animations
  10. 最新的IP归属地数据库-最新IP地址数据库