作者:云时之间
来源:知乎
链接:https://zhuanlan.zhihu.com/p/152319787
编辑:王萌
非极大值抑制算法(Non-maximum suppression, NMS)是有anchor系列目标检测的标配,NMS主要用于消除多余的检测框,那么消除的标准是什么,我们使用IOU作为标准来进行演示,IOU的原称为Intersection over Union,也就是两个box区域的交集比上并集。
大致流程:
-
选取这类box中scores最大的那一个,记为current_box,并保留它(为什么保留它,因为它预测出当前位置有物体的概率最大啊,对于我们来说当前confidence越大说明当前box中包含物体的可能行就越大)
-
计算current_box与其余的box的IOU
-
如果其IOU大于我们设定的阈值,那么就舍弃这些boxes(由于可能这两个box表示同一目标,因此这两个box的IOU就比较大,会超过我们设定的阈值,所以就保留分数高的那一个)
- 从最后剩余的boxes中,再找出最大scores的那一个(之前那个大的已经保存到输出的数组中,这个是从剩下的里面再挑一个最大的),如此循环往复
代码实现:
#使用IOU(交互比),来判断预测的边框和真实的边框的交集
def iou_of(boxes0, boxes1, eps=1e-5):
overlap_left_top = np.maximum(boxes0[..., :2], boxes1[..., :2])
overlap_right_bottom = np.minimum(boxes0[..., 2:], boxes1[..., 2:])
overlap_area = area_of(overlap_left_top, overlap_right_bottom)
area0 = area_of(boxes0[..., :2], boxes0[..., 2:])
area1 = area_of(boxes1[..., :2], boxes1[..., 2:])
return overlap_area / (area0 + area1 - overlap_area + eps)
#非极大值抑制算法,最后一层网络,搜索局部极大值,抑制非极大值元素
#消除多余的检测框,从左到右消除了重复的检测框,只保留当前最大confidence的检测框
'''
Args:
box_scores:box检测框的集合,-1表示全保留
iou_threshold :IOU标准获得去除多余检测框
top_k=-1:保留所有的计算后的候选框
candidate_size=200:参与计算的box数量
'''
def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200):
scores = box_scores[:, -1] #box中的最后一个元素也就是当前box检测到物体的概率
boxes = box_scores[:, :-1]#取出左上,右下坐标
picked = []
# _, indexes = scores.sort(descending=True)
#将成绩从小到大排序,得到索引信息
indexes = np.argsort(scores)
# indexes = indexes[:candidate_size]
indexes = indexes[-candidate_size:]
#只保留condidate_size个boxes
while len(indexes) > 0:
# current = indexes[0]
current = indexes[-1]#取出box最大的概率
picked.append(current)
if 0 < top_k == len(picked) or len(indexes) == 1:
break
current_box = boxes[current, :]
# indexes = indexes[1:]
indexes = indexes[:-1]
rest_boxes = boxes[indexes, :]#剩下的BOXIOU标准
iou = iou_of(rest_boxes, np.expand_dims(current_box, axis=0))
indexes = indexes[iou <= iou_threshold]#保留小于一定阈值的boxes
return box_scores[picked, :]
参考文章:
https://blog.csdn.net/qq_36338754/article/details/92794397