前言
Kalman滤波器是多目标跟踪任务中一个经典的运动模型,本次主要以代码实践进行讲解。下文中所有的代码都会开源在https://github.com/nightmaredimple/libmot。
1Kalman Filter
本章将结合Kalman理论部分进行讲述,Kalman滤波器主要分为预测和更新两个阶段,在这之前能,我们需要预先设定状态变量和观测变量维度、协方差矩阵、运动形式和转换矩阵:
1 | def __init__(self, dim_x, dim_z, dim_u = 0, x = None, P = None, |
上述即对Kalman滤波器中各个参数的初始化,一般各个协方差矩阵都会初始化为单位矩阵,因此具体的矩阵初始化还需要针对特定场景设计,会在下一章介绍。
然后进入预测环节,这里我们为了保证通用性,引入了遗忘系数$\alpha$,其作用在于调节对过往信息的依赖程度,$\alpha$越大对历史信息的依赖越小。
$$ \begin{array}{l}x = Fx + Bu\\P = \alpha FxF^T + Q\end{array} $$
相应的代码如下:
1 | def predict(self, u = None, B = None, F = None, Q = None): |
而对于更新阶段,有:
$$ \left\{ \begin{array}{l} K = PH^T/\left( {HPH^T + R} \right)\\ x = Hx + K\left( {z - Hx} \right)\\ P = (1 - KH)P \end{array} \right. $$
不过在实际工程应用中通常会做一些微调:
$$ P = \left( {1 - KH} \right)P{\left( {1 - KH} \right)^T} + KR{K^T} $$
1 | def update(self, z, R = None, H = None): |
其中我们可以注意到马氏距离的计算方式:
1 | self._mahalanobis = math.sqrt(float(self.y.T @self.SI @ self.y)) |
另外,我们保存上个阶段的状态,其主要作用在于,第一防止多次更新带来的重复运算,第二防止前一次更新对下一次更新参数造成影响。
2KalmanTracker
那么对于Kalman滤波器的跟踪器设计,我们这里直接借鉴DeepSort的参数设计方案%E2%80%94%E2%80%94%E5%BA%94%E7%94%A8%E7%AF%87/](https://huangpiao.tech/2020/02/29/Kalman滤波在MOT中的应用(二)——应用篇/),因此基于KalmanFilter的设计,需要在初始化阶段之后修改对应的参数:
1 | def __init__(self, box, fading_memory = 1.0, dt = 1.0, std_weight_position = 0.05, std_weight_velocity = 0.00625): |
其中,DeepSort对于Q和R的设计中,为了保证各自对目标尺度更加敏感,采用了自适应的方式,即同样的公式应用在每一次跟踪:
1 | def predict(self): |
另外,为了方便多个观测量对Kalman滤波器的多次更新,我加入了一个批处理模块,主要作用有:防止重复更新造成的变量内存改变、消除重复更新参数部分.
1 | def batch_filter(self, zs): |
3Example
前两章将Kalman滤波器和跟踪器的代码层面都设计好了,接下来我们以MOT17-10数据集为例进行跟踪实验。这里不采用DeepSort的方式,我自己简单搭建了一套流程:
Step1 我们先初始化参数:
1 | track_len = 655 # total tracking length |
Step2 读取detection和groundtruth文件,筛选出满足行人类别和检测置信度阈值的目标:
1 | # prefetch |
Step3 对每个目标新建一个Kalman滤波器,逐一进行预测、更新、数据关联。其中如果数据关联失败的话,对于匹配失败的跟踪轨迹,在一定时间内,我们依旧允许其预测。
1 | # begin track |
值得注意的是其中的iou_blocking部分,这个模块使我们基于iou mask改进升级的,原本的iou是用来删除iou<0.3的关联边,现在我们可以放宽要求,将不在目标邻域的观测删除:
1 | def iou_blocking(tracks, dets, region_shape): |
Step4 我们将轨迹中有效长度较短的轨迹视为无效轨迹:
1 | # post processure |
上述过程呢,我们可以得到以下结果:
Detection | MOTA↑ | MOTP↑ | IDF1↑ | ID Sw.↓ |
---|---|---|---|---|
SDP | 0.675 | 0.203 | 0.518 | 201 |
可视化效果如下:
可以看到,在检测质量较好时,跟踪效果也还不错,以上的代码我都放在了https://github.com/nightmaredimple/libmot,
参考资源
[1]WOJKE N, BEWLEY A, PAULUS D. Simple online and realtime tracking with a deep association metric[C]. in: 2017 IEEE international conference on image processing (ICIP). IEEE, 2017. 3645-3649.