目标检测是计算机视觉领域中非常重要的一个研究方向,它是将图像或者视频中目标与其他不感兴趣的部分进行区分,判断是否存在目标,确定目标位置,识别目标种类的任务,即定位+分类。传统的目标检测模型有VJ.Det[1,2],HOG.Det[3],DPM[4,5,6],直到2012年,CNN模型日益成熟化,以深度学习为基础的目标检测模型开始发展,主要分为单阶段模型(One stage)和两阶段模型(Two stage),发展路径如下:

目标检测定义 目标检测有哪些_目标检测定义

目标检测也面临许多挑战:

  • 环境影响
  • 密集
  • 遮挡
  • 重叠
  • 多尺度:大目标、小目标
  • 小样本
  • 旋转框

目标检测也细分了很多领域

  • 通用检测:
  • 行人检测:行人违规检测
  • 车辆检测:车辆违规检测、车辆牌照识别等
  • 人脸检测:人脸口罩检测,人脸识别打卡等
  • 文字检测:OCR(光学字符识别)的文本检测,常见算法:DBNet

1、常见术语介绍

(1)BBox(边界框)

BBox:Bounding Box,边界框,边界框分为两种:Groud-truth(真实框,也简称gt_box)和prediction box(预测框,也简称pred_box),使用边界框(bounding box)来表示物体的位置,边界框是正好能包含物体的矩形框,通常有两个格式

  • (x1,y1,x2,y2)

        (x1,y1)是矩形框的左上角的坐标,(x2,y2)是矩形框的右上角的坐标。

  •  (x ,y ,w ,h )

          (x,y)是矩形框中心点的坐标,w ww是矩形框的宽度,h hh是矩形框的高度。

(2)Anchor(锚框)

锚框与物体边界框不同,是由人们假想出来的一种框。先设定好锚框的大小和形状,再以图像上某一个点为中心画出矩形框, 将这些锚框当成可能的候选区域。

(3)RoI(Region of Interest):特定的感兴趣区域

(4)Region Proposal :候选区域

(5)RPN(Pegion Proposal Network):区域生成网络,用于生成候选区域的网络。

(6)IoU(Intersaction over Union)

在检测任务中,使用交并比(Intersection of Union,IoU)作为衡量指标。这一概念来源于数学中的集合,用来描述两个集合A AA和B BB之间的关系,它等于两个集合的交集里面所包含的元素个数,除以它们的并集里面所包含的元素个数,具体计算公式如下:

我们将用这个概念来描述两个框之间的重合度。两个框可以看成是两个像素的集合,它们的交并比等于两个框重合部分的面积除以它们合并起来的面积。

目标检测定义 目标检测有哪些_目标检测_02

(7)mAP

AP(Average Precision)是某一类以Precision、Recall为纵、横坐标的曲线下的面积,mAP(mean Average Precision)是所有类别AP平均。

(8)NMS

搜索局部最大值,抑制极大值。

2、深度学习的目标检测方案

在Ross Girshick等人提出DPM方法后,目标检测进入瓶颈期,图像特征提取成为难点,随着CNN的发展,也开始尝试将神经网络加入到目标检测任务中。该图是几个模型的差异对比:

目标检测定义 目标检测有哪些_数据集_03

 (1)R-CNN

R-CNN的全称是Region-CNN,是第一个成功将深度学习应用到目标检测中的算法,传统的目标检测方法是在图片上穷举出所有物体可能出现的区域框,对这些区域提取特征并进行分类,得到所有分类成功的区域,通过非极大值抑制(Non-maximum suppression)输出结果。R-CNN的实现步骤是

  • 采用提取框(Selective Search):搜索候选区域,并对候选区域提取特征,并将提取到的特征存储起来。
  • 对每个框提取特征(CNN):在数据集上训练CNN,R-CNN论文中使用的网络是AlexNet,数据集是ImageNet,在目标检测的数据集上,对训练好的CNN做微调。
  • 图像分类(SVM):使用分类模型SVM进行训练
  • 边框回归:通过非最大抑制策略对同一类别的ROI(region of interest)进行合并得到最终的检测结果,即得到每个矩形框的置信度。

不足:

  • 每个候选区域都需要通过CNN计算特征,计算量大
  • Selective Search提取的区域质量不够好
  • 特征提取、SVM分类器是分模块独立训练的,没有联合起来系统性优化,训练耗时长

(2)Fast R-CNN

在改进Fast R-CNN之前,有一个版本是SPPNet(Spatial Pyramind Pooling Convolutional 

Networks),将CNN的输入从固定尺寸改进为任意尺寸,加入ROI池化层(即对ROI的区域进行池化),使得网络的输入图像可以是任意尺寸,输出则不变,是固定维数的向量。

Fast R-CNN在SPPNet的基础上,将 SVM分类改成了神经网络进行分类,全连接层有两个输出,一个输出负责分类(softmax),另一个输出负责框回归(bbox regressor)。

最终得到两个结果:softmax分类以及L2回归,损失函数是分类和回归的加权和。

不足:

  • 仍用Selective Search提取候选区域

ROI Pooling的不足:

  • 在候选框的位置和提取特征时两次取整,会导致检测信息和提取出的特征不匹配

(3)Faster R-CNN

为了解决Selective Search带来的耗时问题,Faster R-CNN引用了RPN来进行候选区域的提取,RPN是一个全卷积神经网络(Fully Convolutional Network),输入是前一层任意大小的特征图,输出是一系列的矩形目标候选区,在卷积神经网络的最后一个特征层上滑动。

目标检测定义 目标检测有哪些_计算机视觉_04

 为了适应多种形状的物体,RPN定义了k种不同尺度的滑窗,并将这些滑窗成为anchor,在Faster R-CNN论文中,用了9种anchor。

在分类任务中,需计算每个anchor和真实标记矩形框gt_box的IOU

  • 当IOU>0.7时,认为该anchor包含目标物体,为正样本
  • 当IOU在0.3-0.7之间时,不参与网络训练的迭代过程
  • 当IOU<0.3时,认为该anchor不包含目标物体,为负样本

在回归任务中,需计算anchor和gt_box的横、纵坐标及宽高的偏移量,Loss函数的是通过smooth L1进行计算的,公式为

目标检测定义 目标检测有哪些_目标检测_05

ROI Align:消除ROI Padding的误差

 在区域内均匀的取N个点,找到特征图上离每个点最近的四个点,再通过双线性插值的方式,得到点的输出值,最后对N个点取平均得到区域的输出。

(4)进阶模型

  • FPN(解决多尺度问题)

方案可以构造多尺度金字塔,期望模型能够具备检测不同大小尺度物体的能力,具体方案如下图:

  • a是将特征缩放到不同尺度,使用多个模型进行预测
  • b是仅使用最后一层的特征作为检测模型后续部分的输入
  • c是每个层级分别预测
  • d是使用不同层级特征进行融合,在分级预测(FPN)

目标检测定义 目标检测有哪些_目标检测_06

FPN是以骨干网络的输出为输入,将特征进行上采样并与上一层特征相加得到FPN结构每一层的输出,网络结构图如下

目标检测定义 目标检测有哪些_深度学习_07

在FPN结构中,会存在多个ROI Align,将FPN的特征金字塔类比为图像金字塔,可以通过面积来对候选框进行分配。

目标检测定义 目标检测有哪些_目标检测定义_08

  • Cascade R-CNN(IoU)

Cascade R-CNN主要是对IoU指标的改进,IoU是计算两个框之间的重叠区域,在模型中涉及到的细节有:一、计算基于Anchor和GT框的IoU值,二是基于预测框和真实框的IoU值。通过调整IoU的阈值并未对模型有较大提升,单一阈值训练的模型有限,因此,对模型进行多Head改进。

  • Libra R-CNN

Libra R-CNN进行三方面的改进,分别是特征融合、采样策略、损失函数。

目标检测定义 目标检测有哪些_数据集_09

 增强FPN的特征融合:

  1. Rescale(重新调节):将不同层级的特征图(C层)通过差值或者下采样的方法进行统一到C4层
  2. Integrate(合并):将汇集的特征进行融合
  3. refine(重新定义):使用non-local结构对融合特征进行加强
  4. strengthen(增强):将优化的特征与不同层级上的原始特征加和

采样策略:

  1. 正样本采样(正样本类别不平衡):对正样本里边的类别进行随机采样,保证类别均衡
  2. 负样本采样(负样本IoU分配不平衡):根据阈值划分,高于阈值的进行分桶,计算应该落在每个桶中的样本数量,最后得到IoU均匀分布的负样本;低于阈值的样本随机采样

Loss(Smooth L1 loss--->Balanced L1 loss):

目标检测定义 目标检测有哪些_数据集_10

还有Mask R-CNN、RFCN、Light-Head R-CNN等模型的改进

3、深度学习的目标检测实现

3.1. PaddleDetection的安装和使用

(1)安装

#下载PaddleDetection
! git clone https://github.com/PaddlePaddle/PaddleDetection
#解压
! unzip -o PaddleDetection.zip
#安装cocoapi
! pip install "git+https://hub.fastgit.org/cocodataset/cocoapi.git#subdirectory=PythonAPI"
#安装需求包,在PaddleDetection路径下
!pip install -r requirements.txt

#配置环境变量
%env PYTHONPATH=.:$PYTHONPATH
%env CUDA_VISIBLE_DEVICES=0

#验证
! python ppdet/modeling/tests/test_architectures.py

目标检测定义 目标检测有哪些_深度学习_11

(2)介绍

在PaddleDetection中实现目标检测、关键点检测、实例分割等算法,具体模型如下:

目标检测定义 目标检测有哪些_目标检测定义_12

 (3)模型包内容拆解

目标检测定义 目标检测有哪些_目标检测_13

核心文件有四个configs、dataset、demo、tools, 包含了数据集、测试、模型、训练整个过程,可以按需调整实现。

教程参考:飞桨AI Studio - 人工智能学习与实训社区

(4)实现

#运行代码---训练操作,并进行验证集验证
! python -u tools/train.py -c ../faster_rcnn_r34_1x.yml --eval

其中,faster_rcnn_r34_1x.yml为配置文件,内容如下

  • 超参数配置

目标检测定义 目标检测有哪些_目标检测_14

DataReader配置:

  • image_dir: images 图片路径
  • anno_path: Annotations/train_cpu.json 标注文件
  • dataset_dir: /home/aistudio/work/PCB_DATASET 数据路径
#预测,并可视化
! python -u tools/infer.py -c ../faster_rcnn_r34_1x.yml \
                --infer_img=../PCB_DATASET/images/04_missing_hole_10.jpg \
                -o weights=output/faster_rcnn_r34_1x/best_model

其他模型实现步骤跟faster R-CNN相似!

2、torchvision实现(基于pytorch)

(1)安装

直接用pip就能完成安装操作,故忽略。

(2)实现(参考pytorch教程文档)

import torchvision
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection.mask_rcnn import MaskRCNNPredictor


def get_model_instance_segmentation(num_classes):
    # load an instance segmentation model pre-trained on COCO
    model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)

    # get number of input features for the classifier
    in_features = model.roi_heads.box_predictor.cls_score.in_features
    # replace the pre-trained head with a new one
    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)

    # now get the number of input features for the mask classifier
    in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels
    hidden_layer = 256
    # and replace the mask predictor with a new one
    model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask,
                                                       hidden_layer,
                                                       num_classes)

    return model

(3)实现细节

  • backbone:骨干网络(提取图片特征,基本是卷积神经网络),需要知道Module的out_channels
  • rpn:区域预测网络
rpn = RegionProposalNetwork(
            rpn_anchor_generator, rpn_head,
            rpn_fg_iou_thresh, rpn_bg_iou_thresh,
            rpn_batch_size_per_image, rpn_positive_fraction,
            rpn_pre_nms_top_n, rpn_post_nms_top_n, rpn_nms_thresh,
            score_thresh=rpn_score_thresh)

#rpn_anchor_generator:AnchorGenerator-生成锚框
#rpn_head:RPNHead(包含classification and regression 的RPN head,参数:输入特征的通道数,被预测的anchors数量)
  • roi_heads:里边的方法有RoI Pooling 转成RoI Align。
roi_heads = RoIHeads(
            # Box
            box_roi_pool, box_head, box_predictor,
            box_fg_iou_thresh, box_bg_iou_thresh,
            box_batch_size_per_image, box_positive_fraction,
            bbox_reg_weights,
            box_score_thresh, box_nms_thresh, box_detections_per_img)
box_head: TwoMLPHead:两个linear
box_roi_pool:MultiScaleRoIAlign
box_predictor: FastRCNNPredictor 两个linear,一个做classifer,一个做box regression
  • transform