多目标跟踪的主要步骤:
- 获取原视频帧
- 利用目标检测器对视频帧中的目标进行检测
- 将检测到的目标的框中的特征提取出来,该特征包括表观特征(方便特征对比避免ID switch)和运动特征(运动特征方便卡尔曼滤波对其进行预测)
表观特征与运动特征:
表观特征:
描述目标的外观信息,通常包括颜色、纹理、形状等。主要基于目标的视觉外观进行识别和分类;常见的表观特征提取方法有卷积神经网络
运动特征:
描述目标在时序上的运动信息,关注目标的速度、方向、轨迹等随时间变化的属性;通常通过光流、轨迹分析、或者通过跟踪算法提取
- 计算前后两帧目标之间的匹配程度(利用匈牙利算法和级联匹配),为每个追踪道德目标分配ID
SORT流程:
Deepsort的前身是sort算法,sort算法的核心是卡尔曼滤波算法和匈牙利算法。
卡尔曼滤波:
卡尔曼公式的理解:
实现过程:
使用上一次的最优结果预测当前的值(先验估计),同时使用观测值(传感器所传值)修正当前值,得到最优结果(最优估计)
F:状态转移矩阵,描述系统如何从状态t-1变为t
U:控制输入(现实中指一些人为控制的变量)
B:控制输入矩阵
Q:过程噪声协方差矩阵,用来描述系统的过程噪声
Kk:卡尔曼增益矩阵,平衡预测和观测之间的权重
H:观测矩阵,描述观测如何映射到系统状态
R:观测噪声协方差矩阵,描述观测过程中的噪声
调整超参数:
卡尔曼滤波算法作用:
对检测框进行预测;用当前的一系列运动变量去预测下一时刻的运动变量,但是第一次的检测结果用来初始化卡尔曼滤波的运动变量。
卡尔曼滤波器与跟踪器:
在一段场景中,可以获得所有目标的box坐标,如果需要从多个检测结果中对一指定目标进行跟踪?
用该目标上一帧的box与所有检测到的box计算IoU,IoU最大的box可认为是被跟踪的目标;最大IoU匹配,更新跟踪框,不断进行迭代
当遇到障碍物遮挡时,漏检导致上一帧的box没有匹配对象?
使用卡尔曼滤波器对目标下一帧的位置进行估计,这样在检测器失效的情况下,可使用估计值来更新box的位置
单目标的前后帧跟踪里,目标框仅用最大IoU匹配轨迹和卡尔曼滤波预测;多目标的前后帧跟踪里,多个目标框用最大权值匹配轨迹,其中IoU作为“距离”去匹配,最后还要考虑没匹配上的观测值和状态值
IoU匹配里用到了上一帧的检测框来对下一帧进行IoU计算来匹配(取最大值),但是IoU匹配一旦找不到最大值就会失去匹配目标,也就是视频中因为遮挡产生的漏检,所以引入卡尔曼滤波之后可以让上一帧的检测框具有运动属性,从而使框不再和之前一样来自上一帧,而是根据运动属性预测下一帧,保持和当前检测框处于同一时间,解决IoU匹配问题。
匈牙利算法:
匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法
手算过程:
匈牙利算法作用:
解决分配问题;把一群检测框和卡尔曼预测的框做分配,让卡尔曼预测的框找到和自己最匹配的检测框,达到追踪的效果。
SORT的工作流程图:
Detections是通过目标检测到的框;Tracks是轨迹信息。
- 将第一帧检测到的结果创建对应的Tracks,用卡尔曼滤波的运动变量初始化,通过卡尔曼滤波预测其下一部分对应的框
- 将该帧目标检测的框与上一帧通过Tracks预测的框进行IoU匹配,再通过IoU匹配的结果计算其代价矩阵(cost matrix,计算公式为1-IoU)
- 将②中得到的所有的代价矩阵作为匈牙利算法的输入,得到线性的匹配的结果,得到的结果有三种:
- Unmatched Tracks:先前帧中已经存在的目标轨迹在当前帧中没有找到匹配的检测结果,直接将失配的Tracks删除;
- Unmatched Detections:在当前帧中检测到的新目标,然而这些检测结果没有与任何先前的轨迹匹配,将这样的Detections初始化为一个新的Tracks(new Tracks);
- 检测框和预测的框框配对成功,说明我们前一帧和后一帧追踪成功,将其对应的Detections通过卡尔曼滤波更新其对应的Tracks变量。
- 反复循环②~③的步骤,直到视频帧结束
SORT的劣势:
- 仅依赖于目标的运动信息(如卡尔曼滤波器预测目标的速度和位置)来进行轨迹的匹配和关联
- 在遮挡和目标丢失的场景下表现不佳
- 只基于卡尔曼滤波器的欧氏距离来进行轨迹关联
Deepsort算法流程:
与SORT的区别:
- SORT的卡尔曼为七维,更改为八维(x、y、w、h、x’、y’、w’、h’),x’、y’、w’、h’为x、y、w、h的导数,代表变化率
- 轨迹增删策略:大于一定更新值就删除;对于新轨迹连续存在一定的帧数才真正认为它是真正新轨迹
- 匹配策略:运动特征(卡尔曼的状态向量,八维只取了前四维;使用了马氏距离)和外观特征(用余弦相似度来衡量一个轨迹和一个检测的外观相似度)
轨迹状态:
SORT算法在物体发生遮挡时,容易丢失自己的ID;而Deepsort算法在sort算法的基础上增加了级联匹配(Matching Cascade)和新轨迹的确认(confirmed)。
Tracks分为确认态(confirmed)和不确认态(unconfirmed);新产生的Tracks是不确认态的;不确认态的Tracks必须要和Detections连续匹配一定的次数(默认为3)才可以转化为确认态;确认态的Tracks必须要和Detections连续失配一定次数(默认为30次),才会被删除
级联匹配:
级联匹配通常基于轨迹的“年龄”来逐步执行匹配过程。
基于一个假设:越最近出现的轨迹越有可能和检测相匹配,把轨迹划分为一些不相交的子集,每一个子集就表示这一个轨迹上一次更新是多长时间之前,轨迹也包含外观特征和卡尔曼状态向量,基于外观特征和卡尔曼状态向量计算代价矩阵
年龄:包括当前帧在内,有连续几帧未被匹配到
级联匹配流程:
①生成代价矩阵,包括马氏距离和外观距离
第i个轨迹和第j个检测框的代价(当外观信息和运动信息都有效时,才进行匹配)
马氏距离:
马氏距离计算方法:
②生成(与)门矩阵;根据马氏距离或外观距离,设置阈值,看是否算匹配上
门矩阵形成为相乘关系,当全为1,才为1,是一个或的关系;当一个距离不满足,就认为轨迹是不可能和检测框匹配
③初始化匹配项轨迹,第一步为空
Deepsort算法的工作流程:
- 将第一帧检测结果创建其对应的Tracks,将卡尔曼滤波的运动变量初始化,通过卡尔曼滤波预测其对应框,此时Tracks为unconfirmed
- 将该帧目标检测框与上一帧Tracks预测框进行IoU匹配,再通过IoU匹配的结果计算其代价矩阵(cost matrix,其计算方式为1-IoU)
- 将②中的得到的所有代价矩阵作为匈牙利算法的输入,得到线性的匹配结果,此时得到三种情况:
- Tracks失配,将失配Tracks(此时的Tracks为不确定态,若为确定态则需连续达到(默认30)次才可以删除)删除
- Detections失配,将Detections初始化为一个新的Tracks
- 检测框和预测框配对成功,说明前一帧与后一帧追踪成功,将其对应的detections通过卡尔曼滤波更新其对应的Tracks变量
- 反复循环②~③步,直到出现确认态的Tracks或视频帧结束
- 通过卡尔曼滤波预测其确认态的Tracks和不确认态的Tracks对应框。将确认态的Tracks的框和是Detections进行级联匹配(每次Tracks匹配成功都会保存Detections的外观特征和运动信息,默认保存前100帧,利用外观特征和运动信息和Detections进行级联匹配)。
- 进行级联匹配后可能出现三种可能结果:
- Tracks匹配,则Tracks通过卡尔曼滤波更新其对应的Tracks变量
- Detections和Tracks失配,将之前不确认状态的Tracks和失配的Tracks一起和Unmatched Detections进行IoU匹配,再通过IoU匹配的结果计算其代价矩阵(cost matrix,其计算方式为1-IoU)
- 将⑥中的得到的所有代价矩阵作为匈牙利算法的输入,得到线性的匹配结果,此时得到三种情况:
- Tracks失配,将失配Tracks(此时的Tracks为不确定态,若为确定态则需连续达到(默认30)次才可以删除)删除
- Detections失配,将Detections初始化为一个新的Tracks
- 检测框和预测框配对成功,说明前一帧与后一帧追踪成功,将其对应的detections通过卡尔曼滤波更新其对应的Tracks变量
- 反复循环⑤~⑦步骤,直到视频帧结束