FairMOT理解与实现

理解:
(1)概述:多目标跟踪,单纯跟踪能力不足以完成任务,所以,不同于单目标跟踪,这里加入了检测任务,可以将多目标跟踪任务看成为目标检测+重识别任务。
(2)论文网络结构
FairMOT理解与实现_第1张图片
文中网络结构分3大部分:
网络结构在:.\src\lib\models\networks\pose_dla_dcn.py中。
①:Encoder-decoder 部分
网络中,这是backbone network部分,主干网络为DLA-34(34层的DLA),最终input(HxW)->output(H/4xW/4)
Encoder部分(base/DLA):
FairMOT理解与实现_第2张图片
其中:Tree结构为:conv1->bn1->relu->conv2->bn2;
root结构为:conv->bn->relu;
downSample结构为:Maxpool2d;
project结构为:conv->bn
project结构为:conv->bn
Encoder部分的网络结构类似金字塔结构(或者树形结构),实现不同block,不同深度之间的特征融合。
decoder 部分(dlA-up/DLAup):decoder 部分实际就是反卷积上采样的过程,实现输出为原图尺寸的1/4。
FairMOT理解与实现_第3张图片
其中:Proj结构为:BN->Relu->conv;
Up结构为:convTranspose2d;
node结构为:BN->Relu->conv;
②:detection部分+Re-ID部分
Encoder-decoder 部分之后,并行的接入4部分,分别为:{hm,wh,reg,id}
其中,这四部分结构均为:con2d(3 * 3卷积)->Relu->con2d(1*1卷积),每个部分为一个任务,继而每个任务,需要加一个loss约束。
Hm:采用基于热力图定位目标中心点位置,实现anchor-free。
FairMOT理解与实现_第4张图片
如上图所示,如果用anchor表示目标位置。在目标相互靠近时,anchor给出来的位置很粗糙,所以在文中,作者采用点代表目标,位置会比较精确。
Loss:假如在原图中
FairMOT理解与实现_第5张图片
Wh:负责预测目标的长宽尺寸。reg负责预测长宽偏移尺寸,引入这个任务的目的是为了更精确的定位目标位置。将这两个任务的loss写在一起:(懒的写,盗用一下博友的图)
FairMOT理解与实现_第6张图片
Id:重识别的过程。相当于分类任务,判断目标是哪一类(跟踪任务中,同一个目标为一类)(懒的写,盗用一下博友的图)
FairMOT理解与实现_第7张图片
3)复现(服务器上训练):
官网链接:https://github.com/ifzhang/FairMOT
①首先搭建需要的环境,编译项目:
conda install pytorch1.2.0 torchvision0.4.0 cudatoolkit=10.0 -c pytorch
cd ${FAIRMOT_ROOT}
pip install -r requirements.txt
cd src/lib/models/networks/DCNv2_new sh make.sh
② 准备数据(只使用了2DMOT2015为训练集)
FairMOT理解与实现_第8张图片
将2DMOT2015.zip解压,重命名为images,放入./FairMOT-master/FairMOT-master/dataset/MOT15目录下,解析完后,里面有train和test两个文件夹,里面存着train和test数据,再在./FairMOT-master/FairMOT-master/dataset/MOT15目录下新建一个labels_with_ids文件夹,里面建一个空的train文件夹。
然后下载seqinfo 文件,将 seqinfo 文件夹中的 *.ini 复制到 MOT15 对应的文件夹中,如下所示:FairMOT理解与实现_第9张图片
下面网盘里提供2DMOT2015.zip,seqinfo 文件,和预训练模型。
链接:https://pan.baidu.com/s/1Ue702BbAIB_EGA8rYoWo2w
提取码:kb37

然后修改 src/python gen_labels_15.py 文件中数据集的路径,
FairMOT理解与实现_第10张图片
运行 gen_labels_15.py,
./FairMOT-master/FairMOT-master/dataset/MOT15/labels_with_ids/train,文件夹中就会生成训练集的label.
③ 准备预训练模型
FairMOT理解与实现_第11张图片
④ 修改训练集地址(因为只用了2DMOT2015),均改自己数据集的位置
./src/lib/opts.py
FairMOT理解与实现_第12张图片
src/lib/cfg/mot15.json
FairMOT理解与实现_第13张图片
⑤:训练…
根据自己实际,修改all_dla34.sh
sh experiments/all_dla34.sh
FairMOT理解与实现_第14张图片
使用2DMOT2015的16段视频训练的结果:
FairMOT理解与实现_第15张图片
FairMOT理解与实现_第16张图片
FairMOT理解与实现_第17张图片
跟踪过程:
(一)获取网络个tensor输出
Hm:热力图,size=[1,1,152,272];
Wh:回归长宽,size=[1,2,152,272];
Id:重识别特征,size=[1,512,152,272];
Reg:中心点偏移,size=[1,2,152,272];
(二):相应的处理,为了得到目标框bboxes以及对应目标id_feature。
①对hm做一个sigmoid()处理,将数值归一到0-1;
②对id 做一个normalize()归一化处理;
③将归一化的hm做_nms处理, 跟传统nms不太一样,这里的_nms是把hm做一个3*3大小卷积的max_pool2d,然后只保留和原来hm一样的值(每9个临域中最大的数值被保留,其他全部置0);
④使用topk,取前K(论文源码中,K=128)个scores,size=[1,128],以及相应的位置索引inds,size=[1,128],x轴位置索引xs,size=[1,128],y轴位置索引ys,size=[1,128];
|0 |0 |8
|7 |0 |0
| 0| 8|0
如:在上图一个vector中,是用topk提取前3个scores={8,7,8},inds={2,3,7},xs={2,0,1},ys={1,2,0}
⑤根据hm得到的inds索引,获取所需的reg,size=[1,128,2],然后reg[:,:,0]与hm所求的xs,reg[:,:,1]与hm所求的ys分别相加,得到最终目标中心点的坐标(x,y);
⑥根据hm得到的inds索引,获取所需的wh,size=[1,128,2],然后结合目标长宽,得到最终目标框bboxes={x1,y1,x2,y2},size=[1,128,4]
⑦根据hm得到的inds索引,获取所需的id_feature,size=[1,128,512],去掉维度为1的维度,得到size=[128,512]
⑧设置超参conf_thres,源码conf_thres=0.4,保留scores大于conf_thres的分数,以及对应的bboxes,size=[15,4]和id_feature,size=[15,512];
(三)第一帧得到目标框bboxes以及对应目标id_feature保留在stracked_stracks中,初始化跟踪轨迹,一个目标一个id号;
(四)第二帧:
① 进行步骤(一),预测的第二帧目标框bboxes以及对应目标id_feature;
② 与tracklets中保留的目标计算两辆之间目标框iou,dists=1-iou当做两目标之间的距离,如果第一帧有15个目标,第二帧有17个目标,则dists 的size=[15,17];
③ 在第一帧中找与第二帧距离小于距离阈值的两两目标对,找到存放tracked_stracks,id不变,这些目标认为是正在跟踪的目标;并找到两帧不同时出现的目标,保留初始化轨迹在activated_starcks中;
④将activated_starcks合并到stracked_stracks中。
(五)第三帧:
① 进行步骤(一),预测的第三帧目标框bboxes以及对应目标id_feature;
② 将正在跟踪的目标(tracked_stracks里的目标)与第三帧目标的id_feature特征求余弦距离
③ 使用卡尔曼滤波预测tracked_stracks中新的mean和conv,并计算新旧两者之间的马氏距离。将大于阈值的距离设置无穷大,便于删除;
④ 只保留小于距离阈值的轨迹(源码为0.7),保留在activated_starcks中
⑤ 将上面匹配漏的tracked_stracks中目标存放到lost_stracks中,并与第三帧中没有匹配上的目标进行iou处理,如果有匹配上的,合并到activated_starcks中,id不变,

⑥ 将上一帧初始化的目标与这一帧没有匹配上的目标做iou处理,如果有匹配上的,合并到activated_starcks中,id不变;
⑦ 将这一帧没有匹配上的,合并到activated_starcks中,初始化轨迹;

你可能感兴趣的:(跟踪)