在机器视觉中追踪时常会用到预测算法,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. Android 6.0 Kotlin 蓝牙BLE扫描(改为指定时间没有发现新设备后停止扫描使用interface)

    package com.arci.myapplication import android.os.Bundleimport android.support.design.widget.Snackbar ...

  2. 调试利器之tcpdump详解

    简介你执行 man tcpdump 命令,你会看到文档中对tcpdump的说明是“dump traffic on a network”.可见,tcpdump是一个根据使用者的定义对网络上的数据包进行截 ...

  3. java 工厂模式的作用,为什么要用工厂模式以及示例演示

    1 工厂模式的作用,为什么要用工厂模式? 工厂模式是为了解耦:把对象的创建和使用的过程分开.就是Class A 想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类. 工厂模式可 ...

  4. 剑指offer编程题66道题 36-66

    36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...

  5. C# winform 屏蔽鼠标右键 spreadsheet Gear 屏蔽鼠标右键菜单

    今天用到spreadsheetGear 插件,然后右键有插件自己的菜单.都是英文的,而且还能打开新的窗体.嵌到程序里面,不太合适,所以着手屏蔽. 刚开始用的Mouse_up,虽然能捕获事件,但是没有K ...

  6. String类型是特殊的引用类型

    例证: string peom1 = "Kubla Khan"; string peom2 = "Kubla Khan"; string peom3 = Str ...

  7. 面试:做过sql优化吗?

    近来面试找工作经常会遇见这种问题: 做过数据库优化吗?大数据量基础过吗?系统反应慢怎么查询? 这咱也没背过啊,面试还老问,现在的网站主要的压力都来自于数据库,频繁的数据库访问经常会使系统瘫痪,这样就需 ...

  8. H3C交换机配置镜像端口

    配置步骤 进入配置模式:system-view: 创建本地镜像组:mirroring-group 1 local 为镜像组配置源端口:mirroring-group 1 mirroring-port ...

  9. JAVA基础补漏--反射

    获得CLASS的三种方式: 1.Class.forname("全类名"):将字节码文件加载进内存,返回Class对象. 多用于配置文件,将类名放到配置文件中,读取配置文件,加载类 ...

  10. PAT1051. Pop Sequence (25)

    #include <iostream> #include <stack> using namespace std; int sizeMax,n,k; stack<int& ...