OpenCV入门教程03.27:kalman(卡尔曼)滤波
索引地址:系列索引
编程步骤
定义KalmanFilter类并初始化
- KalmanFilter KF(DP, MP, 0);构造KF对象,初始化相关参数
- KF.transitionMatrix 转移矩阵 A
- KF.measurementMatrix 测量矩阵 H
- KF.processNoiseCov 过程噪声 Q
- KF.measurementNoiseCov 测量噪声 R
- KF.errorCovPost 最小均方误差 P
- KF.statePost 系统初始状态 x(0)
- Mat measurement 定义初始测量值 z(0)
预测
- KF.predict();返回的是下一时刻的状态值KF.statePost (k+1)
更新
更新measurement; //注意measurement不能通过观测方程进行计算得到,要自己定义!
更新KF KF.correct(measurement)
最终的结果应该是更新后的statePost.
相关参数的确定
对于系统状态方程,简记为Y=AX+B,X和Y是表示系统状态的列向量,A是转移矩阵,B是其他项。
状态值(向量)只要能表示系统的状态即可,状态值的维数决定了转移矩阵A的维数,比如X和Y是N×1的,则A是N×N的。
A的确定跟X有关,只要保证方程中不相干项的系数为0即可,看下面例子
X和Y是二维的,
X和Y是三维的,
X和Y是三维的,但c和是相关项
上面的1也可以是其他值。
下面对predict( ) 和correct( )函数介绍下,可以不用看,不影响编程。
1 |
|
gemm( )是矩阵的广义乘法
1 |
|
$ dst = alpha · src1 · src2 +beta· src3 $
上面,oclMat()其实是,只不过默认为0,所以没赋值。整个过程就计算了x’和P’。(用x’代表x的预测值,用P’代表P的预测值)。GEMM_2_T表示对第2个参数转置。
如果B非空,
x’(k) = 1·B·u + 1·x’(k-1)
temp1 = 1·A·P(k-1) + 0·u(k)
P’(k) = 1· temp1·AT + 1· Qk= A·P(k-1)·AT + 1· Qk
可见,和第一部分的理论介绍完全一致。
1 |
|
1 |
|
求解线型最小二乘估计
temp2 = 1· H·P’ + 0·u(k)
temp3 = 1· temp2·HT + 1·R = H·P’·HT+ 1· R 也就是上面的Sk
temp = argmin||tem2- temp3||
K=temp
temp5 = -1· H·x’ + 1·zk 就是上面的y’。
x = 1·K·temp5 + 1·x’ = KT·y’ +x’
P =-1·K·temp2 + 1·P’ = -K·H·P’+P’ = (I- K·H) P’
也和第一部分的理论完全一致。
通过深入函数内部,学到了两个实用的函数哦。矩阵广义乘法gemm()、最小二乘估计solve()
测试代码:
1 |
|
效果: