NMS—非极大值抑制算法的理解
一、概念
在目标检测中,得到多个候选框及其置信度得分。非极大值抑制算法(NMS)对多个候选框,去除重合率大的冗余候选框,得到最具代表性的结果,以加快目标检测的效率。
二、实例
以下图人脸检测为例,目标:消除重合率大且多余的候选框,保留某个区域的一个最优的候选框。
非极大值抑制算法(NMS)抑制冗余的框, 抑制的过程是一个迭代-遍历-消除的过程。
1)将所有框的得分排序,选中最高分及其对应的框
a) 假设图中有A:0.75、B:0.98 、C:0.83、D:0.67、E:0.81
b) 将置信度升序排序为D:0.67、A:0.75、E:0.81、C:0.83、B:0.98
c) 选中得分最高的B:0.98
2)遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。
a)由B:0.98对其余A、C、D、E框计算IOU,B与A、C的IOU>阈值,删除A、C框。
b)第一轮得到B:0.98、D:0.67、E:0.81
3) 从未处理的D、E框中继续选一个得分最高的,重复上述过程。
a) 删除D框,保留E
b) 最后保留B、E框
三、Python代码
#候选框boxes为5列,分别是[x1 y1 x2 y2 score],score为置信度得分
#threshold: IOU阈值
def py_nms(dets, thresh):
#取出候选框左上角和右下角坐标以及置信度得分
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)
#计算当前置信度最大矩形框与其他矩形框的重叠面积
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
#计算IOU
ovr = inter / (areas[i] + areas[order[1:]] - inter)
#保留所有重叠面积小于阈值的框
inds = np.where(ovr <= threshold)[0]
order = order[inds + 1]