目标检测是计算机视觉领域中非常重要的一个研究方向,它是将图像或者视频中目标与其他不感兴趣的部分进行区分,判断是否存在目标,确定目标位置,识别目标种类的任务,即定位+分类。传统的目标检测模型有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之间的关系,它等于两个集合的交集里面所包含的元素个数,除以它们的并集里面所包含的元素个数,具体计算公式如下:
我们将用这个概念来描述两个框之间的重合度。两个框可以看成是两个像素的集合,它们的交并比等于两个框重合部分的面积除以它们合并起来的面积。
(7)mAP
AP(Average Precision)是某一类以Precision、Recall为纵、横坐标的曲线下的面积,mAP(mean Average Precision)是所有类别AP平均。
(8)NMS
搜索局部最大值,抑制极大值。
2、深度学习的目标检测方案
在Ross Girshick等人提出DPM方法后,目标检测进入瓶颈期,图像特征提取成为难点,随着CNN的发展,也开始尝试将神经网络加入到目标检测任务中。该图是几个模型的差异对比:
(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),输入是前一层任意大小的特征图,输出是一系列的矩形目标候选区,在卷积神经网络的最后一个特征层上滑动。
为了适应多种形状的物体,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进行计算的,公式为
ROI Align:消除ROI Padding的误差
在区域内均匀的取N个点,找到特征图上离每个点最近的四个点,再通过双线性插值的方式,得到点的输出值,最后对N个点取平均得到区域的输出。
(4)进阶模型
- FPN(解决多尺度问题)
方案可以构造多尺度金字塔,期望模型能够具备检测不同大小尺度物体的能力,具体方案如下图:
- a是将特征缩放到不同尺度,使用多个模型进行预测
- b是仅使用最后一层的特征作为检测模型后续部分的输入
- c是每个层级分别预测
- d是使用不同层级特征进行融合,在分级预测(FPN)
FPN是以骨干网络的输出为输入,将特征进行上采样并与上一层特征相加得到FPN结构每一层的输出,网络结构图如下
在FPN结构中,会存在多个ROI Align,将FPN的特征金字塔类比为图像金字塔,可以通过面积来对候选框进行分配。
- Cascade R-CNN(IoU)
Cascade R-CNN主要是对IoU指标的改进,IoU是计算两个框之间的重叠区域,在模型中涉及到的细节有:一、计算基于Anchor和GT框的IoU值,二是基于预测框和真实框的IoU值。通过调整IoU的阈值并未对模型有较大提升,单一阈值训练的模型有限,因此,对模型进行多Head改进。
- Libra R-CNN
Libra R-CNN进行三方面的改进,分别是特征融合、采样策略、损失函数。
增强FPN的特征融合:
- Rescale(重新调节):将不同层级的特征图(C层)通过差值或者下采样的方法进行统一到C4层
- Integrate(合并):将汇集的特征进行融合
- refine(重新定义):使用non-local结构对融合特征进行加强
- strengthen(增强):将优化的特征与不同层级上的原始特征加和
采样策略:
- 正样本采样(正样本类别不平衡):对正样本里边的类别进行随机采样,保证类别均衡
- 负样本采样(负样本IoU分配不平衡):根据阈值划分,高于阈值的进行分桶,计算应该落在每个桶中的样本数量,最后得到IoU均匀分布的负样本;低于阈值的样本随机采样
Loss(Smooth L1 loss--->Balanced L1 loss):
还有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
(2)介绍
在PaddleDetection中实现目标检测、关键点检测、实例分割等算法,具体模型如下:
(3)模型包内容拆解
核心文件有四个configs、dataset、demo、tools, 包含了数据集、测试、模型、训练整个过程,可以按需调整实现。
教程参考:飞桨AI Studio - 人工智能学习与实训社区
(4)实现
#运行代码---训练操作,并进行验证集验证
! python -u tools/train.py -c ../faster_rcnn_r34_1x.yml --eval
其中,faster_rcnn_r34_1x.yml为配置文件,内容如下
- 超参数配置
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 MaskRCNNPredictordef get_model_instance_segmentation(num_classes):# load an instance segmentation model pre-trained on COCOmodel = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)# get number of input features for the classifierin_features = model.roi_heads.box_predictor.cls_score.in_features# replace the pre-trained head with a new onemodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)# now get the number of input features for the mask classifierin_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channelshidden_layer = 256# and replace the mask predictor with a new onemodel.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(# Boxbox_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