NMS,全称为Non-maximum suppression,非极大值抑制,是一种去除非极大值的算法,常用于计算机视觉中的边缘检测、目标检测等。其作用是去掉detection任务中重复的检测框。
算法流程
给出一张图片和其上面许多物体检测的候选框(即每个框可能代表某种物体),但是这些框很可能有相互重叠的部分,我们要做的就是只留下最优的框。假设有N个框,每个框被分类器计算得到的分数为Si,i∈[1,N]。
a、建造一个存放待处理候选框的集合H,初始化为包含全部N个框;建造一个存放最优框的集合M,初始化为空集。
b、将所有集合H中的框进行排序,选出分数最高的框m,从集合H移到集合M;
c、遍历集合H中的框,分别与框m计算交并比(Interection-over-union,IOU),如果高于某个阈值(一般为0~0.5),则认为此框与m重叠,将此框从集合H中去除;
d、回到b步骤进行迭代,直到集合H为空,集合M中的框为我们所需。
需要优化的参数:
IoU的阈值是一个可优化的参数,一般范围为0~0.5,可以使用交叉验证来选择最优的参数。
示例:
比如人脸识别的一个例子:
已经识别出了5个候选框,但是我们只需要最后保留两个人脸。
首选选出分数最大的框(0.98),然后遍历剩余框,计算IoU,会发现露丝脸上的两个绿框都和0.98的框重叠率很大,都要去除。
然后对杰克脸上的两个框,选出最大框(0.81),遍历剩余框(就有一个0.67的框),发现0.67这个框与0.81的IoU也很大,去除。
最后得到结果:
代码:
下面是Fast RCNN关于NMS的源代码(python版)
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
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]
keep.append(i)
keep.append(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]
order = order[inds + 1]
return keep