NMS 和 Soft-NMS
转自https://zhuanlan.zhihu.com/p/42018282
一 NMS
NMS算法的大致思想:对于有重叠的候选框:若大于规定阈值(某一提前设定的置信度)则删除,低于阈值的保留。对于无重叠的候选框:都保留。
所谓非极大值抑制:先假设有6个输出的矩形框(即proposal_clip_box),根据分类器类别分类概率做排序,从小到大分别属于车辆的概率(scores)分别为A、B、C、D、E、F。
(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
就这样一直重复,找到所有被保留下来的矩形框。

如上图F与BD重合度较大,可以去除BD。AE重合度较大,我们删除A,保留scores较大的E。C和其他重叠都小保留C。最终留下了C、E、F三个。
相关代码:
# coding:utf-8
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] # i 是还未处理的图片中的最大评分
keep.append(i) # 保留改图片的值
# 矩阵操作,下面计算的是图片i分别与其余图片相交的矩形的坐标
tmp=x1[order[1:]]
xxxx = x1[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:]]) # 计算出各个相交矩形的面积
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[1:]] - inter) # 只保留比例小于阙值的图片,然后继续处理
inds = np.where(ovr <= thresh)[0]
indsd= inds+1
order = order[inds + 1] return keep
boxes = np.array([[100, 100, 150, 168, 0.63],[166, 70, 312, 190, 0.55],[221, 250, 389, 500, 0.79],[12, 190, 300, 399, 0.9],[28, 130, 134, 302, 0.3]])
thresh = 0.1
keep = py_cpu_nms(boxes, thresh)
print(keep)
二 soft NMS
论文链接:http://cn.arxiv.org/abs/1704.04503
github:bharatsingh430/soft-nms
soft NMS提出尤其对密集物体检测的检测效果有一定的提升作用.
绝大部分目标检测方法,最后都要用到 NMS-非极大值抑制进行后处理。 通常的做法是将检测框按得分排序,然后保留得分最高的框,同时删除与该框重叠面积大于一定比例的其它框。
这种贪心式方法存在如下图所示的问题: 红色框和绿色框是当前的检测结果,二者的得分分别是0.95和0.80。如果按照传统的NMS进行处理,首先选中得分最高的红色框,然后绿色框就会因为与之重叠面积过大而被删掉。
另一方面,NMS的阈值也不太容易确定,设小了会出现下图的情况(绿色框因为和红色框重叠面积较大而被删掉),设置过高又容易增大误检。

思路:不要粗鲁地删除所有IOU大于阈值的框,而是降低其置信度。
soft NMS算法的大致思路为:M为当前得分最高框,bi 为待处理框,bi 和M的IOU越大,bi 的得分si 就下降的越厉害。
算法结构如图所示:

NMS中:

soft NMS中:
(1)线性加权:

(2)高斯加权:

soft NMS仍然有问题:其阈值仍然需要手工设定
soft NMS的相关代码如下:
# coding:utf-8
import numpy as np
def soft_nms(boxes, sigma=0.5, Nt=0.1, threshold=0.001, method=1):
N = boxes.shape[0]
pos = 0
maxscore = 0
maxpos = 0 for i in range(N):
maxscore = boxes[i, 4]
maxpos = i tx1 = boxes[i,0]
ty1 = boxes[i,1]
tx2 = boxes[i,2]
ty2 = boxes[i,3]
ts = boxes[i,4] pos = i + 1
# get max box
while pos < N:
if maxscore < boxes[pos, 4]:
maxscore = boxes[pos, 4]
maxpos = pos
pos = pos + 1 # add max box as a detection
boxes[i,0] = boxes[maxpos,0]
boxes[i,1] = boxes[maxpos,1]
boxes[i,2] = boxes[maxpos,2]
boxes[i,3] = boxes[maxpos,3]
boxes[i,4] = boxes[maxpos,4] # swap ith box with position of max box
boxes[maxpos,0] = tx1
boxes[maxpos,1] = ty1
boxes[maxpos,2] = tx2
boxes[maxpos,3] = ty2
boxes[maxpos,4] = ts tx1 = boxes[i,0]
ty1 = boxes[i,1]
tx2 = boxes[i,2]
ty2 = boxes[i,3]
ts = boxes[i,4] pos = i + 1
# NMS iterations, note that N changes if detection boxes fall below threshold
while pos < N:
x1 = boxes[pos, 0]
y1 = boxes[pos, 1]
x2 = boxes[pos, 2]
y2 = boxes[pos, 3]
s = boxes[pos, 4] area = (x2 - x1 + 1) * (y2 - y1 + 1)
iw = (min(tx2, x2) - max(tx1, x1) + 1)
if iw > 0:
ih = (min(ty2, y2) - max(ty1, y1) + 1)
if ih > 0:
ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih)
ov = iw * ih / ua #iou between max box and detection box if method == 1: # linear
if ov > Nt:
weight = 1 - ov
else:
weight = 1
elif method == 2: # gaussian
weight = np.exp(-(ov * ov)/sigma)
else: # original NMS
if ov > Nt:
weight = 0
else:
weight = 1 boxes[pos, 4] = weight*boxes[pos, 4]
print(boxes[:, 4]) # if box score falls below threshold, discard the box by swapping with last box
# update N
if boxes[pos, 4] < threshold:
boxes[pos,0] = boxes[N-1, 0]
boxes[pos,1] = boxes[N-1, 1]
boxes[pos,2] = boxes[N-1, 2]
boxes[pos,3] = boxes[N-1, 3]
boxes[pos,4] = boxes[N-1, 4]
N = N - 1
pos = pos - 1 pos = pos + 1
keep = [i for i in range(N)]
return keep
boxes = np.array([[100, 100, 150, 168, 0.63],[166, 70, 312, 190, 0.55],[221, 250, 389, 500, 0.79],[12, 190, 300, 399, 0.9],[28, 130, 134, 302, 0.3]])
keep = soft_nms(boxes)
print(keep)
NMS 和 Soft-NMS的更多相关文章
- NMS技术总结(NMS原理、多类别NMS、NMS的缺陷、NMS的改进思路、各种NMS方法)
前言 本文介绍了NMS的应用场合.基本原理.多类别NMS方法和实践代码.NMS的缺陷和改进思路.介绍了改进NMS的几种常用方法.提供了其它不常用的方法的链接. 本文很早以前发过,有个读者评论说 ...
- 论文阅读笔记四十八:Bounding Box Regression with Uncertainty for Accurate Object Detection(CVPR2019)
论文原址:https://arxiv.org/pdf/1809.08545.pdf github:https://github.com/yihui-he/KL-Loss 摘要 大规模的目标检测数据集在 ...
- IoU与非极大值抑制(NMS)的理解与实现
1. IoU(区域交并比) 计算IoU的公式如下图,可以看到IoU是一个比值,即交并比. 在分子中,我们计算预测框和ground-truth之间的重叠区域: 分母是并集区域,或者更简单地说,是预测框和 ...
- 一分钟速学 | NMS, IOU 与 SoftMax
非极大抑制 NMS的英文是Non-maximum suppression的缩写. 简单的说,就是模型给出了多个重叠在一起的候选框,我们只需要保留一个就可以了.其他的重叠的候选框就删掉了,效果可见下图: ...
- NMS系列
NMS soft NMS softer NMS https://www.cnblogs.com/VincentLee/p/12579756.html
- ActiveMQ NMS使用过程中的一点经验
最近,项目中使用到了ActiveMQ获取第三方推送过来的数据.具体背景是:公司需要监控全国各地车辆实时运行的GPS数据,但监控本身不是公司做的,而是交给第三方公司做,第三方采集GPS数据后推送给我们. ...
- 非极大值抑制(Non-Maximum Suppression,NMS)
概述 非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索.这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二 ...
- 非极大值抑制(NMS)
转自:https://www.cnblogs.com/makefile/p/nms.html 概述 非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的 ...
- 非极大值抑制(NMS)的几种实现
因为之前对比了RoI pooling的几种实现,发现python.pytorch的自带工具函数速度确实很慢,所以这里再对Faster-RCNN中另一个速度瓶颈NMS做一个简单对比试验. 这里做了四组对 ...
随机推荐
- thinkphp 切换数据库
除了在预先定义数据库连接和实例化的时候指定数据库连接外,我们还可以在模型操作过程中动态的切换数据库,支持切换到相同和不同的数据库类型.用法很简单, 只需要调用Model类的db方法,用法: 常州大理石 ...
- js面试总结2
原型和原型链: 题目,知识点,解答: 1.如何准确地判断一个变量是数组类型 2.写一个原型链继承的例子 3.描述new一个对象的过程 4.zepto(或其他框架)源码中如何使用原型链. 知识点 构造函 ...
- csp-s模拟测试90
csp-s模拟测试90 考场发明$Spfa$祭. $T1$按照题意模拟,然后我就发现我死了.一气之下删掉了$priority$,拍了几下发现贼jb快而且还是对的就开心地交了.$T2$的差分状态定义很棒 ...
- day22_5-xml模块
# 参考资料:# python模块(转自Yuan先生) - 狂奔__蜗牛 - 博客园# https://www.cnblogs.com/guojintao/articles/9070485.html ...
- 「APIO 2019」桥梁
题目 三天终于把\(APIO\)做完了 这题还是比较厉害的,如果不知道这是个分块应该就自闭了 考虑一个非常妙的操作,按照操作分块 我们设一个闸值\(S\),把\(S\)个边权修改操作分成一块,把所有的 ...
- shell脚本练习06
######################################################################### # File Name: -.sh # Author ...
- python全栈开发:hashlib加密
哈希加密代码 #!/usr/bin/env python # -*- coding;utf-8 -*- """ 哈希加密模块中有很多算法,调用不同的算法执行不同的加密, ...
- apache日志配置一例,包括指定存储目录与格式、自动删除过期的日志文件
有需要的朋友可以参考下(http://www.nanke0834.com) 1.vim /usr/local/apache2/conf/extra/httpd-vhosts.conf 添加或修改为:复 ...
- 分享一个现代的,免费的,简单而有效的编辑器Vis
Vis是一个免费的开源,类似Vi的代码编辑器,它扩展了vi的模态编辑,内置支持使用相同编辑器的基于结构正则表达式的命令语言实现的多个游标/选择.并将其与基于sam结构正则表达式的命令语言相结合. Vi ...
- 拦截器和自定义注解@interface
1 .拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略. 拦截用户的请求并进行相应的处理,比如:判断用 ...