卡尔曼滤波简介+ 算法实现代码(C/C++)(转)
2010-07-14 22:04
316 查看
原帖地址:/article/4931121.html
最佳线性滤波理论起源于
40
年代美国科学家
Wiener
和前苏联科学家K
олмогоров
等人的研究工作,后人统称为维纳滤波理论。从理论上说,维纳滤波的最大缺点是必须用到无限过去的数据,不适用于实时处理。为了克服这一缺点,
60
年代
Kalman
把
状态空间模型引入滤波理论,并导出了一套递推估计算法,后人称之为卡尔曼滤波理论。卡尔曼滤波是以最小均方误差为估计的最佳准则,来寻求一套递推估计的算
法,其基本思想是:采用信号与噪声的状态空间模型,利用前一时刻地估计值和现时刻的观测值来更新对状态变量的估计,求出现时刻的估计值。它适合于实时处理
和计算机运算。
现设线性时变系统的离散状态防城和观测方程为:
X(k) = F(k,k-1)·X(k-1)+T(k,k-1)·U(k-1)
Y(k) = H(k)·X(k)+N(k)
其中
X(k)和Y(k)分别是k时刻的状态矢量和观测矢量
F(k,k-1)为状态转移矩阵
U(k)为k时刻动态噪声
T(k,k-1)为系统控制矩阵
H(k)为k时刻观测矩阵
N(k)为k时刻观测噪声
则卡尔曼滤波的算法流程为:
预估计X(k)^= F(k,k-1)·X(k-1)
计算预估计协方差矩阵
C(k)^=F(k,k-1)×C(k)×F(k,k-1)'+T(k,k-1)×Q(k)×T(k,k-1)'
Q(k) = U(k)×U(k)'
计算卡尔曼增益矩阵
K(k) = C(k)^×H(k)'×[H(k)×C(k)^×H(k)'+R(k)]^(-1)
R(k) = N(k)×N(k)'
更新估计
X(k)~=X(k)^+K(k)×[Y(k)-H(k)×X(k)^]
计算更新后估计协防差矩阵
C(k)~ = [I-K(k)×H(k)]×C(k)^×[I-K(k)×H(k)]'+K(k)×R(k)×K(k)'
X(k+1) = X(k)~
C(k+1) = C(k)~
重复以上步骤
其c语言实现代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include
"
stdlib.h
"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include
"
rinv.c
"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int
lman(n,m,k,f,q,r,h,y,x,p,g)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int
n,m,k;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
double
f[],q[],r[],h[],y[],x[],p[],g[];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
int
i,j,kk,ii,l,jj,js;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
double
*
e,
*
a,
*
b;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e
=
malloc(m
*
m
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
l
=
m;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(l
<
n) l
=
n;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a
=
malloc(l
*
l
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b
=
malloc(l
*
l
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ ii
=
i
*
l
+
j; a[ii]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[ii]
=
a[ii]
+
p[i
*
n
+
kk]
*
f[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ ii
=
i
*
n
+
j; p[ii]
=
q[ii];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
p[ii]
=
p[ii]
+
f[i
*
n
+
kk]
*
a[kk
*
l
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(ii
=
2
; ii
<=
k; ii
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
+
p[i
*
n
+
kk]
*
h[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
m
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
m
+
j; e[jj]
=
r[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e[jj]
=
e[jj]
+
h[i
*
n
+
kk]
*
a[kk
*
l
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
js
=
rinv(e,m);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(js
==
0
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ free(e); free(a); free(b);
return
(js);}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
m
+
j; g[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
m
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
g[jj]
=
g[jj]
+
a[i
*
l
+
kk]
*
e[j
*
m
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
(ii
-
1
)
*
n
+
i; x[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
x[jj]
=
x[jj]
+
f[i
*
n
+
j]
*
x[(ii
-
2
)
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
m
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l; b[jj]
=
y[(ii
-
1
)
*
m
+
i];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b[jj]
=
b[jj]
-
h[i
*
n
+
j]
*
x[(ii
-
1
)
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
(ii
-
1
)
*
n
+
i;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
x[jj]
=
x[jj]
+
g[i
*
m
+
j]
*
b[j
*
l];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(ii
<
k)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
m
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
-
g[i
*
m
+
kk]
*
h[kk
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(i
==
j) a[jj]
=
1.0
+
a[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; b[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b[jj]
=
b[jj]
+
a[i
*
l
+
kk]
*
p[kk
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
+
b[i
*
l
+
kk]
*
f[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
n
+
j; p[jj]
=
q[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
p[jj]
=
p[jj]
+
f[i
*
n
+
kk]
*
a[j
*
l
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
free(e); free(a); free(b);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return
(js);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
C++实现代码如下:
============================
kalman.h
================================
//
kalman.h: interface for the kalman class.
//
/////////////////////////////////////////////////////////////////////
/
#if
!defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_)
#define
AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_
#if
_MSC_VER > 1000
#pragma once
#endif
//
_MSC_VER > 1000
#include
<
math.h
>
#include
"
cv.h
"
class
kalman
{
public
:
void
init_kalman(
int
x,
int
xv,
int
y,
int
yv);
CvKalman
*
cvkalman;
CvMat
*
state;
CvMat
*
process_noise;
CvMat
*
measurement;
const
CvMat
*
prediction;
CvPoint2D32f get_predict(
float
x,
float
y);
kalman(
int
x
=
0
,
int
xv
=
0
,
int
y
=
0
,
int
yv
=
0
);
//
virtual ~kalman();
};
#endif
//
!defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_)
============================
kalman.cpp
================================
#include
"
kalman.h
"
#include
<
stdio.h
>
/*
tester de printer toutes les valeurs des vecteurs
![](http://www.cnblogs.com/Images/dot.gif)
*/
/*
tester de changer les matrices du noises
*/
/*
replace state by cvkalman->state_post ???
*/
CvRandState rng;
const
double
T
=
0.1
;
kalman::kalman(
int
x,
int
xv,
int
y,
int
yv)
{
cvkalman
=
cvCreateKalman(
4
,
4
,
0
);
state
=
cvCreateMat(
4
,
1
, CV_32FC1 );
process_noise
=
cvCreateMat(
4
,
1
, CV_32FC1 );
measurement
=
cvCreateMat(
4
,
1
, CV_32FC1 );
int
code
=
-
1
;
/*
create matrix data
*/
const
float
A[]
=
{
1
, T,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
, T,
0
,
0
,
0
,
1
};
const
float
H[]
=
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
};
const
float
P[]
=
{
pow(
320
,
2
), pow(
320
,
2
)
/
T,
0
,
0
,
pow(
320
,
2
)
/
T, pow(
320
,
2
)
/
pow(T,
2
),
0
,
0
,
0
,
0
, pow(
240
,
2
), pow(
240
,
2
)
/
T,
0
,
0
, pow(
240
,
2
)
/
T, pow(
240
,
2
)
/
pow(T,
2
)
};
const
float
Q[]
=
{
pow(T,
3
)
/
3
, pow(T,
2
)
/
2
,
0
,
0
,
pow(T,
2
)
/
2
, T,
0
,
0
,
0
,
0
, pow(T,
3
)
/
3
, pow(T,
2
)
/
2
,
0
,
0
, pow(T,
2
)
/
2
, T
};
const
float
R[]
=
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
};
cvRandInit(
&
rng,
0
,
1
,
-
1
, CV_RAND_UNI );
cvZero( measurement );
cvRandSetRange(
&
rng,
0
,
0.1
,
0
);
rng.disttype
=
CV_RAND_NORMAL;
cvRand(
&
rng, state );
memcpy( cvkalman
->
transition_matrix
->
data.fl, A,
sizeof
(A));
memcpy( cvkalman
->
measurement_matrix
->
data.fl, H,
sizeof
(H));
memcpy( cvkalman
->
process_noise_cov
->
data.fl, Q,
sizeof
(Q));
memcpy( cvkalman
->
error_cov_post
->
data.fl, P,
sizeof
(P));
memcpy( cvkalman
->
measurement_noise_cov
->
data.fl, R,
sizeof
(R));
//
cvSetIdentity( cvkalman->process_noise_cov, cvRealScalar(1e-5) );
//
cvSetIdentity( cvkalman->error_cov_post, cvRealScalar(1));
//
cvSetIdentity( cvkalman->measurement_noise_cov, cvRealScalar(1e-1) );
/*
choose initial state
*/
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
1
]
=
xv;
state
->
data.fl[
2
]
=
y;
state
->
data.fl[
3
]
=
yv;
cvkalman
->
state_post
->
data.fl[
0
]
=
x;
cvkalman
->
state_post
->
data.fl[
1
]
=
xv;
cvkalman
->
state_post
->
data.fl[
2
]
=
y;
cvkalman
->
state_post
->
data.fl[
3
]
=
yv;
cvRandSetRange(
&
rng,
0
, sqrt(cvkalman
->
process_noise_cov
->
data.fl[
0
]),
0
);
cvRand(
&
rng, process_noise );
}
CvPoint2D32f kalman::get_predict(
float
x,
float
y){
/*
update state with current position
*/
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
2
]
=
y;
/*
predict point position
*/
/*
x'k=A鈥k+B鈥k
P'k=A鈥k-1*AT + Q
*/
cvRandSetRange(
&
rng,
0
, sqrt(cvkalman
->
measurement_noise_cov
->
data.fl[
0
]),
0
);
cvRand(
&
rng, measurement );
/*
xk=A?xk-1+B?uk+wk
*/
cvMatMulAdd( cvkalman
->
transition_matrix, state, process_noise, cvkalman
->
state_post );
/*
zk=H?xk+vk
*/
cvMatMulAdd( cvkalman
->
measurement_matrix, cvkalman
->
state_post, measurement, measurement );
/*
adjust Kalman filter state
*/
/*
Kk=P'k鈥T鈥?H鈥'k鈥T+R)-1
xk=x'k+Kk鈥?zk-H鈥'k)
Pk=(I-Kk鈥)鈥'k
*/
cvKalmanCorrect( cvkalman, measurement );
float
measured_value_x
=
measurement
->
data.fl[
0
];
float
measured_value_y
=
measurement
->
data.fl[
2
];
const
CvMat
*
prediction
=
cvKalmanPredict( cvkalman,
0
);
float
predict_value_x
=
prediction
->
data.fl[
0
];
float
predict_value_y
=
prediction
->
data.fl[
2
];
return
(cvPoint2D32f(predict_value_x,predict_value_y));
}
void
kalman::init_kalman(
int
x,
int
xv,
int
y,
int
yv)
{
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
1
]
=
xv;
state
->
data.fl[
2
]
=
y;
state
->
data.fl[
3
]
=
yv;
cvkalman
->
state_post
->
data.fl[
0
]
=
x;
cvkalman
->
state_post
->
data.fl[
1
]
=
xv;
cvkalman
->
state_post
->
data.fl[
2
]
=
y;
cvkalman
->
state_post
->
data.fl[
3
]
=
yv;
}
最佳线性滤波理论起源于
40
年代美国科学家
Wiener
和前苏联科学家K
олмогоров
等人的研究工作,后人统称为维纳滤波理论。从理论上说,维纳滤波的最大缺点是必须用到无限过去的数据,不适用于实时处理。为了克服这一缺点,
60
年代
Kalman
把
状态空间模型引入滤波理论,并导出了一套递推估计算法,后人称之为卡尔曼滤波理论。卡尔曼滤波是以最小均方误差为估计的最佳准则,来寻求一套递推估计的算
法,其基本思想是:采用信号与噪声的状态空间模型,利用前一时刻地估计值和现时刻的观测值来更新对状态变量的估计,求出现时刻的估计值。它适合于实时处理
和计算机运算。
现设线性时变系统的离散状态防城和观测方程为:
X(k) = F(k,k-1)·X(k-1)+T(k,k-1)·U(k-1)
Y(k) = H(k)·X(k)+N(k)
其中
X(k)和Y(k)分别是k时刻的状态矢量和观测矢量
F(k,k-1)为状态转移矩阵
U(k)为k时刻动态噪声
T(k,k-1)为系统控制矩阵
H(k)为k时刻观测矩阵
N(k)为k时刻观测噪声
则卡尔曼滤波的算法流程为:
预估计X(k)^= F(k,k-1)·X(k-1)
计算预估计协方差矩阵
C(k)^=F(k,k-1)×C(k)×F(k,k-1)'+T(k,k-1)×Q(k)×T(k,k-1)'
Q(k) = U(k)×U(k)'
计算卡尔曼增益矩阵
K(k) = C(k)^×H(k)'×[H(k)×C(k)^×H(k)'+R(k)]^(-1)
R(k) = N(k)×N(k)'
更新估计
X(k)~=X(k)^+K(k)×[Y(k)-H(k)×X(k)^]
计算更新后估计协防差矩阵
C(k)~ = [I-K(k)×H(k)]×C(k)^×[I-K(k)×H(k)]'+K(k)×R(k)×K(k)'
X(k+1) = X(k)~
C(k+1) = C(k)~
重复以上步骤
其c语言实现代码如下:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include
"
stdlib.h
"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include
"
rinv.c
"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int
lman(n,m,k,f,q,r,h,y,x,p,g)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int
n,m,k;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
double
f[],q[],r[],h[],y[],x[],p[],g[];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
int
i,j,kk,ii,l,jj,js;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
double
*
e,
*
a,
*
b;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e
=
malloc(m
*
m
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
l
=
m;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(l
<
n) l
=
n;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a
=
malloc(l
*
l
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b
=
malloc(l
*
l
*
sizeof
(
double
));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ ii
=
i
*
l
+
j; a[ii]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[ii]
=
a[ii]
+
p[i
*
n
+
kk]
*
f[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ ii
=
i
*
n
+
j; p[ii]
=
q[ii];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
p[ii]
=
p[ii]
+
f[i
*
n
+
kk]
*
a[kk
*
l
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(ii
=
2
; ii
<=
k; ii
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
+
p[i
*
n
+
kk]
*
h[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
m
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
m
+
j; e[jj]
=
r[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e[jj]
=
e[jj]
+
h[i
*
n
+
kk]
*
a[kk
*
l
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
js
=
rinv(e,m);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(js
==
0
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ free(e); free(a); free(b);
return
(js);}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
m
+
j; g[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
m
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
g[jj]
=
g[jj]
+
a[i
*
l
+
kk]
*
e[j
*
m
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
(ii
-
1
)
*
n
+
i; x[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
x[jj]
=
x[jj]
+
f[i
*
n
+
j]
*
x[(ii
-
2
)
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
m
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l; b[jj]
=
y[(ii
-
1
)
*
m
+
i];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b[jj]
=
b[jj]
-
h[i
*
n
+
j]
*
x[(ii
-
1
)
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
(ii
-
1
)
*
n
+
i;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
m
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
x[jj]
=
x[jj]
+
g[i
*
m
+
j]
*
b[j
*
l];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(ii
<
k)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
m
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
-
g[i
*
m
+
kk]
*
h[kk
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if
(i
==
j) a[jj]
=
1.0
+
a[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; b[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
b[jj]
=
b[jj]
+
a[i
*
l
+
kk]
*
p[kk
*
n
+
j];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
l
+
j; a[jj]
=
0.0
;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
a[jj]
=
a[jj]
+
b[i
*
l
+
kk]
*
f[j
*
n
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(i
=
0
; i
<=
n
-
1
; i
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(j
=
0
; j
<=
n
-
1
; j
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{ jj
=
i
*
n
+
j; p[jj]
=
q[jj];
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for
(kk
=
0
; kk
<=
n
-
1
; kk
++
)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
p[jj]
=
p[jj]
+
f[i
*
n
+
kk]
*
a[j
*
l
+
kk];
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
free(e); free(a); free(b);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return
(js);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
C++实现代码如下:
============================
kalman.h
================================
//
kalman.h: interface for the kalman class.
//
/////////////////////////////////////////////////////////////////////
/
#if
!defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_)
#define
AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_
#if
_MSC_VER > 1000
#pragma once
#endif
//
_MSC_VER > 1000
#include
<
math.h
>
#include
"
cv.h
"
class
kalman
{
public
:
void
init_kalman(
int
x,
int
xv,
int
y,
int
yv);
CvKalman
*
cvkalman;
CvMat
*
state;
CvMat
*
process_noise;
CvMat
*
measurement;
const
CvMat
*
prediction;
CvPoint2D32f get_predict(
float
x,
float
y);
kalman(
int
x
=
0
,
int
xv
=
0
,
int
y
=
0
,
int
yv
=
0
);
//
virtual ~kalman();
};
#endif
//
!defined(AFX_KALMAN_H__ED3D740F_01D2_4616_8B74_8BF57636F2C0__INCLUDED_)
============================
kalman.cpp
================================
#include
"
kalman.h
"
#include
<
stdio.h
>
/*
tester de printer toutes les valeurs des vecteurs
![](http://www.cnblogs.com/Images/dot.gif)
*/
/*
tester de changer les matrices du noises
*/
/*
replace state by cvkalman->state_post ???
*/
CvRandState rng;
const
double
T
=
0.1
;
kalman::kalman(
int
x,
int
xv,
int
y,
int
yv)
{
cvkalman
=
cvCreateKalman(
4
,
4
,
0
);
state
=
cvCreateMat(
4
,
1
, CV_32FC1 );
process_noise
=
cvCreateMat(
4
,
1
, CV_32FC1 );
measurement
=
cvCreateMat(
4
,
1
, CV_32FC1 );
int
code
=
-
1
;
/*
create matrix data
*/
const
float
A[]
=
{
1
, T,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
1
, T,
0
,
0
,
0
,
1
};
const
float
H[]
=
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
};
const
float
P[]
=
{
pow(
320
,
2
), pow(
320
,
2
)
/
T,
0
,
0
,
pow(
320
,
2
)
/
T, pow(
320
,
2
)
/
pow(T,
2
),
0
,
0
,
0
,
0
, pow(
240
,
2
), pow(
240
,
2
)
/
T,
0
,
0
, pow(
240
,
2
)
/
T, pow(
240
,
2
)
/
pow(T,
2
)
};
const
float
Q[]
=
{
pow(T,
3
)
/
3
, pow(T,
2
)
/
2
,
0
,
0
,
pow(T,
2
)
/
2
, T,
0
,
0
,
0
,
0
, pow(T,
3
)
/
3
, pow(T,
2
)
/
2
,
0
,
0
, pow(T,
2
)
/
2
, T
};
const
float
R[]
=
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
};
cvRandInit(
&
rng,
0
,
1
,
-
1
, CV_RAND_UNI );
cvZero( measurement );
cvRandSetRange(
&
rng,
0
,
0.1
,
0
);
rng.disttype
=
CV_RAND_NORMAL;
cvRand(
&
rng, state );
memcpy( cvkalman
->
transition_matrix
->
data.fl, A,
sizeof
(A));
memcpy( cvkalman
->
measurement_matrix
->
data.fl, H,
sizeof
(H));
memcpy( cvkalman
->
process_noise_cov
->
data.fl, Q,
sizeof
(Q));
memcpy( cvkalman
->
error_cov_post
->
data.fl, P,
sizeof
(P));
memcpy( cvkalman
->
measurement_noise_cov
->
data.fl, R,
sizeof
(R));
//
cvSetIdentity( cvkalman->process_noise_cov, cvRealScalar(1e-5) );
//
cvSetIdentity( cvkalman->error_cov_post, cvRealScalar(1));
//
cvSetIdentity( cvkalman->measurement_noise_cov, cvRealScalar(1e-1) );
/*
choose initial state
*/
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
1
]
=
xv;
state
->
data.fl[
2
]
=
y;
state
->
data.fl[
3
]
=
yv;
cvkalman
->
state_post
->
data.fl[
0
]
=
x;
cvkalman
->
state_post
->
data.fl[
1
]
=
xv;
cvkalman
->
state_post
->
data.fl[
2
]
=
y;
cvkalman
->
state_post
->
data.fl[
3
]
=
yv;
cvRandSetRange(
&
rng,
0
, sqrt(cvkalman
->
process_noise_cov
->
data.fl[
0
]),
0
);
cvRand(
&
rng, process_noise );
}
CvPoint2D32f kalman::get_predict(
float
x,
float
y){
/*
update state with current position
*/
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
2
]
=
y;
/*
predict point position
*/
/*
x'k=A鈥k+B鈥k
P'k=A鈥k-1*AT + Q
*/
cvRandSetRange(
&
rng,
0
, sqrt(cvkalman
->
measurement_noise_cov
->
data.fl[
0
]),
0
);
cvRand(
&
rng, measurement );
/*
xk=A?xk-1+B?uk+wk
*/
cvMatMulAdd( cvkalman
->
transition_matrix, state, process_noise, cvkalman
->
state_post );
/*
zk=H?xk+vk
*/
cvMatMulAdd( cvkalman
->
measurement_matrix, cvkalman
->
state_post, measurement, measurement );
/*
adjust Kalman filter state
*/
/*
Kk=P'k鈥T鈥?H鈥'k鈥T+R)-1
xk=x'k+Kk鈥?zk-H鈥'k)
Pk=(I-Kk鈥)鈥'k
*/
cvKalmanCorrect( cvkalman, measurement );
float
measured_value_x
=
measurement
->
data.fl[
0
];
float
measured_value_y
=
measurement
->
data.fl[
2
];
const
CvMat
*
prediction
=
cvKalmanPredict( cvkalman,
0
);
float
predict_value_x
=
prediction
->
data.fl[
0
];
float
predict_value_y
=
prediction
->
data.fl[
2
];
return
(cvPoint2D32f(predict_value_x,predict_value_y));
}
void
kalman::init_kalman(
int
x,
int
xv,
int
y,
int
yv)
{
state
->
data.fl[
0
]
=
x;
state
->
data.fl[
1
]
=
xv;
state
->
data.fl[
2
]
=
y;
state
->
data.fl[
3
]
=
yv;
cvkalman
->
state_post
->
data.fl[
0
]
=
x;
cvkalman
->
state_post
->
data.fl[
1
]
=
xv;
cvkalman
->
state_post
->
data.fl[
2
]
=
y;
cvkalman
->
state_post
->
data.fl[
3
]
=
yv;
}
相关文章推荐
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码(转)
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 详解Java实现负载均衡的几种算法代码
- 【高级算法】Lasvegas算法解决3SAT问题(C++实现代码)
- Tarjan 算法的伪代码实现 及 求割点的思路浅谈
- 求旋转数组的最小数字算法的解析以及完整c语言代码实现
- 二叉堆建堆的优化算法原理图解及代码实现
- 区域生长算法(附MATLAB代码实现)
- 哈希表及其常用算法(代码实现)
- 希尔算法代码实现
- 图像去雾之何凯明暗通道先验去雾算法原理及c++代码实现
- 关于FIR设计的切比雪夫最佳逼近法的算法流程和代码实现
- 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果。
- C++ 基本算法 冒泡法、交换法、选择法、实现代码集合