在机器视觉中追踪时常会用到预测算法,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. ASC转换BCD,ASC2BCD(转)

    int ASC2BCD(const char* szASC,byte* szBDC)   {   int szASCLen=strlen(szASC);   byte * bpBCD = new by ...

  2. python继承,判断类型,多态

    1.python中继承 如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承: class Person(object): def __init_ ...

  3. MyEclipse激活失败

    最近从MyEclipse2014升级MyEclipse2015,结果按照MyEclipse2014的方式激活2015总是失败,显示错误如下图所示: 反复实验,怎么也不能成功激活,最终找到方法 很多情况 ...

  4. c语言字符处理函数常见使用集合

    1.最近看一些开源项目代码时,总会看到 c 语言中一些  "str" 开头的处理字符串的用法,有的之前没用到过,特此记录,随时看到随时添加. 这里不提出源码,只是一些使用说明加例子 ...

  5. ASC和字符转化,整形和String转化

    public class ASCTest { public static void main(String[] args) { /* 区别这两种 String s = "123"; ...

  6. python 之Tornado

    一.Tomado Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webap ...

  7. 使用SpringMVC时报错HTTP Status 405 - Request method 'GET' not supported

    GET方法不支持.我出错的原因在于,在JSP中我希望超链接a以post方式提交,但是这里写js代码时出错. <script type="text/javascript"> ...

  8. svn官方版本的使用

    创建仓库的命令是:svndadmin create c:\abcde 启动命令是:svnserve -d -r c:\abcde 官方版本,svn路径

  9. 用纯css写一个常见的小三角形

    .test{ margin:50px auto; width: 0; height: 0; overflow: hidden; border-width: 10px; border-color: #0 ...

  10. shell 数组操作

    1. 定义数组: var_array=(one two three four five) 2.常用操作 获取数组长度: ${#var_array[@]} 获取所有数组元素:  ${var_array[ ...