CV学习笔记(二十六):NMS非极大值抑制算法

作者:云时之间
来源:知乎
链接: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

上一篇:简单说说模拟退火


下一篇:2bc-gskew:De-aliased hybrid branch predictors(1999)