前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >目标检测算法基础概念:边框回归和NMS

目标检测算法基础概念:边框回归和NMS

作者头像
深度学习技术前沿公众号博主
发布2020-06-10 16:43:23
1.3K0
发布2020-06-10 16:43:23
举报
文章被收录于专栏:深度学习技术前沿

【导读】前面我们详细介绍了目标检测领域常用的一些评价指标。本文我们来讨论一下在目标检测算法中必须掌握的两个基本概念:边框回归和NMS(非极大值抑制)。

边框回归的背景

如下图所示:

对于上图,绿色的框表示Ground Truth, 红色的框为Selective Search提取的Region Proposal。那么即便红色的框被分类器识别为飞机,但是由于红色的框定位不准(IoU<0.5), 那么这张图相当于没有正确的检测出飞机。如果我们能对红色的框进行微调, 使得经过微调后的窗口跟Ground Truth 更接近, 这样岂不是定位会更准确。确实,Bounding-box regression 就是用来微调这个窗口的。

边框回归的含义

对于窗口一般使用四维向量(x,y,w,h)来表示, 分别表示窗口的中心点坐标和宽高。边框回归的目的就是:在给定一组候选目标框 ,寻找到一个

映射 ,使得 。边界框回归过程图像表示如下图所示。在图2中红色框代表候选目标框,绿色框代表真实目标框,蓝色框代表边界框回归算法预测目标框,红色圆圈代表选候选目标框的中心点,绿色圆圈代表选真实目标框的中心点,蓝色圆圈代表选边界框回归算法预测目标框的中心点。

边界框回归中的变换

RCNN论文里指出,边界框回归是利用平移变换和尺度变换来实现映射 。平移变换的计算公式如下:

尺度变换的计算公式如下:

宽高尺度设计

由于CNN具有尺度不变性,以下图为例:

我们想要得到一个放缩的尺度,也就是说这里限制尺度必须大于0。我们学习的tw,th怎么保证满足大于0呢?直观的想法就是EXP函数,如公式(2)所示,那么反过来推导就是Log函数的来源了。

为什么IoU较大时边界框回归可视为线性变换?

在这里我们需要回顾下在高等数学中有关等价无穷小的结论:

NMS的定义

NMS(Non-maximum suppression),即非极大值抑制,在目标检测中的出镜率也很高呀。在目标检测中,不论是最初的region proposal,还是后来的anchor box,不可避免的一个问题就是对于同一个物体,会预测出多个bounding box,如下左图所示。而NMS所做的就是去除掉多余的bounding box,只保留和ground truth重叠度最高的bounding box,如下右图所示。

在目标检测中,分类器会给每个bounding box(bbox)计算出一个class score,就是这个bbox属于每一类的概率,NMS就是根据这些值来进行的,主要流程:

  • 对于每一类,首先把所有score<threshold的bbox的score设为0
  • 之后,将所有的bbox按照得分排序,选中最高分及其对应的bbox
  • 遍历其余的bbox,如果和当前最高分bb的重叠面积(IoU)大于一定的阀值,便将该bbox删除
  • 从未处理的bbox中继续选择一个最高分的bb,重复上述过程
  • 重复上述过程,直到找到全部保留的bbox
  • 然后根据所有保留bbox的class score和class color画出最后的预测结果

NMS的实现(Pytorch代码)

代码语言:javascript
复制
from __future__ import absolute_import

import numpy as np
import torch

def nms(dets, thresh):
    dets = dets.numpy()
    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.item(0)
        keep.append(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]
        order = order[inds + 1]

    return torch.IntTensor(keep)

参考链接:

1. https://blog.csdn.net/zijin0802034/article/details/77685438

2. https://zhuanlan.zhihu.com/p/76603583

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深度学习技术前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像识别
腾讯云图像识别基于深度学习等人工智能技术,提供车辆,物体及场景等检测和识别服务, 已上线产品子功能包含车辆识别,商品识别,宠物识别,文件封识别等,更多功能接口敬请期待。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档