Kalman Filter(卡尔曼滤波)的个人笔记以及程序实现 - 小胖蛋

yangyangxin 2021-08-04 原文


Kalman Filter(卡尔曼滤波)的个人笔记以及程序实现

简单的介绍一下卡尔曼滤波器的关键的5个公式。

引入一个离散控制过程的系统。该系统可用一个线性随机微分方程来描述:

  X(k)=A X(k-1)+B U(k)+W(k)

  再加上系统的测量值:

  Z(k)=H X(k)+V(k)

上两式子中,X(k)是k时刻的系统状态,U(k)是k时刻对系统的控制量。A和B是系统参数,对于多模型系统,他们为矩阵。Z(k)是k时刻的测量值,H是测量系统的参数,对于多测量系统,H为矩阵。W(k)和V(k)分别表示过程和测量的噪声。他们被假设成高斯白噪声,他们的协方差(covariance )分别是Q,R(这里我们假设他们不随系统状态变化而变化)

首先利用系统的过程模型来预测系统下一状态,设在k时刻的系统状态为x(k),则可以根据系统模型,由上一状态预测出现在状态:

x(k|k-1) = A x(k-1|k-1) + B u(k)…..(1)

其中x(k|k-1)是上一时刻的状态对现在时刻状态的预测,x(k-1|k-1)是上一时刻状态的最优结果, u(k)为现在时刻状态的控制量。

系统的状态已经更新,现在需要更新系统的误差估计协方差矩阵,用p(k|k-1)表示误差估计协方差矩阵:

p(k|k-1) = A p(k-1|k-1)A\’ + Q……..(2)

其中p(k|k-1)是在k时刻由上一状态对此状态的预测, p(k-1|k-1)是x(k-1|k-1)对应的误差估计协方差矩阵,A\’ 是A 的转置。Q 表示系统过程噪声的covariance。

现在我们得到了预测结果,然后我们根据得到的现在状态的测量值进行更新(修正)(预测得到的)现在的状态 x(k|k):

x(k|k) = x(k|k-1) + Kg(k) (Z(k)-Hx(k|k-1))….(3)

(3)式中 Kg(k)未知,则需要对其就行求解,就引出(4)式:

 Kg(k) = p(k|k-1) H\’ /(H p(k|k-1)H\’ + R)…(4)

到现在,我们以及得出的k 时刻的系统状态的最优值x(k|k),为了让卡尔曼滤波器不断地进行下去,我们需要更新 x(k|k) 对应的p(k|k) (应用于式(2)):

p(k|k) = (I-Kg(k) H) p(k|k-1)…..(5)

 

卡尔曼滤波实现的小程序:opencv+ C++

  1 #include "opencv2/video/tracking.hpp"
  2 #include "opencv2/highgui/highgui.hpp"
  3 #include <cmath>  
  4 #include <vector>
  5 #include <stdio.h>
  6 #include <iostream>
  7 
  8 using namespace cv;
  9 using namespace std;
 10 const int winHeight=600;  
 11 const int winWidth=800;
 12 
 13 Point move_mouse = Point(winWidth>>1,winHeight>>1);
 14 //mouse event callback  
 15 
 16 void mouseEvent(int event, int x, int y, int flags, void *param )
 17 {
 18     if (event==CV_EVENT_MOUSEMOVE)
 19     {  
 20         move_mouse=Point(x,y);  
 21     } 
 22 }
 23 
 24 
 25 int main()
 26 {
 27     
 28     ////1.kalman filter setup
 29 
 30     const int stateNum=4;  
 31     const int measureNum=2;
 32 
 33     KalmanFilter kalman(stateNum,measureNum,0);
 34     Mat processNoise(stateNum,1,CV_32F);
 35     Mat measureNoise(stateNum,1,CV_32F);
 36     Mat measurement (measureNum,1,CV_32F);
 37     float A[stateNum][stateNum] ={//transition matrix  
 38         1,0,1,0,  
 39         0,1,0,1,  
 40         0,0,1,0,  
 41         0,0,0,1  
 42     };  
 43 
 48     memcpy( kalman.transitionMatrix.data,A,sizeof(A));
 49     cout<<kalman.transitionMatrix<<endl;
 50     setIdentity(kalman.measurementMatrix);
 51     setIdentity(kalman.processNoiseCov,Scalar::all(1e-5));
 52     setIdentity(kalman.measurementNoiseCov,Scalar::all(1e-1));
 53     setIdentity(kalman.errorCovPost,Scalar::all(1));
 54 
 55     //initialize post state of kalman filter at random 
 56     randn(kalman.statePost,Scalar::all(0), Scalar::all(0.1));
 57     CvFont font;  
 58     cvInitFont(&font,CV_FONT_HERSHEY_SCRIPT_COMPLEX,1,1);  
 59 
 60    
 62     namedWindow("kalman",1);
 63     setMouseCallback("kalman",mouseEvent);
 64     
 65     Mat img(500, 500, CV_8UC3);
 66     while (1)
 67     {
 68         //2.kalman prediction
 69         Mat prediction = kalman.predict();
 70         Point predict_pt = Point(prediction.at<float>(0),prediction.at<float>(1));
 71  
 72        //3.update measurement 
 73 
 74         measurement.at<float>(0) = (float)move_mouse.x;
 75         measurement.at<float>(1) = (float)move_mouse.y;
 76 
 77         //4.update
 78         kalman.correct(measurement);
 79 
 80 
 81         //5.draw
 82 
 84         img = Scalar::all(0);
 85         circle(img,predict_pt,4,CV_RGB(0,255,0),2);//predicted point with green 
 86         circle(img,move_mouse,4,CV_RGB(255,0,0),2);//current position with red
 87      
 93     imshow("kalman", img);  
 94         int key=cvWaitKey(3);  
 95         if (key==27)
 96         {
 97             break;    
 98         }
 99     }
101     system("pause");
102     return 0;
103 }

程序说明:

本程序由http://blog.sina.com.cn/s/blog_9db9f81901015wuo.html 稍作修改适应新版本的opencv。

程序主要由以下几个部分:

1.实例化一个 KalmanFilter 的对象kalman,声明并初始化矩阵processNoise,measureNoise, measurement ;

注意:要设置的变量主要是KalmanFilter的成员,否则会出现跟踪效果不好或者出错

Mat statePre;    //!< predicted state (x\'(k)): x(k)=A*x(k-1)+B*u(k)
Mat statePost;    //!< corrected state (x(k)): x(k)=x\'(k)+K(k)*(z(k)-H*x\'(k))
Mat transitionMatrix;    //!< state transition matrix (A)
Mat controlMatrix;    //!< control matrix (B) (not used if there is no control) 
Mat measurementMatrix;    //!< measurement matrix (H)
Mat processNoiseCov;   //!< process noise covariance matrix (Q)
Mat measurementNoiseCov;  //!< measurement noise covariance matrix (R)
Mat errorCovPre;   //!< priori error estimate covariance matrix (P\'(k)): P\'(k)=A*P(k-1)*At + Q)*/
Mat gain;  //!< Kalman gain matrix (K(k)): K(k)=P\'(k)*Ht*inv(H*P\'(k)*Ht+R)
Mat errorCovPost;    //!< posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P\'(k)

2.预测KalmanPredict,只需要调用函数 predict() ,然后读出自己需要的值

3.根据采集到的数据更新观测数据

4.用观测数据来更新预测状态值。

 

 

参考资料:http://blog.sina.com.cn/s/blog_4c2b25550100b8yq.html

http://blog.csdn.net/yangtrees/article/details/8075911#comments 学习OpenCV——Kalman滤波

发表于
2016-08-24 17:38 
小胖蛋 
阅读(9246
评论(0
编辑 
收藏 
举报

 

版权声明:本文为yangyangxin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yangyangxin/p/5803965.html

Kalman Filter(卡尔曼滤波)的个人笔记以及程序实现 - 小胖蛋的更多相关文章

  1. 简要说明一下offsetWidth的替换 – 愚小子

    简要说明一下offsetWidth的替换    前面几个例子中用到了offsetWidth这个属性,其实还有o […]...

  2. 从零开始部署小型企业级虚拟桌面 — Vmware Horizon View 6 For Linux VDI — 概念简介

    什么是桌面虚拟化? 桌面虚拟化有很多概念,此处谈论的,是指的一般企业使用的“服务器 + 虚拟机 + 云终端”的 […]...

  3. Java 语法 索引 —– 抽象类(Abstract)

    abstract class Shape { public int x = 100, y = 100; pub […]...

  4. windows下《Go Web编程》之Go开发工具 – 落叶虽美只活一世Live2D

    windows下《Go Web编程》之Go开发工具   Go开发工具很多,比较喜欢的使用作者列出的第一个工具, […]...

  5. Solr使用初探——Solr的安装环境与配置 – 静以修身!

    Solr使用初探——Solr的安装环境与配置 一、依赖包 http://mirrors.cnnic.cn/ap […]...

  6. chrome 问题 – j.w

    chrome 问题 1、chrome表单自动填充去掉input黄色背景解决方案  http://blog.cs […]...

  7. 大话性能测试系列(3)- 常用的性能指标

    如果你对性能测试感兴趣,但是又不熟悉理论知识,可以看下面的系列文章 https://www.cnblogs.c […]...

  8. 宏碁本安装linux系统找不到操作系统的解决方法。 – 拉格朗

    宏碁本安装linux系统找不到操作系统的解决方法。 最近在笔记本上安装linux,ubuntu15.04系统。 […]...

随机推荐

  1. HTML 编辑器大全 HTML 编辑器大全

    HTML 编辑器大全 WebHtmlEditor WebHtmlEditor 是一个网页的在线文本编辑器,她能 […]...

  2. go最基本生产者与消费

    package main import ( "fmt" "math/rand" "time" ) //生产者 […]...

  3. C语言编程基础知识汇总学习,适合初学者!

      我们用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,加深小伙伴们对C语言的认识。 […]...

  4. REST API接口测试

    背景介绍 为什么要做借口测试? 很多系统关联都是基于接口来实现的,接口测试可以将复杂的系统关联进行简化. 接口 […]...

  5. 论文查重是怎么查的 – kk20_625

    论文查重是怎么查的 论文查重是怎么查的 论文查重系统作为高校中检查学生毕业论文的重要工具,每年的毕业生将使用对 […]...

  6. 【数模学习】Matlab 符号微积分 计算微分、雅可比矩阵、不定积分与定积分、求解微分方程 – Tob__yuhong

    【数模学习】Matlab 符号微积分 计算微分、雅可比矩阵、不定积分与定积分、求解微分方程 1.计算微分   […]...

  7. 【转载】 jmeter 命令行模式(非GUI)运行脚本,察看结果树结果为空,解决办法

    转载地址:https://www.cnblogs.com/canglongdao/p/12636403.htm […]...

  8. Java生产者消费者的三种实现

    Java生产者消费者是最基础的线程同步问题,java岗面试中还是很容易遇到的,之前没写过多线程的代码,面试中被 […]...

展开目录

目录导航