• NMS 系列


    NMS

    解决问题:多个建议框指向了同一个物体,我们只需要该物体IoU最大的建议框

    基本思路:多个类别分开处理;每个列别中 iou 较大的删除,iou 较小的 保留

    具体操作

    1. 输入为2000x20矩阵,2000代表2000个建议框,20代表20个类别

    2. 对每个类别进行排序,从大到小

    3. 首先取得分最高的建议框,设为物体1,然后遍历后面所有的建议框,如果建议框和物体1的建议框IoU大于阈值,则认为是一个物体,把这些建议框删除,

    如果小于阈值,则认为是另一个物体,暂时保留,保留下来的建议框仍然是有序的

    4. 去掉该列被认定的建议框,如物体1,将剩下的建议框进行步骤3操作,直到认定完所有物体

    5. 对每列进行上述操作

    如上图F与BD重合度较大,可以去除BD。AE重合度较大,我们删除A,保留scores较大的E。C和其他重叠都小保留C。最终留下了C、E、F三个 

    存在问题

    1.如果 IOU 大于阈值,直接删除,忽略了 该 bbox 的 score,试想 如果 score 很高,很可能存在一个物体的,但被删除了,这对于密集物体十分不友好;

    2.阈值 不太好确定

    NMS 下 绿框 会被删除 

    demo

    针对 单类别

    # coding:utf-8
    import numpy as np
    def py_cpu_nms(dets, thresh):
        """Pure Python NMS baseline."""
        # 所有图片的坐标信息,字典形式储存??
        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]  # i 是还未处理的图片中的最大评分
            keep.append(i)  # 保留改图片的值
            # 矩阵操作,下面计算的是图片i分别与其余图片相交的矩形的坐标
            tmp=x1[order[1:]]
            xxxx = x1[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
            # 计算重叠比例
            ovr = inter / (areas[i] + areas[order[1:]] - inter)
    
            # 只保留比例小于阙值的图片,然后继续处理
            inds = np.where(ovr <= thresh)[0]
            indsd= inds+1
            order = order[inds + 1]
    
        return keep
    boxes = np.array([[100, 100, 150, 168, 0.63],[166, 70, 312, 190, 0.55],[221, 250, 389, 500, 0.79],[12, 190, 300, 399, 0.9],[28, 130, 134, 302, 0.3]])
    thresh = 0.1
    keep = py_cpu_nms(boxes, thresh)
    print(keep)

    soft-NMS

    soft-nms 优化点在于:并非暴力删除 iou 较大的 框,而是 降低 这个框的 score

    存在问题

    阈值仍需手工设定

    优势

    1、Soft-NMS可以很方便地引入到object detection算法中,不需要重新训练原有的模型、代码容易实现,不增加计算量(计算量相比整个object detection算法可忽略)。并且很容易集成到目前所有使用NMS的目标检测算法。

    2、soft-NMS在训练中采用传统的NMS方法,仅在推断代码中实现soft-NMS

    3、NMS是Soft-NMS特殊形式,当得分重置函数采用二值化函数时,Soft-NMS和NMS是相同的。soft-NMS算法是一种更加通用的非最大抑制算法。

    demo

    def my_soft_nms(bboxes, scores, iou_thresh=0.5, sigma=0.5, score_threshold=0.25):
    
        bboxes = bboxes.contiguous()
    
        x1 = bboxes[:, 0]
        y1 = bboxes[:, 1]
        x2 = bboxes[:, 2]
        y2 = bboxes[:, 3]
        areas = (x2 - x1 + 1) * (y2 - y1 + 1)
        order = scores.sort(0, descending=True)
        keep = []
    
        while order.numel() > 0:
            if order.numel() == 1: 
                i = order.item()
                break
            else:
                i = order[0].item()
                keep.append(i)
            xx1 = x1[order[1:]].clamp(min=x1[i])
            yy1 = y1[order[1:]].clamp(min=y1[i])
            xx2 = x2[order[1:]].clamp(max=x2[i])
            yy2 = y2[order[1:]].clamp(max=y2[i])
            inter = (xx2 - xx1).clamp(min=0) * (yy2 - yy1).clamp(min=0)
    
            idx = (iou > iou_thresh).nonzero().squeeze()  
            if idx.numel() > 0:
                iou = iou[idx]
                newScores = torch.exp(-torch.pow(iou, 2) / sigma)  
                scores[order[idx + 1]] *= newScores  
    
            newOrder = (scores[order[1:]] > score_threshold).nonzero().squeeze()
            if newOrder.numel() == 0:
                break
            else:
                maxScoreIndex = torch.argmax(newScores)
    
                if maxScoreIndex != 0:
                   newOrder[[0, maxScoreIndex],] = newOrder[[maxScoreIndex, 0],]
    
                order = order[newOrder + 1]
    
        return torch.LongTensor(keep)

    有人在多个数据集上做了大量实验,针对不同的数据集效果不同,有轻微的提升作用。

    softer-NMS

    未完待续...

    参考资料:

    https://mp.weixin.qq.com/s?__biz=MzUyODY5ODg5NQ==&mid=2247483782&idx=1&sn=bae1d8b8c56c2e5fe82886ca2f418f9e&chksm=fa6d1ae6cd1a93f0adaa3cae6458e238d32e6d5436b0e3b70e35cd0881b56403f99be48d0443&scene=132#wechat_redirect  YOLOv5改进之八:非极大值抑制NMS算法改进Soft-nms

    https://zhuanlan.zhihu.com/p/42018282  NMS与soft NMS

    https://zhuanlan.zhihu.com/p/89426063  NMS、 soft-nms、softer-nms

  • 相关阅读:
    LoadRunne遇到的一些问题FAQ(持续更新...)
    LoadRunner11下载、安装与破解
    LoadRunner之录制你的第一个脚本
    appium+Linux环境安装配置
    appium-FAQ(持续更新...)
    appium启动运行log分析
    利用Unity3D与Oculus实现机器情绪安抚师的一种方案
    利用Unity3D实现多平台增强现实网络游戏的一种方案
    Ubuntu16.04安装NVIDIA驱动时的一些坑与解决方案
    你的计算机也可以看懂世界——十分钟跑起卷积神经网络(Windows+CPU)
  • 原文地址:https://www.cnblogs.com/yanshw/p/16575643.html
Copyright © 2020-2023  润新知