# 详细设计文档
# 算法、数据来源、评判标准、参考文献
## 1算法
### 1.1车辆、行人检测框架
YOLO V3
### Yolo V3结构图

* DBL: 如图1左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+BN+Leaky relu。对于v3来说,BN和leaky relu已经是和卷积层不可分离的部分了(最后一层卷积除外),共同构成了最小组件。
* resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。这是yolo_v3的大组件,yolo_v3开始借鉴了ResNet的残差结构,使用这种结构可以让网络结构更深(从v2的darknet-19上升到v3的darknet-53,前者没有残差结构)。对于res_block的解释,可以在图1的右下角直观看到,其基本组件也是DBL。
* concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。
### yolo_v3_body

对于代码层面的layers数量一共有252层,包括add层23层(主要用于res_block的构成,每个res_unit需要一个add层,一共有1+2+8+8+4=23层)。除此之外,BN层和LeakyReLU层数量完全一样(72层),在网络结构中的表现为:每一层BN后面都会接一层LeakyReLU。卷积层一共有75层,其中有72层后面都会接BN+LeakyReLU的组合构成基本组件DBL。看结构图,可以发现上采样和concat都有2次,和表格分析中对应上。每个res_block都会用上一个零填充,一共有5个res_block。
### backbone
整个v3结构里面,是没有池化层和全连接层的。前向传播过程中,张量的尺寸变换是通过改变卷积核的步长来实现的,比如stride=(2, 2),这就等于将图像边长缩小了一半(即面积缩小到原来的1/4)。在yolo_v2中,要经历5次缩小,会将特征图缩小到原输入尺寸的1/2^5,即1/32。输入416x416,则输出为13x13(416/32=13)。
yolo_v3也和v2一样,backbone都会将输出特征图缩小到输入的1/32。所以,通常都要求输入图片是32的倍数。可以对比v2和v3的backbone看看:(DarkNet-19 与 DarkNet-53)

### Output
输出张量:

yolo v3输出了3个不同尺度的feature map,如上图所示的y1, y2, y3。这也是v3论文中提到的为数不多的改进点:predictions across scales
这个借鉴了FPN(feature pyramid networks),采用多尺度来对不同size的目标进行检测,越精细的grid cell就可以检测出越精细的物体。
y1,y2和y3的深度都是255,边长的规律是13:26:52
对于COCO类别而言,有80个种类,所以每个box应该对每个种类都输出一个概率。
yolo v3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)五个基本参数,然后还要有80个类别的概率。所以3*(5 + 80) = 255。
### some tricks
b-box预测手段是v3论文中提到的又一个亮点。
yolo v2的b-box预测方法:直接预测相对位置。预测出b-box中心点相对于网格单元左上角的相对坐标。
$$
\begin{aligned}
b_{x} &=\sigma\left(t_{x}\right)+c_{x} \\
b_{y} &=\sigma\left(t_{y}\right)+c_{y} \\
b_{w} &=p_{w} e^{t_{w}} \\
b_{h} &=p_{h} e^{t_{h}} \\
\operatorname{Pr}(\text { object }) * I O U(b, \text { object }) &=\sigma\left(t_{o}\right) \text { optrum }
\end{aligned}
$$

yolo v2直接predict出$$\left(t_{x}, t_{y}, t_{w}, t_{h}, t_{o}\right)$$,并不像RPN中anchor机制那样去遍历每一个pixel。可以从上面的公式看出,b-box的位置大小和confidence都可以通过$$\left(t_{x}, t_{y}, t_{w}, t_{h}, t_{o}\right)$$计算得来,v2相当直接predict出了b-box的位置大小和confidence。
yolo v3对b-box进行预测的时候,采用了logistic regression。这类似RPN中的线性回归调整b-box。v3每次对b-box进行predict时,输出和v2一样都是$\left(t_{x}, t_{y}, t_{w}, t_{h}, t_{o}\right)$,然后通过公式1计算出绝对的(x, y, w, h, c)。
logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模
### loss function
在目标检测任务里,有几个关键信息是需要确定的:
$(x, y),(w, h), \text { class, confidence}$
根据关键信息的特点可以分为上述四类,损失函数应该由各自特点确定。最后加到一起就可以组成最终的loss_function了,也就是一个loss_function搞定端到端的训练。
除了w, h的损失函数依然采用总方误差之外,其他部分的损失函数用的是二值交叉熵。最后加到一起。
### 1.2车辆颜色、车辆朝向、车辆类型识别 car_class
程序调用函数cls_draw_bbox,在cls_draw_bbox中,逐一处理每个检测框。
首先,取出原图像检测框区域检测框对应的的ROI(region of interest),将ROI送入车辆多标签分类器。分类器调用B-CNN算法对ROI中的车辆进行多标签属性分类。B-CNN主要用于训练端到端的细粒度分类。为了兼顾程序的推断速度和准确度,这里的B-CNN的基础网络采用Resnet-18。
* 车辆多标签数据模块 dataset.py
Vehicle类重载了data.Dataset的init, getitem, len方法:
__init__函数负责初始化数据路径,数据标签,由于数据标签是多标签类型,故对输出向量分段计算交叉熵loss即可
__getitem__函数负责迭代返回数据和标签,返回的数据需要经过标准化等预处理
__len__函数获取数据的总数量
* 车辆多标签训练、测试模块 train_vehicle_multilabel.py
此模块负责车辆多标签的训练和测试。训练过程选择交叉熵作为损失函数,需要注意的是,由于是多标签分类,故计算loss的时候需要累加各个标签的loss,其中loss = loss_color + loss_direction + 2.0 * loss_type,根据经验,将车辆类型的loss权重放大到2倍效果较好。
另一方面,训练分为两步:
(1)冻结除了Resnet-18除全连接层之外的所有层,Fine-tune训练到收敛为止;
(2)打开第一步中冻结的所有层,进一步Fine-tune训练,调整所有层的权重,直至整个模型收敛为止
### 1.3车辆检测(cv2.CascadeClassifier——HyperLPR的分类模型)
LBP含义为局部二值模式,是用来描述图像局部纹理特征的算子。由T.Ojala, M.Pietikäinen, 和 D. Harwood在1994年提出,最初是为纹理描述而设计的。由于LBP对单调灰度变化的不变性和计算效率高,其适用于高要求的图像分析任务,在计算机视觉的许多领域都得到了广泛的应用:比如人脸识别、目标检测、应用LBP特征来进行训练目标检测分类器。
* LBP特征的描述
原始的LBP算子定义为在3*3的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数(通常转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。如下图所示:

* LBP特征用于检测的原理
提取的LBP算子在每个像素点都可以得到一个LBP“编码”,那么,对一幅图像(记录的是每个像素点的灰度值)提取其原始的LBP算子之后,得到的原始LBP特征依然是“一幅图片”(记录的是每个像素点的LBP值)。
从下图可以看出LBP对光照具有很强的鲁棒性。

LBP的应用中,一般都不将LBP图谱作为特征向量用于分类识别,而是采用LBP特征谱的统计直方图作为特征向量用于分类识别。
因为,从上面的分析我们可以看出,这个“特征”跟位置信息是紧密相关的。直接对两幅图片提取这种“特征”,并进行判别分析的话,会因为“位置没有对准”而产生很大的误差。后来,研究人员发现,可以将一幅图片划分为若干的子区域,对每个子区域内的每个像素点都提取LBP特征,然后,在每个子区域内建立LBP特征的统计直方图。如此一来,每个子区域,就可以用一个统计直方图来进行描述,整个图片就由若干个统计直方图组成。
例如:一幅100*100像素大小的图片,划分为10*10=100个子区域(可以通过多种方式来划分区域),每个子区域的大小为10*10像素;在每个子区域内的每个像素点,提取其LBP特征,然后,建立统计直方图;这样,这幅图片就有10*10个子区域,也就有了10*10个统计直方图,利用这10*10个统计直方图,就可以描述这幅图片了。之后,我们利用各种相似性度量函数,就可以判断两幅图像之间的相似性了。
* 对LBP特征向量进行提取的步骤
(1)首先将检测窗口划分为16×16的小区域(cell);
(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;
(3)然后计算每个cell的直方图,即每个数字(假定是十进制数LBP值)出现的频率;然后对该直方图进行归一化处理。
(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也就是整幅图的LBP纹理特征向量;
然后便可利用SVM或者其他机器学习算法进行分类。
### 1.4车牌识别
#### OCR
传统OCR所采用的Pipline
* 文档分析(提取文档区域,包括了文档的校正等操作)
* 行分割
* 字符分割
* 字符识别
* 重新排版
##### 字符分割
* 基于滑动窗口的字符分割方法
主要思想是利用一个训练好的正负样本分类器来进行在图像上滑动然后产生概率response图,然后对raw response进行nms(非极大值抑制)。在确定字符bdbox,数目之后使用类似于viterbi算法来获取最佳分割路径。

* HyperLPR中的字符分割方法
也是基于滑动窗口的分割方法。首先训练一个分类器输出三种概率分别为正样本、负样本、中文字符。
接着对车牌做滑动输出每个位置的三种字符概率(这个滑动的窗口的stride可以设高一点使得速度更快)接着对这三种利用车牌的模板进行匹配。使得第一个字符的中文概率+后6个字符的正样本概率最大。这个最大的位置即为最佳分割位置。
约束条件:
\begin{array}{l}
X_{0}=\text { zeroadd } \\
X_{1}=X_{0}+w+\text {interval} \\
X_{n}=X_{n-1}+w(n>2) \\
F(\text {zeroadd jnterval,w})=\sum_{i=0}^{i=5} H\left(X_{i}\right) \\
\text {Min}(F\text { zeroadd jnterval,w) }
\end{array}
* 字符分割模型的训练
训练只需提供三种样本
../character_judgement_samples/T #正样本 正样本指样本图片的中心有文字
../character_judgement_samples/F #负样本 负样本指样本图片的中心无文字,左右两侧有也没有关系
../character_judgement_samples/CH #中文样本 正样本指样本图片的中心有中文文字
###### 图例
正样本

负样本

中文样本

###### 依赖环境
* Tensorflow
* Keras
* OpenCV3
车牌识别部分使用 HyperLPR 高性能开源中文车牌识别框架
代码地址:https://github.com/zeusees/HyperLPR
#### 1.5车辆重识别概述
随着深度学习技术的发展,重识别(ReID)在计算机视觉领域得到了广泛的研究,本程序的车辆重识别技术基于深度学习算法,先用卷积神经网络对输入图片进行各种各样的卷积操作后,提取出重要特征后压缩成一个embedded向量,对这个表示向量采取度量学习来进行相似度计算。下图即是车辆重识别的一个基本流程:

#### 1.5.1特征提取网络
IBN-Net是具有域/外观不变性的CNN模型,不仅在单个深度网络中统一实例规范化和批处理规范化,还提供了一种简单的方法来增加建模和归纳能力,而不会增加模型的复杂性。因此IBN-Net特别适合跨分布域或行人车辆的重新识别任务。

#### 1.5.2车辆身份分类
将最后得到的特征向量经过一个batch-normalize层,并对正则化后的向量输入到全连接分类网络中进行ID分类。

* 论文:https://arxiv.org/pdf/2004.10547.pdf
* 代码:https://github.com/heshuting555/AICITY2020_DMT_VehicleReID
#### 1.6车辆跟踪算法
Sort
* 论文 http://arxiv.org/pdf/1602.00763.pdf
* 代码 https://github.com/abewley/sort
##### 概述
物体跟踪是把物体跟踪预测的BBox与物体检测的BBox关联,然后用对应的物体检测BBox代表成功跟踪的BBox结果

* 假设T1时刻成功跟踪了某个单个物体,ID为1,绘制物体跟踪BBox(紫色)
* T2时刻物体检测BBox总共有4个(黑色),预测T2时刻物体跟踪的BBox(紫色)有1个,解决紫色物体跟踪BBox如何与黑色物体检测BBox关联的算法,就是SORT物体跟踪算法要解决的核心问题
* SORT关联两个BBox的核心算法是:用IOU计算Bbox之间的距离 + 匈牙利算法选择最优关联结果
###### 多目标跟踪

* T1时刻已经成功跟踪了3个检体(不同颜色的BBox代表不同的物体ID)
* T2时刻除了所有物体检测的新位置BBox(灰色),还要物体跟踪预测的Bbox(非灰的其它不同颜色BBox)与物体检测Bbox(灰色)关联,从而分辨出哪一个物体跟踪的Bbox对应哪一个物体检测的BBox,从而产生T2时刻的物体跟踪BBox结果(包括新增物体跟踪器跟踪T2中新检测到的物体)
* T3时刻如果被追踪的物体发生了遮挡(红框BBox的物体),那么要继续能找到该物体并追踪 (避免ID Switch)
### 2数据来源
#### 2.1 yolo数据集
Coco
* 官网地址 http://cocodataset.org
* 数据集下载 http://cocodataset.org/#download
* 简介
COCO数据集是一个大型的、丰富的物体检测,分割和字幕数据集。这个数据集以scene understanding为目标,主要从复杂的日常场景中截取,图像中的目标通过精确的segmentation进行位置的标定。图像包括91类目标,328,000影像和2,500,000个label。目前为止有语义分割的最大数据集,提供的类别有80类,有超过33 万张图片,其中20万张有标注,整个数据集中个体的数目超过150万个。
* Coco目标检测挑战
1. COCO数据集包含20万个图像;
2. 80个类别中有超过50万个目标标注,它是最广泛公开的目标检测数据库;
3. 平均每个图像的目标数为7.2,这些是目标检测挑战的著名数据集。
* Coco数据集的特点
1. 对象分割;
2. 在上下文中可识别;
3. 超像素分割;
4. 330K图像(>200K标记);
5. 150万个对象实例;
6. 80个对象类别;
7. 91个类别;
8. 每张图片5个字幕;
9. 有关键点的250,000人;
* Coco数据集的大小和版本
1. 大小:25GB(压缩)
2. 记录数量:330K图像、80个对象类别、每幅图像有5个标签、25万个关键点。
COCO数据集分两部分发布,前部分于2014年发布,后部分于2015年。
2014年版本:82,783 training, 40,504 validation, and 40,775 testing images,有270k的segmented people和886k的segmented object;
2015年版本:165,482 train, 81,208 val, and 81,434 test images。
2014年版本的数据,一共有20G左右的图片和500M左右的标签文件。标签文件标记了每个segmentation的像素精确位置+bounding box的精确坐标,其精度均为小数点后两位。
#### 2.2 车牌数据集
CCPD and PDRC标注、数据样本
CCPD(Chinese City Parking Dataset,ECCV)and PDRC (license Plate Detection and Recognition Challenge)
[ECCV 2018] CCPD&PDRC:用于车牌检测和识别的多样化的数据集
这是一个用于车牌识别的大型国内的数据集,由中科大的科研人员构建出来的。发表在ECCV 2018论文Towards End-to-End License Plate Detection and Recognition: A Large Dataset and Baseline
该数据集在合肥市的停车场采集得来的,采集时间早上7:30到晚上10:00。涉及多种复杂环境。
一共包含超过25万张图片,每种图片大小720*1160*3
一共包含9项,每项占比如下图:

数据集内部包含的文件夹以及内容如下表所示:

数据集下载地址:https://github.com/detectRecog/CCPD
## 3评判标准
#### 3.1 目标检测性能评价指标
假设我们分类目标只有两类,计为正例(positive)和负例(negtive)分别是:
1)True positives(TP): 被正确地划分为正例的个数,即实际为正例且被分类器划分为正例的实例数(样本数);
2)False positives(FP): 被错误地划分为正例的个数,即实际为负例但被分类器划分为正例的实例数;
3)False negatives(FN):被错误地划分为负例的个数,即实际为正例但被分类器划分为负例的实例数;
4)True negatives(TN): 被正确地划分为负例的个数,即实际为负例且被分类器划分为负例的实例数。
##### P
代表precision即准确率
计算公式为:
预测样本中实际正样本数/所有的正样本数 即 precision=TP/(TP+FP)
##### R
代表recall即召回率
计算公式为:
预测样本中实际正样本数/预测的样本数 即 Recall=TP/(TP+FN)=TP/P
一般来说,precision和recall是鱼与熊掌的关系,往往召回率越高,准确率越低
##### AP
代表Average Precision即平均精确度
##### P-R曲线

P-R曲线即以precision和recall作为纵、横轴坐标的二维曲线。通过选取不同阈值时对应的精度和召回率画出
总体趋势,精度越高,召回越低,当召回达到1时,对应概率分数最低的正样本,这个时候正样本数量除以所有大于等于该阈值的样本数量就是最低的精度值
另外,P-R曲线围起来的面积就是AP值,通常来说一个越好的分类器,AP值越高
* mAP
mAP即Mean Average Precision即平均AP值,是对多个验证集个体求平均AP值,作为 object dection中衡量检测精度的指标
在目标检测中,每一类都可以根据recall和precision绘制P-R曲线,AP就是该曲线下的面积,mAP就是所有类AP的平均值
* IOU(交并比)
即Intersection-over-Union,是目标检测中使用的一个概念,是一种测量在特定数据集中检测相应物体准确度的一个标准
IOU表示了产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率或者说重叠度,也就是它们的交集与并集的比值。相关度越高该值。最理想情况是完全重叠,即比值为1。

计算公式:
$\operatorname{lo} U=\frac{\operatorname{area}(C) \cap \operatorname{area}(G)}{\operatorname{area}(C) \cup \operatorname{area}(G)}$
* NMS(非极大抑制)
NMS即non maximum suppression即非极大抑制,顾名思义就是抑制不是极大值的元素,搜索局部的极大值。
在物体检测中,NMS应用十分广泛,其目的是为了清除多余的框,找到最佳的物体检测的位置。
* 速度
除了检测准确度,目标检测算法的另外一个重要性能指标是速度,只有速度快,才能实现实时检测,这对一些应用场景极其重要。评估速度的常用指标是每秒帧率(Frame Per Second,FPS),即每秒内可以处理的图片数量。当然要对比FPS,你需要在同一硬件上进行。另外也可以使用处理一张图片所需时间来评估检测速度,时间越短,速度越快。
#### 3.2 车辆重识别性能评价指标
* Rank-k
在车辆重识别任务中,我们的目标是在不同的相机下寻找到与查询(Query)车辆最相似的车辆。
通常我们的数据集中会有查询集(Query set)和测试集(Test set)又或叫做展览集(Gallery set)。
当我们输入一张Query set中的车辆图像,便在Gallery set中寻找与之最相似的车辆图像。处理方法常是利用训练好的网络,只进行前向传播(feed-forward),抽取出最后一个FC层的特征(对于多目标车辆重识别任务,我们常抽取Identification层的特征)。对于每一个Query set中的图像的特征,计算它与Gallery set中所有图像的相似度(用欧式距离、余弦相似度等表示)。
Rank-k即表示按照相似度排序后的前k张图像中存在与查询图像(Query Image)属于同一ID的准确率。
假设ID的数量为N,也即最后一层FC层的神经元数量为N,特征的维数即为N,提取query图像的特征如下形式:
feature $_{q_{\text {leny }}}=\left[q_{1}, q_{2}, \cdots, q_{N}\right]$
Gallery set含有M张图片,提取test set所有图像的特征如下形式:
feature$_{\text {sillev}}=\left[\begin{array}{ccc}a_{11}, a_{12}, \cdots, & a_{1 N} \\ a_{21}, a_{22}, \cdots, & a_{2 N} \\ \vdots & \vdots & \vdots \\ a_{M 1}, a_{M 2}, \cdots, a_{N N}\end{array}\right]$
利用欧式距离计算图片之间的相似度(similarity),定义符号S表示相似度,相似度如下形式:
$S_{M}=\sqrt{\sum_{k=1}^{N}\left(q_{k}-a_{M k}\right)^{2}}$
其中,qk为查询图像提取后的特征中的一个分量,amk为test set中第M张图像的特征中的一个分量。SM越低表示图像相似性越大,可能是同一幅图像的置信度越高。
继而将SM按照大小从低到高排序,根据Test set中的标签(label)和query image的标签相对照,计算出准确率。
分别计算Rank-k,k=1,5,10,15,20的准确率,即分别计算在排序后的test set集中前1,5,10,15,20内能找到与query image相同标签的图像。
### 4参考文献
[1] Redmon J , Farhadi A . YOLOv3: An Incremental Improvement[J]. 2018.
[2] Shuting He
, Hao Luo, Weihua Chen
, Miao Zhang
, Yuqi Zhang
Fan Wang
, Hao Li
, Wei Jiang.Multi-Domain Learning and Identity Mining for Vehicle Re-Identification[J]. arXiv, 2004.
[3] Bewley A , Ge Z , Ott L , et al. Simple Online and Realtime Tracking[J]. arXiv, 2016.
[4] Yan D , Hongqing M , Jilin L , et al. A high performance license plate recognition system based on the web technique[C]// Intelligent Transportation Systems. IEEE, 2001.
[5] 王耀玮, 唐伦, 刘云龙,等. 基于多任务卷积神经网络的车辆多属性识别[J]. 计算机工程与应用, 2018(8):21-27.
[6] 阮航, 孙涵. 基于FasterR-CNN的车辆多属性识别[J]. 计算机技术与发展, 2018, 028(010):129-134.