点击上方“计算机视觉工坊”,选择“星标”

干货第一时间送达

作者丨仿佛若有光157

来源丨CV技术指南


前言  本文介绍了NMS的应用场合、基本原理、多类别NMS方法和实践代码、NMS的缺陷和改进思路、介绍了改进NMS的几种常用方法、提供了其它不常用的方法的链接。

本文很早以前发过,有个读者评论说没有介绍多类别NMS让他不满意,因此特来补充。顺便补充了NMS的缺点和改进思路。

Non-Maximum Suppression(NMS)非极大值抑制。从字面意思理解,抑制那些非极大值的元素,保留极大值元素。其主要用于目标检测,目标跟踪,3D重建,数据挖掘等。

目前NMS常用的有标准NMS, Soft  NMS, DIOU NMS等。后续出现了新的Softer NMS,Weighted NMS等改进版。

原始NMS


以目标检测为例,目标检测推理过程中会产生很多检测框(A,B,C,D,E,F等),其中很多检测框都是检测同一个目标,但最终每个目标只需要一个检测框,NMS选择那个得分最高的检测框(假设是C),再将C与剩余框计算相应的IOU值,当IOU值超过所设定的阈值(普遍设置为0.5,目标检测中常设置为0.7,仅供参考),即对超过阈值的框进行抑制,抑制的做法是将检测框的得分设置为0,如此一轮过后,在剩下检测框中继续寻找得分最高的,再抑制与之IOU超过阈值的框,直到最后会保留几乎没有重叠的框。这样基本可以做到每个目标只剩下一个检测框。

原始NMS(左图1维,右图2维)算法伪代码如下:

实现代码:(以pytorch为例)

def NMS(boxes,scores, thresholds):x1 = boxes[:,0]y1 = boxes[:,1]x2 = boxes[:,2]y2 = boxes[:,3]areas = (x2-x1)*(y2-y1)_,order = scores.sort(0,descending=True)keep = []while order.numel() > 0:i = order[0]keep.append(i)if order.numel() == 1:breakxx1 = x1[order[1:]].clamp(min=x1[i])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).clamp(min=0)h = (yy2-yy1).clamp(min=0)inter = w*hovr = inter/(areas[i] + areas[order[1:]] - inter)ids = (ovr<=thresholds).nonzero().squeeze()if ids.numel() == 0:breakorder = order[ids+1]return torch.LongTensor(keep)

除了自己实现以外,也可以直接使用torchvision.ops.nms来实现。

torchvision.ops.nms(boxes, scores, iou_threshold)

上面这种做法是把所有boxes放在一起做NMS,没有考虑类别。即某一类的boxes不应该因为它与另一类最大得分boxes的iou值超过阈值而被筛掉。

对于多类别NMS来说,它的思想比较简单:每个类别内部做NMS就可以了。

实现方法:把每个box的坐标添加一个偏移量,偏移量由类别索引来决定。

下面是torchvision.ops.batched_nms的实现源码以及使用方法

#实现源码
max_coordinate = boxes.max()
offsets = idxs.to(boxes) * (max_coordinate + torch.tensor(1).to(boxes))
boxes_for_nms = boxes + offsets[:, None]
keep = nms(boxes_for_nms, scores, iou_threshold)
return keep#使用方法
torchvision.ops.boxes.batched_nms(boxes, scores, classes, nms_thresh)

这里偏移量用boxes中最大的那个作为偏移基准,然后每个类别索引乘以这个基准即得到每个类的box对应的偏移量。这样就把所有的boxes按类别分开了。

在YOLO_v5中,它自己写了个实现的代码。

c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
i = torchvision.ops.nms(boxes, scores, iou_thres)

这里的max_wh相当于前面的boxes.max(),YOLO_v5中取的定值4096。这里的agnostic用来控制是否用于多类别NMS还是普通NMS。

NMS的缺点


1. 需要手动设置阈值,阈值的设置会直接影响重叠目标的检测,太大造成误检,太小达不到理想情况。

2. 低于阈值的直接设置score为0,做法太hard。

3. 只能在CPU上运行,成为影响速度的重要因素。

4. 通过IoU来评估,IoU的做法对目标框尺度和距离的影响不同。

NMS的改进思路


1. 根据手动设置阈值的缺陷,通过自适应的方法在目标系数时使用小阈值,目标稠密时使用大阈值。例如Adaptive NMS

2. 将低于阈值的直接置为0的做法太hard,通过将其根据IoU大小来进行惩罚衰减,则变得更加soft。例如Soft NMS,Softer NMS。

3. 只能在CPU上运行,速度太慢的改进思路有三个,一个是设计在GPU上的NMS,如CUDA NMS,一个是设计更快的NMS,如Fast NMS,最后一个是掀桌子,设计一个神经网络来实现NMS,如ConvNMS。

4. IoU的做法存在一定缺陷,改进思路是将目标尺度、距离引进IoU的考虑中。如DIoU。

下面稍微介绍一下这些方法中常用的一部分,另一部分仅提供链接。

Soft NMS


根据前面对目标检测中NMS的算法描述,易得出标准NMS容易出现的几个问题:当阈值过小时,如下图所示,绿色框容易被抑制;当过大时,容易造成误检,即抑制效果不明显。因此,出现升级版soft NMS。

Soft NMS算法伪代码如下:

标准的NMS的抑制函数如下:

IOU超过阈值的检测框的得分直接设置为0,而soft NMS主张将其得分进行惩罚衰减,有两种衰减方式,第一种惩罚函数如下:

这种方式使用1-Iou与得分的乘积作为衰减后的值,但这种方式在略低于阈值和略高于阈值的部分,经过惩罚衰减函数后,很容易导致得分排序的顺序打乱,合理的惩罚函数应该是具有高iou的有高的惩罚,低iou的有低的惩罚,它们中间应该是逐渐过渡的。因此提出第二种高斯惩罚函数,具体如下:

这样soft NMS可以避免阈值设置大小的问题。

Soft NMS还有后续改进版Softer-NMS,其主要解决的问题是:当所有候选框都不够精确时该如何选择,当得分高的候选框并不更精确,更精确的候选框得分并不是最高时怎么选择 。论文值得一看,本文不作更多的详解。

此外,针对这一阈值设置问题而提出的方式还有Weighted NMS和Adaptive NMS。

Weighted NMS主要是对坐标进行加权平均,实现函数如下:

其中Wi = Si *IoU(M,Bi),表示得分与IoU的乘积。

Adaptive NMS在目标分布稀疏时使用小阈值,保证尽可能多地去除冗余框,在目标分布密集时采用大阈值,避免漏检。

Softer NMS论文链接:

https://arxiv.org/abs/1809.08545

Softer NMS论文代码:

https://github.com/yihui-he/softer-NMS

Weighted NMS论文链接:

https://ieeexplore.ieee.org/document/8026312/

Adaptive NMS论文链接:

https://arxiv.org/abs/1904.03629

DIoU NMS


当IoU相同时,如上图所示,当相邻框的中心点越靠近当前最大得分框的中心点,则可认为其更有可能是冗余框。第一种相比于第三种更不太可能是冗余框。因此,研究者使用所提出的DIoU替代IoU作为NMS的评判准则,公式如下:

DIoU定义为DIoU=IoU-d²/c²,其中c和d的定义如下图所示

在DIoU实际应用中还引入了参数β,用于控制对距离的惩罚程度。

当 β趋向于无穷大时,DIoU退化为IoU,此时的DIoU-NMS与标准NMS效果相当。

当 β趋向于0时,此时几乎所有中心点与得分最大的框的中心点不重合的框都被保留了。

注:除了DIoU外,还有GIoU,CIoU,但这两个都没有用于NMS,而是用于坐标回归函数,DIoU虽然本身也是用于坐标回归,但有用于NMS的。

GIoU


GIoU的主要思想是引入将两个框的距离。寻找能完全包围两个框的最小框(计算它的面积Ac)。

计算公式如下:

当两个框完全不相交时,没有抑制的必要。

当两个框存在一个大框完全包围一个小框时或大框与小框有些重合时,GIoU的大小在(-1,1)之间,不太好用来作为NMS的阈值。

GIoU的提出主要还是用于坐标回归的loss,个人感觉用于NMS不合适,CIoU也是如此,这里之所以提这个,是因为它与DIoU、CIoU一般都是放一起讲的。

其它相关NMS


为了避免阈值设置大小、目标太密集等问题,还有一些其他方法使用神经网络去实现NMS,但并不常用,这里只提一笔,感兴趣的读者请自行了解。如:

ConvNMS:A Convnet for Non-maximum Suppression

Pure NMS Network:Learning non-maximum suppression

Yes-Net: An effective Detector Based on Global Information

Fast NMS:

https://github.com/dbolya/yolact

Cluster NMS:

https://github.com/Zzh-tju/CIoU

Matrix NMS:

https://github.com/WXinlong/SOLO

Torchvision封装的免编译CUDA NMS

此处参考:

https://zhuanlan.zhihu.com/p/157900024

本文仅做学术分享,如有侵权,请联系删文。

干货下载与学习

后台回复:巴塞罗自治大学课件,即可下载国外大学沉淀数年3D Vison精品课件

后台回复:计算机视觉书籍,即可下载3D视觉领域经典书籍pdf

后台回复:3D视觉课程,即可学习3D视觉领域精品课程

计算机视觉工坊精品课程官网:3dcver.com

1.面向自动驾驶领域的多传感器数据融合技术

2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
4.国内首个面向工业级实战的点云处理课程
5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解
6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦
7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化
8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)

9.从零搭建一套结构光3D重建系统[理论+源码+实践]

10.单目深度估计方法:算法梳理与代码实现

11.自动驾驶中的深度学习模型部署实战

12.相机模型与标定(单目+双目+鱼眼)

13.重磅!四旋翼飞行器:算法与实战

14.ROS2从入门到精通:理论与实战

15.国内首个3D缺陷检测教程:理论、源码与实战

重磅!计算机视觉工坊-学习交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有ORB-SLAM系列源码学习、3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、深度估计、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定、激光/视觉SLAM、自动驾驶等)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近4000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

圈里有高质量教程资料、答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~

NMS技术总结(NMS原理、多类别NMS、NMS的缺陷、NMS的改进思路、各种NMS方法)相关推荐

  1. 蓝牙技术的工作原理及用途

    所谓蓝牙技术就是一种全球无线通讯标准,在一定距离内连接设备.目前,蓝牙技术也已应用到各个领域中,并已成为接入物联网(IOT)的主要技术.那关于蓝牙技术的工作原理本文将进行介绍,并概括其特点. 蓝牙技术 ...

  2. 深入掌握Java技术 EJB调用原理分析

      深入掌握Java技术 EJB调用原理分析     一个远程对象至少要包括4个class文件:远程对象:远程对象的接口:实现远程接口的对象的stub:对象的skeleton这4个class文件. 在 ...

  3. 微型计算机原理与接口技术教材,微型计算机原理与接口技术(修订本)(21世纪高职高专规划教材....

    摘要: 本书是根据"计算机应用技术"专业"微型计算机原理与接口技术"课程教学大纲编写的.全书共9章.介绍微型计算机基础,微处理器,指令与指令系统,汇编语言程序设 ...

  4. iOS KVO crash 自修复技术实现与原理解析

    摘要: [前言]KVO API设计非常不合理,于是有很多的KVO三方库,比如 KVOController 用更优的API来规避这些crash,但是侵入性比较大,必须编码规范来约束所有人都要使用该方式. ...

  5. camera(9)--手机摄像头技术结构与原理

    科普:手机摄像头技术结构与原理 21世纪初夏普与当时的日本通信运营商J-PHONE发明了夏普 J-SH04,夏普 J-SH04具有拍照功能,2003年4月24日夏普发售了全球首款百万像素手机J-SH5 ...

  6. java holder详解,Java基础系列18:Holder技术的实现原理分析

    一 简介 (1)Java中的Holder是什么? 我这里说的Holder即这个类:javax.xml.ws.Holder 这个类属于JAX-WS 2.0规范中的一个类.它的作用是为不可变的对象引用提供 ...

  7. 读书笔记:大型网站技术架构-核心原理与案例分析

    李智慧<大型网站技术架构-核心原理与案例分析> 性能 可用性 伸缩性 扩展性 安全性 总结 这本书组织的很不错,语言精练,篇幅也不长,对网站架构的要点讲的狠清楚透彻,思路清晰.主要围绕架构 ...

  8. 业界大佬揭秘美颜技术的算法原理

    业界大佬揭秘美颜技术的算法原理 美颜技术发展现状和应用场景 1. 人脸检测 2. 人脸关键点 3. 瘦脸 4. 磨皮 5. 美白 微信公众号同步 美颜技术发展现状和应用场景   随着视频类APP的流行 ...

  9. 10张图了解UWB技术的工作原理

    关注.星标公众号,直达精彩内容 文章来源:网络 超宽带技术 (UWB) 是最佳定位跟踪技术,因为超宽带技术 (UWB) 的设计的初衷就是实现高精度测距估计,同时进行双向通信.所以 UWB 是当今最好. ...

最新文章

  1. 魅族手机使用应用沙盒一键修改位置数据
  2. Swift-学习Perfect搭建博客
  3. 扩展springmvc组件——当页面跳转时,需要在Controller里面创建一个空方法去跳转或者是创建一个配置类  ||日期格式化说明||自定义格式化器||消息转化器扩展fastjson
  4. Spring boot web(2):web综合开发
  5. YY一下IT业的未来
  6. Python之数据分析(numpy线性模型、线性预测、线性拟合)
  7. 批量修改图像命名方式
  8. ❤️Java面试高频《注解与反射》(建议收藏)❤️
  9. JAVA写接口傻瓜(%)教程(五)
  10. java字典序列化_在Python中解析序列化Java对象
  11. 玉品游戏java_整蛊游戏N合一(玉品)
  12. 计算机内存改成多少合适,32g内存需要设置虚拟内存吗?32g内存虚拟内存设置多少合适...
  13. python自制linux桌面,自己动手写Python实现Ubuntu自动切换壁纸
  14. dw cs6设置字体样式
  15. ysoserial URLDNS解析
  16. 多线程开发实战:Java实现多线程四种方式及相关方法原理
  17. 《微服务系列:SpringCloudConfig配置中心》
  18. kali下apt/dpkg 卸载软件
  19. 京东2015校园招聘笔试编程题
  20. 【lnmp】require(): open_basedir restriction in effect.【百度不是万能的,关键时刻还得靠自己】

热门文章

  1. 巴菲特致股东的一封信:2013年
  2. 美女张璐经典古诗词翻译
  3. 消息服务器 级联,监控服务器级联
  4. OSChina 周五乱弹 —— 想找类似的女孩就要调用同一个父类
  5. usaco 虫洞 洛谷
  6. 转载:“亚洲八大讲师”出炉经…
  7. 【经验分享】MathType试用期到了怎么办?
  8. ygo游戏王卡组_游戏王卡组教程系列【光道卡组】
  9. 网游策划案例:魔兽世界—细节决定成败
  10. 学校计算机语音室管理制度,多媒体、语音室管理制度