卡尔曼滤波(Kalman filtering)小结

2024-06-03 22:38

本文主要是介绍卡尔曼滤波(Kalman filtering)小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近项目用到了kalman滤波,本博文简单介绍下卡尔曼滤波器的概念、原理和应用,做个小结。

概念

卡尔曼滤波(Kalman filtering)一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。

斯坦利·施密特(Stanley Schmidt)首次实现了卡尔曼滤波器。卡尔曼在NASA埃姆斯研究中心访问时,发现他的方法对于解决阿波罗计划的轨道预测很有用,后来阿波罗飞船的导航电脑使用了这种滤波器。 关于这种滤波器的论文由Swerling (1958), Kalman (1960)与 Kalman and Bucy (1961)发表[1]。

卡尔曼滤波的一个典型实例是从一组有限的,包含噪声的,对物体位置的观察序列(可能有偏差)预测出物体的位置的坐标及速度。在很多工程应用(如雷达、计算机视觉)中都可以找到它的身影。同时,卡尔曼滤波也是控制理论以及控制系统工程中的一个重要课题[2]。

应用

例如,对于雷达来说,人们感兴趣的是其能够跟踪目标。但目标的位置、速度、加速度的测量值往往在任何时候都有噪声。卡尔曼滤波利用目标的动态信息,设法去掉噪声的影响,得到一个关于目标位置的好的估计。这个估计可以是对当前目标位置的估计(滤波),也可以是对于将来位置的估计(预测),也可以是对过去位置的估计(插值或平滑)。
扩展卡尔曼滤波(EXTEND KALMAN FILTER, EKF)是由kalman filter考虑时间非线性的动态系统,常应用于目标跟踪系统。

kalman滤波器

理论上,kalman滤波器需要三个重要假设:
1)被建模的系统是线性的;
2)影响测量的噪声属于白噪声;
3)噪声本质上是高斯分布的。
第一条假设是指k时刻的系统状态可以用某个矩阵与k-1时刻的系统状态的乘积表示。余下两条假设,即噪声是高斯分布的白噪声,其含义为噪声与时间不相关,且只用均值和协方差就可以准确地为幅值建模。

在kalman滤波器滤波器应用中,一般考虑三种运动:
1)动态运动:这种运动是我们期望的前次测量时系统状态的直接结果,如匀速运动等。
2)控制运动:这种运动是我们期望的,由于某种已知的外部因素以某种原因施加于系统,如加速运动等。
3)随机运动:随机的无规则运动,在Kalman滤波器中,至少是可以用高斯模型有效地来建模。

以下是两个重要方程:
状态方程:

xk=Axk1+Buk1+qk1

观测方程:
yk=Hxk+rk

上两式子中,x(k)是k时刻的系统状态,u(k)是k时刻对系统的控制量。A是传输参数、B是控制参数,都是系统参数,对于多模型系统,他们为矩阵。y(k)是k时刻的测量值,H是测量系统的参数,对于多测量系统,H为状态转移矩阵。q(k)和r(k)分别表示状态和测量的噪声。他们被假设成高斯白噪声,他们的协方差分别是Q,R(这里我们假设他们不随系统状态变化而变化)。

KF算法流程如下图:
1
这里的K是kalman增益矩阵。

五个重要更新公式:
时间更新:

x^k=Ax^k1+Buk1 (1)

上标”-“表示“在新的测量之前”,求出先验估计 x^k ;
Pk=APk1AT+Q (2)

这个等式构成预测部分的基础,这告诉我们根据已看到的“我们可以期望什么”;
状态更新:
Kk=PkHT(HPkHT+R)1 (3)

这里给出所谓的Kalman增益或更新率或混合比例,告诉我们如何给定新信息相对已知信息的权重,在直接测量一个位置变量的一维例子中,状态误差是 σ2k1 ,测量误差是 σ2k K=σ2k1σ2k1+σ2k
x^k=x^k+Kk(ykHx^k) (4)

Pk=(IKkH)Pk (5)

得到“新的测量之后”,就可以用更新率K对 x^kPk 做更新得到最优的更新值 x^kPk

举例

以测量在停车场行驶的汽车为实际例子,汽车的状态用两个位置变量 x y,以及两个速度变量 vx vy 表示。这四个变量组成状态向量 xk 的元素。 dt 表示速度增量。这里假设的是动态运动模型。

xk=[x y vx vy]T

A=10000100dt0100dt01

当使用摄像机观测汽车的状态时,可能只观测量到位置变量:
yk=[yxyy]

状态转移矩阵H结构如下:

H=10000100

在该例子中,可能并不真正认为汽车速度不变,所以要设置 Q 来反应这个问题。对视频流用图像分析方法来测量汽车的位置,再根据对测量精确度的估计来选择R
这些量初始化完成后,嵌入到kalman滤波的那些公式中,便可以进行汽车位置估计。

在项目中,用kalman跟踪物体质心运动,建模思路跟这个汽车例子类似,因为运动不是匀速存在偏差(状态误差),因为检测器检测到的目标的质心的位置存在偏差(观测误差),而这些偏差和设定会影响到kalman的跟踪效果。

OpenCV demo

#include "opencv2/video/tracking.hpp"
#include "opencv2/highgui/highgui.hpp"#include <stdio.h>using namespace cv;static inline Point calcPoint(Point2f center, double R, double angle)
{return center + Point2f((float)cos(angle), (float)-sin(angle))*(float)R;
}static void help()
{printf( "\nExamle of c calls to OpenCV's Kalman filter.\n"
"   Tracking of rotating point.\n"
"   Rotation speed is constant.\n"
"   Both state and measurements vectors are 1D (a point angle),\n"
"   Measurement is the real point angle + gaussian noise.\n"
"   The real and the estimated points are connected with yellow line segment,\n"
"   the real and the measured points are connected with red line segment.\n"
"   (if Kalman filter works correctly,\n"
"    the yellow segment should be shorter than the red one).\n""\n"
"   Pressing any key (except ESC) will reset the tracking with a different speed.\n"
"   Pressing ESC will stop the program.\n");
}int main(int, char**)
{help();Mat img(500, 500, CV_8UC3);KalmanFilter KF(2, 1, 0);Mat state(2, 1, CV_32F); /* (phi, delta_phi) */Mat processNoise(2, 1, CV_32F);Mat measurement = Mat::zeros(1, 1, CV_32F);char code = (char)-1;for(;;){randn( state, Scalar::all(0), Scalar::all(0.1) );KF.transitionMatrix = *(Mat_<float>(2, 2) << 1, 1, 0, 1);setIdentity(KF.measurementMatrix);setIdentity(KF.processNoiseCov, Scalar::all(1e-5));setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));setIdentity(KF.errorCovPost, Scalar::all(1));randn(KF.statePost, Scalar::all(0), Scalar::all(0.1));for(;;){Point2f center(img.cols*0.5f, img.rows*0.5f);float R = img.cols/3.f;double stateAngle = state.at<float>(0);Point statePt = calcPoint(center, R, stateAngle);Mat prediction = KF.predict();double predictAngle = prediction.at<float>(0);Point predictPt = calcPoint(center, R, predictAngle);randn( measurement, Scalar::all(0), Scalar::all(KF.measurementNoiseCov.at<float>(0)));// generate measurementmeasurement += KF.measurementMatrix*state;double measAngle = measurement.at<float>(0);Point measPt = calcPoint(center, R, measAngle);// plot points#define drawCross( center, color, d )                                 \line( img, Point( center.x - d, center.y - d ),                \Point( center.x + d, center.y + d ), color, 1, CV_AA, 0); \line( img, Point( center.x + d, center.y - d ),                \Point( center.x - d, center.y + d ), color, 1, CV_AA, 0 )img = Scalar::all(0);drawCross( statePt, Scalar(255,255,255), 3 );drawCross( measPt, Scalar(0,0,255), 3 );drawCross( predictPt, Scalar(0,255,0), 3 );line( img, statePt, measPt, Scalar(0,0,255), 3, CV_AA, 0 );line( img, statePt, predictPt, Scalar(0,255,255), 3, CV_AA, 0 );if(theRNG().uniform(0,4) != 0)KF.correct(measurement);randn( processNoise, Scalar(0), Scalar::all(sqrt(KF.processNoiseCov.at<float>(0, 0))));state = KF.transitionMatrix*state + processNoise;imshow( "Kalman", img );code = (char)waitKey(100);if( code > 0 )break;}if( code == 27 || code == 'q' || code == 'Q' )break;}return 0;
}

运行效果:
2

3

4

<script type="math/tex; mode=display" id="MathJax-Element-26"></script>
个人觉得,Kalman filter算法的核心是新旧信息融合即将先验知识与观测数据结合得到新的估计,作用就是用来对系统状态进行 预估+ 校正

原文链接:http://blog.csdn.net/u011285477/article/details/52070900

参考资料:
[1]卡尔曼滤波-百度百科
[2]对Kalman(卡尔曼)滤波器的理解-CSDN博客
[3]Kalman滤波器从原理到实现-CSDN博客
[4]《学习OpenCV(中文版)》于仕琪、刘瑞祯 译 清华大学出版社 P384

这篇关于卡尔曼滤波(Kalman filtering)小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028314

相关文章

泛型和Integer小结

泛型在Java.util里面找:也可对其他你使用的函数进行查阅 如下:只要函数后面跟有尖括号<>,你都可以拿过来使用泛型     注意:用到集合时尽量使用泛型       int与Integer   integer这个不是关键字,是java的一个类。也就是int的包装类。int是基本数据类型,integer是引用类型,包含很多属性和方法,而int只是一个值,没有其他的任何

我的OS X系统使用小结

最近硬盘出现了故障,为了恢复确认问题,我的Windows电脑就一直运行坏道检测程序,暂时将工作迁移到我的MacBook Pro(后面简称为MBP)上进行。这里简单总结下自己是如何使用MBP进行做的。 原本计划是用我的小米游戏笔记本,但是不知为何,即便是非游戏模式,风扇偶尔也会狂转,产生很大的噪音。相反,MBP非常安静,就是有点烫手。 我的MBP是17年款,13寸屏幕,蝶式键盘。为了不烫手

风速预测 | 基于MATLAB的无迹卡尔曼滤波算法UKF、SVR-UKF、ANN-Kalman等时间序列风速预测模型

基本描述 基于MATLAB的无迹卡尔曼滤波算法UKF、SVR-UKF、ANN-Kalman等时间序列风速预测模型 模型步骤 时间序列风速预测模型基于MATLAB的无迹卡尔曼滤波算法(Unscented Kalman Filter, UKF)、SVR-UKF(Support Vector Regression - Unscented Kalman Filter)和ANN-Kalman(Arti

python装饰器小结

按照我自己的理解,python装饰器的作用就是让一些重复性的“操作”(代码)只出现一次就好,这样整个代码看起来会更清晰整洁,主要也减少了无谓的赋值粘贴。 例如,当前有两个方法get请求和post请求,在执行两个方法前,都要先检查一下请求的url是否符合要求,一般会这样写: # encoding=utf8import requestsclass Test():def __init__(self)

js创建对象的几种常用方式小结

最近在看javascript高级程序设计,其中对对象的创建做了具体的阐述,综合起来,总结了下(je知识库javascript专栏由这方面的教程,有兴趣的可以去知识库看看) 第一种模式:工厂方式 复制代码 代码如下: var lev=function(){ return "脚本之家"; }; function Parent(){ var Child = new

Java反射机制小结

一、概念定义 反射机制:反射提供了一种动态的功能,这种动态功能非常强大。它主要体现 在通过反射相关的API就可以知道一个陌生Java类的所有信息,包括属性、方法、构造器等。而且元素完全可以在运行时动态的进行创建或调用,而不必在JVM运行时就进行确定。即运行状态中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的

Java内部类的小结

内部类定义:一个外部类的内部再定义一个类,编译时的概念,一旦编译成功就与外围类属于两个完全不同的类。根据定义的结构的不同可以将内部类分成两种:成员式和局部式。然后成员式内部类又可以分为:静态内部类和成员内部类;局部式又可以分为:普通局部内部类和匿名内部类。具体介绍如下: (1)静态内部类(也称嵌套内部类):定义在另一个类里面的类,前面多了一个关键字static【1)它的创建不需要依赖外围类;

FLASH小结

FLASH小结 1.Flash概念叙述   - Flash是一种非易失性存储器(Non-volatile),也叫Flash EEPROM - Nor FLASH NOR FLASH芯片,不仅具有很强的可擦写次数,还具有完备的地址和数据总线,支持随机寻址,非常适合代替早期的ROM芯片(ROM、PROM、EEPROM),比如BIOS和机顶盒固件等,早期的可移动存储也使用NOR FLASH芯片,

STM32H750 QSPI FLASH使用小结

根据ST的参考手册描述,h750的片内flash只有128kb,在实际的项目应用中,128kb的容量有点太小了,有时候光光移植好lwip+freertos以后,flash的容量就所剩无几了,所幸可以使用QSPI FLASH来存放程序代码,可以把程序的部分或者整个程序都存放在QSPI FLASH中运行。这里介绍两种不同的方法。 一、通过分散加载文件的方式     本文中使用的是正点原子北

Swift Combine — Operators(常用Filtering类操作符介绍)

目录 filter(_: )tryFilter(_: )compactMap(_: )tryCompactMap(_: )removeDuplicates()first(where:)last(where:) Combine中对 Publisher的值进行操作的方法称为 Operator(操作符)。 Combine中的 Operator通常会生成一个 Publisher,