4. 经典跟踪算法(二):卡尔曼滤波(Kalman Filter)原理、状态预测与更新、在目标跟踪中的应用
说到目标跟踪,卡尔曼滤波绝对是个绕不开的经典。我刚开始做跟踪项目时,总觉得这玩意儿数学公式太多,看着就头疼。后来真正上手调参,才发现它其实特别优雅——说白了,就是一套「猜 + 修」的循环。
你想想看,我们跟踪一个目标,比如一辆车。下一帧它会出现在哪里?我们当然可以猜。但猜得准不准,得看我们的模型好不好,以及测量噪声大不大。卡尔曼滤波干的事,就是把这个「猜」的过程数学化,然后用测量值去修正它。
4.1 卡尔曼滤波的两大核心步骤
卡尔曼滤波其实就两个阶段:预测(Predict) 和 更新(Update)。我习惯叫它「先猜后修」。
4.1.1 状态预测(Predict)
这一步,我们根据目标的运动模型,从上一帧的状态推出当前帧的状态。假设目标做匀速运动,那位置和速度就是我们的状态量。
数学上长这样:
x_k = F * x_{k-1} + B * u_k + w_k
P_k = F * P_{k-1} * F^T + Q
解释一下:
- x_k:当前帧的状态(位置、速度等)
- F:状态转移矩阵,描述目标怎么从上一帧运动到这一帧
- B * u_k:控制输入,比如我们知道目标在加速
- w_k:过程噪声,代表模型的不确定性
- P_k:状态协方差矩阵,代表我们对当前状态估计的置信度
- Q:过程噪声协方差矩阵
4.1.2 状态更新(Update)
预测完了,我们得拿实际观测值来修正。比如检测器返回了目标在当前帧的坐标。
K_k = P_k * H^T * (H * P_k * H^T + R)^{-1}
x_k = x_k + K_k * (z_k - H * x_k)
P_k = (I - K_k * H) * P_k
这里:
- K_k:卡尔曼增益,决定我们更相信预测还是观测
- H:观测矩阵,把状态空间映射到观测空间
- z_k:实际观测值
- R:观测噪声协方差矩阵
卡尔曼增益 K 很有意思。当观测噪声 R 很小时,K 会变大,我们更相信观测值;当过程噪声 Q 很小时,K 会变小,我们更相信预测值。说白了,这就是个「谁靠谱听谁的」机制。
4.2 在目标跟踪中的应用
卡尔曼滤波在目标跟踪里,最常见的用法就是平滑轨迹和预测遮挡后的位置。
我举个例子。假设我们跟踪一辆车,检测器每帧返回它的中心坐标 (x, y)。我们定义状态向量为 [x, y, vx, vy],即位置和速度。状态转移矩阵 F 就是匀速运动模型:
F = [[1, 0, dt, 0],
[0, 1, 0, dt],
[0, 0, 1, 0],
[0, 0, 0, 1]]
观测矩阵 H 只提取位置:
H = [[1, 0, 0, 0],
[0, 1, 0, 0]]
这样,每一帧我们都能得到平滑后的位置,还能预测下一帧的位置。如果目标被遮挡了,检测器返回空值,我们就直接用预测值顶上去,直到目标重新出现。
4.3 卡尔曼滤波的局限性
卡尔曼滤波不是万能的。它假设系统是线性的,噪声是高斯分布。如果目标做非线性运动(比如急转弯),或者噪声不是高斯分布,效果就会打折扣。
这时候,我会考虑扩展卡尔曼滤波(EKF)或无迹卡尔曼滤波(UKF)。不过那是另一个话题了,今天先不展开。
4.4 知识体系图
下面这张图,是我自己梳理的卡尔曼滤波在目标跟踪中的知识结构,方便你理解整体脉络:
嗯,这张图基本把卡尔曼滤波在跟踪中的流程说清楚了。从预测到更新,再到下一帧循环,核心就是那两个公式和两个参数 Q、R。调参的时候别急,一点点试,你会找到感觉的。