在机器视觉中追踪时常会用到预测算法,kalman是你一定知道的。它可以用来预测各种状态,比如说位置,速度等。关于它的理论有很多很好的文献可以参考。opencv给出了kalman filter的一个实现,而且有范例,但估计不少人对它的使用并不清楚,因为我也是其中一个。本文的应用是对二维坐标进行预测和平滑

使用方法:

1、初始化

const int stateNum=4;//状态数,包括(x,y,dx,dy)坐标及速度(每次移动的距离)

const int measureNum=2;//观测量,能看到的是坐标值,当然也可以自己计算速度,但没必要

Kalman* kalman = cvCreateKalman( stateNum, measureNum, 0 );//state(x,y,detaX,detaY)

转移矩阵或者说增益矩阵的值好像有点莫名其妙

  1. float A[stateNum][stateNum] ={//transition matrix
  2. 1,0,1,0,
  3. 0,1,0,1,
  4. 0,0,1,0,
  5. 0,0,0,1
  6. };

看下图就清楚了

X1=X+dx,依次类推

所以这个矩阵还是很容易却确定的,可以根据自己的实际情况定制转移矩阵

同样的方法,三维坐标的转移矩阵可以如下

  1. float A[stateNum][stateNum] ={//transition matrix
  2. 1,0,0,1,0,0,
  3. 0,1,0,0,1,0,
  4. 0,0,1,0,0,1,
  5. 0,0,0,1,0,0,
  6. 0,0,0,0,1,0,
  7. 0,0,0,0,0,1
  8. };

当然并不一定得是1和0

2.预测cvKalmanPredict,然后读出自己需要的值

3.更新观测矩阵 

4.更新CvKalman

只有第一步麻烦些。上述这几步跟代码中的序号对应

如果你在做tracking,下面的例子或许更有用些。

  1. #include <cv.h>
  2. #include <cxcore.h>
  3. #include <highgui.h>
  4. #include <cmath>
  5. #include <vector>
  6. #include <iostream>
  7. using namespace std;
  8. const int winHeight=600;
  9. const int winWidth=800;
  10. CvPoint mousePosition=cvPoint(winWidth>>1,winHeight>>1);
  11. //mouse event callback
  12. void mouseEvent(int event, int x, int y, int flags, void *param )
  13. {
  14. if (event==CV_EVENT_MOUSEMOVE) {
  15. mousePosition=cvPoint(x,y);
  16. }
  17. }
  18. int main (void)
  19. {
  20. //1.kalman filter setup
  21. const int stateNum=4;
  22. const int measureNum=2;
  23. CvKalman* kalman = cvCreateKalman( stateNum, measureNum, 0 );//state(x,y,detaX,detaY)
  24. CvMat* process_noise = cvCreateMat( stateNum, 1, CV_32FC1 );
  25. CvMat* measurement = cvCreateMat( measureNum, 1, CV_32FC1 );//measurement(x,y)
  26. CvRNG rng = cvRNG(-1);
  27. float A[stateNum][stateNum] ={//transition matrix
  28. 1,0,1,0,
  29. 0,1,0,1,
  30. 0,0,1,0,
  31. 0,0,0,1
  32. };
  33. memcpy( kalman->transition_matrix->data.fl,A,sizeof(A));
  34. cvSetIdentity(kalman->measurement_matrix,cvRealScalar(1) );
  35. cvSetIdentity(kalman->process_noise_cov,cvRealScalar(1e-5));
  36. cvSetIdentity(kalman->measurement_noise_cov,cvRealScalar(1e-1));
  37. cvSetIdentity(kalman->error_cov_post,cvRealScalar(1));
  38. //initialize post state of kalman filter at random
  39. cvRandArr(&rng,kalman->state_post,CV_RAND_UNI,cvRealScalar(0),cvRealScalar(winHeight>winWidth?winWidth:winHeight));
  40. CvFont font;
  41. cvInitFont(&font,CV_FONT_HERSHEY_SCRIPT_COMPLEX,1,1);
  42. cvNamedWindow("kalman");
  43. cvSetMouseCallback("kalman",mouseEvent);
  44. IplImage* img=cvCreateImage(cvSize(winWidth,winHeight),8,3);
  45. while (1){
  46. //2.kalman prediction
  47. const CvMat* prediction=cvKalmanPredict(kalman,0);
  48. CvPoint predict_pt=cvPoint((int)prediction->data.fl[0],(int)prediction->data.fl[1]);
  49. //3.update measurement
  50. measurement->data.fl[0]=(float)mousePosition.x;
  51. measurement->data.fl[1]=(float)mousePosition.y;
  52. //4.update
  53. cvKalmanCorrect( kalman, measurement );
  54. //draw
  55. cvSet(img,cvScalar(255,255,255,0));
  56. cvCircle(img,predict_pt,5,CV_RGB(0,255,0),3);//predicted point with green
  57. cvCircle(img,mousePosition,5,CV_RGB(255,0,0),3);//current position with red
  58. char buf[256];
  59. sprintf_s(buf,256,"predicted position:(%3d,%3d)",predict_pt.x,predict_pt.y);
  60. cvPutText(img,buf,cvPoint(10,30),&font,CV_RGB(0,0,0));
  61. sprintf_s(buf,256,"current position :(%3d,%3d)",mousePosition.x,mousePosition.y);
  62. cvPutText(img,buf,cvPoint(10,60),&font,CV_RGB(0,0,0));
  63. cvShowImage("kalman", img);
  64. int key=cvWaitKey(3);
  65. if (key==27){//esc
  66. break;
  67. }
  68. }
  69. cvReleaseImage(&img);
  70. cvReleaseKalman(&kalman);
  71. return 0;
  72. }

kalman filter 视频演示:

http://v.youku.com/v_show/id_XMjU4MzEyODky.html

demo snapshot:

kalman 滤波 演示与opencv代码的更多相关文章

  1. OpenCV: kalman滤波的代码段

    序言:在我的疲劳检测工程 AviTest中!显示框为320*240,使用OpenCV的kalman滤波算法,可以实现简单的锁相追踪-实现对眼球的位置锁定. 代码如下: CvPoint Wishchin ...

  2. 理解Kalman滤波的使用

    Kalman滤波简介 Kalman滤波是一种线性滤波与预测方法,原文为:A New Approach to Linear Filtering and Prediction Problems.文章推导很 ...

  3. (二). 细说Kalman滤波:The Kalman Filter

    本文为原创文章,转载请注明出处,http://www.cnblogs.com/ycwang16/p/5999034.html 前面介绍了Bayes滤波方法,我们接下来详细说说Kalman滤波器.虽然K ...

  4. 透过表象看本质!?之三——Kalman滤波

    数据拟合能够估计出数据变化的趋势,另外一个同等重要的应用是如何利用这一趋势,预测下一时刻数据可能的值.通俗点儿说,你观察苍蝇(蚊子,蜜蜂)飞了几秒,你也许会想“它下一个时刻可能在哪儿”,“呈现出什么样 ...

  5. 快速双边滤波 附完整C代码

    很早之前写过<双边滤波算法的简易实现bilateralFilter>. 当时学习参考的代码来自cuda的样例. 相关代码可以参阅: https://github.com/johng12/c ...

  6. 终于理解kalman滤波

    2017拜拜啦,怎么过元旦呢?当然是果断呆实验室过... 应该是大二的时候首次听说kalman,一直到今天早上,我一看到其5条"黄金公式",就会找各种理由放弃,看不懂呀...但是研 ...

  7. kalman滤波

    kalman滤波原理(通俗易懂) 1. 在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”.跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人 ...

  8. 目标跟踪之卡尔曼滤波---理解Kalman滤波的使用预测

    Kalman滤波简介 Kalman滤波是一种线性滤波与预测方法,原文为:A New Approach to Linear Filtering and Prediction Problems.文章推导很 ...

  9. kalman滤波原理

    2017拜拜啦,怎么过元旦呢?当然是果断呆实验室过... 应该是大二的时候首次听说kalman,一直到今天早上,我一看到其5条“黄金公式”,就会找各种理由放弃,看不懂呀...但是研究lidar定位需要 ...

随机推荐

  1. 第一课 C语言简明教程

    1序言: 1与Java.C#等高级语言相比,C语言使用简单但是也非常重要更容易出错,到目前为止基本上操作系统的内核代码超过百分之九十使用C语言完成,因此学好C语言是学好计算机这门课程的基础,特别是进入 ...

  2. .net:easyui-datagrid清空表中原有数据

    $("#StudentTable").datagrid("loadData", { total: 0, rows: [] });

  3. Samba 3.6.9 安装、管理

    Samba简介 Samba服务类似于windows上的共享功能,可以实现linux上共享文件,windows上访问,当然在linux上可以访问到.是一种在局域网上共享文件和打印机的一种通信协议,它为局 ...

  4. centos 6+安装山逗斯骚尅特

    系统支持:CentOS 6+,Debian 7+,Ubuntu 12+ 内存要求:≥128M 关于本脚本 一键安装 Shadowsocks-Python, ShadowsocksR, Shadowso ...

  5. redis_入门网址

    redis中文网: http://www.redis.cn/ 可以 试用 以及 下载 redis百度百科:http://baike.baidu.com/link?url=MEkE5MpGAOfJ7ci ...

  6. java用servlet、cookie实现一个阅读记录

    效果如图 代码1 package com.xiaostudy.servlet; import java.io.IOException; import java.io.PrintWriter; impo ...

  7. HTML常用标签——思维导图

    如图 思维导图图片链接 http://www.edrawsoft.cn/viewer/public/s/38d99149304484

  8. File类之常用方法

    package IoDemo; import java.io.File; import java.io.IOException; /** * @Title:FileTest * @Descriptio ...

  9. 摘录:MINA 框架简介

    Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务.虚拟机管道通信服务等),Mi ...

  10. PHP超级全局变量、魔术变量和魔术函数的区别和联系

    PHP超级全局变量.魔术变量和魔术函数的区别和联系 一.总结 一句话总结:PHP超级全局变量主要用于web开发,魔术变量主要用于输出当前对象的信息,魔术函数则是对象的常用方法 相同点: 1.PHP超级 ...