在机器视觉中追踪时常会用到预测算法,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. hadoop11----socket

    package cn.itcast.bigdata.socket; import java.io.BufferedReader; import java.io.InputStream; import ...

  2. 轮询、长轮询、长连接、socket连接、WebSocket

    轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源.(而每一次的 HTTP 请求和应答 ...

  3. app自动化测试-appium

    一.环境准备(windows) 1.安装Microsoft .NET Framework 4.5 双击运行如下文件:net4.5.1.exe 2.安装node-v6.11.4-x64.msi 双击运行 ...

  4. Hardware Prefetcher

    硬件预取选项,指CPU有硬件预取功能,在CPU处理指令或数据之前,它将这些指令或数据从内存预取到L2缓存中,借此减少内存读取的时间,帮助消除潜在的瓶颈,以此提高系统效能.通常情况下建议设置为Enabl ...

  5. Synchronize原理

    1 普通方法上 2 静态方法上 修饰静态方法内置锁是当前的Class字节码对象 修饰普通方法内置锁是当前类的实例 原理与使用: 从字节码层面解释: 执行同步代码块 monitorenter synch ...

  6. C++中虚函数和纯虚函数的区别与总结

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  7. coredump调试小结

    在已经启动的进程中使用gdb,用gdb attach 查看so文件中的函数列表 nm -D *.so 关于c.c++类的gdb调试,强烈推荐一本书:debug hack

  8. spark学习(RDD案例实战)

    练习0(并行化创建RDD) 先启动spark-shell 通过并行化生成rdd scala> val rdd1 = sc.parallelize(List(63,45,89,23,144,777 ...

  9. spring与quartz整合

    这周学习了quartz定时任务,现在进行总结一下.首先要认识定时任务中几个关键接口,以及各个接口之间是如何联系起来的. 1.关键接口  (1)Scheduler,任务调度的API,它可以用来启动或者终 ...

  10. Treflection02_getMethods()_getMethod()

    1. package reflectionZ; import java.lang.reflect.Constructor; import java.lang.reflect.Method; impor ...