【深度学习】——非极大值抑制(nms/soft-nms)

目录

一、相关概念

1、iou

1)理论计算

2)Python代码(代码参考yolov3模型util.py文件)

2、nms

1)基本思路

2)标准nms和soft-nms

3)Python代码实现(yolov3中util.py文件,增加了注释)

4)标准nms的缺点


一、相关概念

1、iou

1)理论计算

参考:https://blog.csdn.net/zouxiaolv/article/details/107400193

                        

物体检测需要定位出物体的bounding box,就像上面的图片一样,我们不仅要定位出车辆的bounding box 我们还要识别出bounding box 里面的物体就是车辆。

对于bounding box的定位精度,有一个很重要的概念,那就是定位精度评价公式:IOU。

IOU表示了bounding box 与 ground truth 的重叠度,如下图所示:

这里写图片描述

矩形框A、B的一个重合度IOU计算公式为:

                                                                 IOU=Area(A∩B)/Area(A∪B)

就是矩形框A、B的重叠面积占A、B并集的面积比例:

                                                                 IOU=SI/(SA+SB-SI)

如何计算IOU(交并比)

                                

首先求出重合面积:

     选取两个矩形框左顶角的横,纵坐标的最大值,x21,y21;选取两个矩形框右下边角的横纵坐标的最小值,x12,y12;

重合面积计算:

                             inter=    | x12-x21 *| y12-y21 |

并集的面积计算:

                               b = | x12-x21  |*| y12-y21 |+ | x21-x22 || y21-y22  | - inter

计算IOU:

                                   IOU=inter/b

2)Python代码(代码参考yolov3模型util.py文件)

def bboxes_iou(boxes1, boxes2):
    '''
    两个都是数组,注意两个box的维度必须一致,一般是二维
    box:[[xmin,ymin,xmax,ymax],
          [xmin,ymin,xmax,ymax],
          ...]
    '''
    boxes1 = np.array(boxes1)# (1,4)
    boxes2 = np.array(boxes2) # (n,4)

    # 计算两个box的面积
    boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * (boxes1[..., 3] - boxes1[..., 1]) # (1,1)
    boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1]) # (n,1)

    left_up       = np.maximum(boxes1[..., :2], boxes2[..., :2])
    right_down    = np.minimum(boxes1[..., 2:], boxes2[..., 2:])

    inter_section = np.maximum(right_down - left_up, 0.0)
    inter_area    = inter_section[..., 0] * inter_section[..., 1] # 重叠区域
    union_area    = boxes1_area + boxes2_area - inter_area # 全部面积
    ious          = np.maximum(1.0 * inter_area / union_area, np.finfo(np.float32).eps) # ious

    return ious

2、nms

非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素,用于目标检测中,就是提取置信度高的目标检测框,而抑制置信度低的误检框。一般来说,用在当解析模型输出到目标框时,目标框会非常多,具体数量由anchor数量决定,其中有很多重复的框定位到同一个目标,nms用来去除这些重复的框,获得真正的目标框。如下图所示,人、马、车上有很多框,通过nms,得到唯一的检测框。

1)基本思路

所谓非极大值抑制:先假设有6个矩形框,根据分类器类别分类概率做排序,从小到大分别属于车辆的概率分别为A<B<C<D<E<F。

(1) 从最大概率矩形框F开始,分别判断A、B、C、D、E与F的重叠度IOU是否大于某个设定的阈值;

(2) 假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。

(3) 从剩下的矩形框A、C、E中,选择概率最大的E,然后判断A、C与E的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。

(4) 重复这个过程,找到所有被保留下来的矩形框。

2)标准nms和soft-nms

参考:https://zhuanlan.zhihu.com/p/89426063

bi为待处理BBox框,B为待处理BBox框集合,sibi框更新得分,Nt是NMS的阈值,D集合用来放最终的BBox,f是置信度得分的重置函数。 bi和M的IOU越大,bi的得分si就下降的越厉害。

经典的NMS算法将IOU大于阈值的窗口的得分全部置为0,可表述如下:

这种是加权线性的

具体其他的可以参考:https://zhuanlan.zhihu.com/p/89426063

3)Python代码实现(yolov3中util.py文件,增加了注释)

def nms(bboxes, iou_threshold, sigma=0.3, method='nms'):
    """
    :param bboxes: (xmin, ymin, xmax, ymax, score, class),是一个数组,关于(n,6),n是检测出的box个数

    Note: soft-nms, https://arxiv.org/pdf/1704.04503.pdf
          https://github.com/bharatsingh430/soft-nms
    """
    classes_in_img = list(set(bboxes[:, 5])) # 得到不同类别标签的列表,如[0,1,2],标签号
    best_bboxes = [] # 存放最好的box

    for cls in classes_in_img: # 遍历类别号列表
        cls_mask = (bboxes[:, 5] == cls) # 这里返回的是一个True or False的掩模列表,True则表示bboxes中对应索引号的box是属于这个类
        cls_bboxes = bboxes[cls_mask] # 根据掩模获得属于那一类的box,依旧是二维数组

        while len(cls_bboxes) > 0: # 这里一直在循环,直到box列表为空
            max_ind = np.argmax(cls_bboxes[:, 4]) # 获得这类得分最高的box索引
            best_bbox = cls_bboxes[max_ind] # 将分数最高的box作为最佳box
            best_bboxes.append(best_bbox) # 添加
            # 从box列表中去除最佳box
            cls_bboxes = np.concatenate([cls_bboxes[: max_ind], cls_bboxes[max_ind + 1:]])
            # 计算得到两个box之间的iou(重叠部分除以一起共同的面积),下面这里其实进行了批量操作,将最佳box和剩下的box进行了计算
            # np.newaxies,表示增加一个维度
            iou = bboxes_iou(best_bbox[np.newaxis, :4], cls_bboxes[:, :4])
            weight = np.ones((len(iou),), dtype=np.float32)  # 置信度,当iou大于0.7,说明重叠的部分很大,可以视为一个框,故丢弃

            assert method in ['nms', 'soft-nms']

            if method == 'nms': # 标准nms
                iou_mask = (iou > iou_threshold) # 得到一个掩模,iou大于设定阈值的设置为TRUE
                weight[iou_mask] = 0.0 #大于阈值的box的置信度置为0

            if method == 'soft-nms': # soft-nms,不直接丢弃大于阈值的box
                weight = np.exp(-(1.0 * iou ** 2 / sigma)) # sigma为惩罚因子,这个越小,置信度越小,越容易被抛弃

            cls_bboxes[:, 4] = cls_bboxes[:, 4] * weight # 这里是将剩下的box的得分乘以了iou置信度,与bestbox重叠的丢弃了
            score_mask = cls_bboxes[:, 4] > 0. # 取大于0的也就是丢弃了重叠的,这也是掩模
            cls_bboxes = cls_bboxes[score_mask] # 根据掩模跟新剩下的box,进行下一轮的nms

    return best_bboxes

4)标准nms的缺点

1、NMS算法中的最大问题就是它将相邻检测框的分数均强制归零(即将重叠部分大于重叠阈值Nt的检测框移除)。在这种情况下,如果一个真实物体在重叠区域出现,则将导致对该物体的检测失败并降低了算法的平均检测率。

2、NMS的阈值也不太容易确定,设置过小会出现误删,设置过高又容易增大误检。

3、NMS一般只能使用CPU计算,无法使用GPU计算。

 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有情怀的机械男

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值