非极大值抑制在物体检测方面的应用
结合faster-rcnn给出的py_cpu_nms.py的源码来介绍一下nms算法在物体检测方面的应用。faster-rcnn中经过rpn层之后会得到一些boundingbox和boundingbox对应的属于某一类的分数(置信度)。所以可以根据NMS来去除那些overlap值比较大的box。
import numpy as np
def py_cpu_nms(dets, thresh):
"""Pure Python NMS baseline."""
#dets:N*M,N是bbox的个数,M的前4位是对应的(x1,y1,x2,y2),第5位是对应的分数
#thresh:0.3,0.5....
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
scores = dets[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)#求每个bbox的面积
order = scores.argsort()[::-1]#对分数进行倒排序
keep = []#用来保存最后留下来的bbox
while order.size > 0:
i = order[0]#无条件保留每次迭代中置信度最高的bbox
keep.append(i)
#计算置信度最高的bbox和其他剩下bbox之间的交叉区域
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:]])
#计算置信度高的bbox和其他剩下bbox之间交叉区域的面积
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
inter = w * h
#求交叉区域的面积占两者(置信度高的bbox和其他bbox)面积和的必烈
ovr = inter / (areas[i] + areas[order[1:]] - inter)
#保留ovr小于thresh的bbox,进入下一次迭代。
inds = np.where(ovr <= thresh)[0]
#因为ovr中的索引不包括order[0]所以要向后移动一位
order = order[inds + 1]
return keep
下面解释下利用NMS进行过滤区域的原理。当一个窗口区域被认为是最有可能表示某一个物体的时候,那么和这个窗口区域交叉面积大的proposal就可以认为不是需要的窗口区域。
以上为个人对NMS在物体检测方面的一些理解,如果有什么不对的地方,希望指出。另为给出一个个人觉得对NMS解释比较好的连接。http://www.cnblogs.com/liekkas0626/p/5219244.html