非极大值抑制算法 NMS

非极大值抑制NMS

对于目标检测等任务,由于在预测的时候生成了很多默认的候选框,再对这些候选框进行微调,因此导致对同一个物体可能有多个预测框。NMS正是为了解决这个问题而提出的算法。

算法原理

已知:对同一个类别的物体,有多个预测框,每个框都有一个置信度
目的:确定每个物体对应的框体,删除多余的框体
步骤:

  • i)将多个框体按照置信度排序
  • ii)选出置信度最大的框体,删除剩余框体与该框体IoU大于阈值的框体。(这一步确定了一个物体的框体,并删除了其他可能重复预测的框体)
  • iii)重复步骤ii,直至处理完所有框体

例子

先假设有6个输出的矩形框(即proposal_clip_box),根据分类器类别分类概率做排序,从小到大分别属于车辆的概率(scores)分别为A、B、C、D、E、F。
(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
就这样一直重复,找到所有被保留下来的矩形框。

算法实现

def nms(dets, thresh):
    """ 非极大值抑制算法 :param dets: ndarray, eg:[[x1,y1,x2,y2,score], [x1,y1,x2,y2,score], [x1,y1,x2,y2,score]...] :param thresh: int eg:0.7 :return: """
    # 计算每个框的面积
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]

    area = (x2-x1+1) * (y2-y1+1)

    # 按置信度排名
    score = dets[:, 4]
    order = score.argsort()[::-1]   # 从大到小排序

    # 要保留的框体
    keep = []

    # 取出置信度最大的框,删除其他框
    while order.size > 0:
        chosed = order[0]
        keep.append(chosed)
        # 计算和其他框的IoU

        # 计算交叉部分坐标
        inter_x1 = np.maximum(x1[chosed], x1[order[1:]])
        inter_y1 = np.maximum(y1[chosed], y1[order[1:]])
        inter_x2 = np.minimum(x2[chosed], x2[order[1:]])
        inter_y2 = np.minimum(y2[chosed], y2[order[1:]])

        # 交叉面积
        inter_area = (inter_x2-inter_x1+1) * (inter_y2 - inter_y1 + 1)

        # IoU
        IoU = inter_area / (area[chosed] + area[order[1:]] - inter_area)

        # 筛选IoU小于阈值的框体
        left = np.where(IoU < thresh)[0]

        order = order[left + 1] # left 中编号比order中小了1

    return keep
全部评论

相关推荐

04-08 23:14
已编辑
南阳理工学院 算法工程师
本人情况:26届双非本科,两段实习经历,目前拿到的都是实习的offer,一个校招的都没有,他们都说先实习,然后等拿到毕业证了直接转正,我又害怕干三个月给我叉出去面试题也发一下吧###&nbsp;杭州问尔信息技术后端登录你是怎么做的?JWT令牌你了解过吗?他虽然是一段字符串,他表达了什么东西?怎么解析出来信息和过期时间?JWT令牌怎么续期?如果我拉黑一个账号,要怎么做?两种方案(有无redis)mongodb和mysql的区别?mongodb和mysql分别实用于什么项目?选型你会怎么选?数据库的事务,那些地方需要使用,那些地方不需要使用?他会影响什么性能?mysql和pgsql有什么差异你知道吗?消息队列&nbsp;redis也有,为什么要用mq?前后端会部署吗?docker会用吗?内部通信前端&nbsp;async和&nbsp;await你知道吗?异步编程的原理是什么?vue3&nbsp;为什么你改变一个字符串&nbsp;前端会跟着改动AI工具会用什么?你会怎么用?###&nbsp;仲财通常用的锁有哪些synchronize和ReentrantLock的区别分布式锁了解吗?分布式事务mysql表字段sql优化什么时候用索引索引什么时候会失效mysql事务ioc一些项目应用问题###&nbsp;观妙科技项目问题...zset的架构是什么样子的线程池突然队列被打满了怎么办?如果上游和下游都无法控制,该怎么维护select&nbsp;*&nbsp;from&nbsp;user&nbsp;where&nbsp;age&gt;20&nbsp;order&nbsp;by&nbsp;update_time&nbsp;索引设计检索过程是什么样的冒泡排序和快排,有什么区别怎么判断链表有没有环###&nbsp;观妙科技-二面项目部分...线程池的核心参数有哪些你是怎么用线程池的JMMG1模型跳表介绍一下平衡二叉树TCP为什么要三次握手?说一下hashmap红黑树的特征你有什么学习的方法
牛马人的牛马人生:对学院本而言很强了
点赞 评论 收藏
分享
牛客100866号技...:把电科加粗,把电科加粗,把电科加粗,两个吊车尾的项目合并成一个,再加一个管理系统。电科✌🏻在成都面中厂手拿把掐
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务