leikui9966 2016-08-03 12:14 采纳率: 0%
浏览 1610

如何将opencv自带例程blobtrack_sample.cpp与手写体字母识别程序串起来?

手写体字母程序见以下链接手写体字母识别

  • 写回答

1条回答 默认 最新

  • devmiao 2016-08-03 13:47
    关注

    最近想做个简单的跟踪,突然想起了blobtrack_sample这个opencv例程。先对主要代码做一简要分析。

    只说前两个模块:新团块检测模块CvBlobDetector和团块跟踪模块CvBlobTracker

    一,新团块检测模块CvBlobDetector:

    新团块检测模块的处理流程为:首先从前景图像中检测出所有团块,然后将较小的团块(可能是由噪声引起的)和与已经被跟踪团块有重叠的团块丢弃,并对剩余的团块按照大小顺序排列,只保留其中几个比较大的团块(默认为10)。最后利用特定规则筛选,筛选不合标准的团块,将真正的新团块保存到团块列表中。

    DetectNewBlob函数:

    //这个函数首先通过轮廓获得contour blob
    //然后筛掉与其关联的已经存在的blob,该blob应该是通过预测,跟踪后的blob
    //然后将剩下的blob与存在的track进行关联操作,如果符合关联条件则计数加1,
    //这里的track类似于预备blob的历史轨迹表,他们可能成为新blob的,需要符合计数达到SEQ_SIZE
    //轨迹符合线形拟合
    //如果1个contour blob对应多个track则复制这个contour
    /SEQ_SIZE应该是控制是否符合新blob条件的计数上限,
    //比如一个contour blob在一个track里连续SEQ_SIZE次符合新blob条件,则判断是否该contour blob是一个新的blob,
    //符合新blob条件有三个条件:
    //1,物体高宽分别大于门限
    //2,前后帧质心X,Y方向距离与以前blob列表中的所有blob分别都大于两个物体宽度和的平均高度和平均
    //3,对连续SEQ_SIZE个物体的质心进行最小二乘法的线性拟合看是否符合一定运动轨迹规律
    //前面的blob都是coutour blob,通过找轮廓方法获得的blob,
    //coutour blob通过筛选确定是否为新物体
    //m_TrackSeq用于存放可能为新blob的contour blob,每一个DefSeq
    //都保存了符合条件contour blob的历史轨迹 当track计数达到了SEQ_SIZE的时候
    //就与已有的 blob进行比对,看是否与已有的blob关联,关联条件主要是看两个blob的质心X,Y方向的距离是否
    //大于两个blob宽度和的平均高度和平均,个人 认为这里多余了,因为前面已经检测过了
    //还有就是判断物体是否在边界附近,如果在边界附近也可以不用处理跟踪了
    //当所有的都符合,则用最小二乘法来最终确定track中SEQ_SIZE个历史blob的轨迹是否合理

    上述主要出自:http://www.cnblogs.com/freedesert/archive/2012/09/20.html

    二、团块跟踪模块CvBlobTracker

    该模块的作用就是在前面两个模块(前景检测模块、新团块检测模块)对运动目标检测的基础上,实现对运动目标的跟踪。此模块的输入为当前帧的前景图像和团块列表以及当前帧图像,输出结果是当前视频帧中所有运动目标的信息,以团块表示(ID,pos,size)。使用新团块检测模块的结果初始化该模块,并跟踪新进入的团块。

    团块跟踪模块的处理流程为:首先从前景图像提取所有团块,并计算团块的质心、宽度和高度;然后对每一个已被跟踪的轨迹,利用卡尔曼滤波器预测该轨迹在当前帧的团块的位置和大小;最后对每个跟踪的轨迹进行处理,寻找离上一帧里的团块最近的当前帧的团块,将此团块添加到跟踪轨迹。

    主要说明kalman滤波的流程。
    

     使用Kalman编程的主要步骤:

      步骤一 :

     Kalman这个类需要初始化下面变量:      
    

      转移矩阵,测量矩阵,控制向量(没有的话,就是0),过程噪声协方差矩阵,测量噪声协方差矩阵,后验错误协方差矩阵,前一状态校正后的值,当前观察值。

      步骤二:

      调用kalman这个类的predict方法得到状态的预测值矩阵,预测状态的计算公式如下:

      predicted state (x'(k)): x'(k)=A*x(k-1)+B*u(k)

      其中x(k-1)为前一状态的校正值,第一个循环中在初始化过程中已经给定了,后面的循环中Kalman这个类内部会计算。A,B,u(k),也都是给定了的值。这样进过计算就得到了系统状态的预测值x'(k)了。

      步骤三:

      调用kalman这个类的correct方法得到加入观察值校正后的状态变量值矩阵,其公式为:

      corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))

      其中x'(k)为步骤二算出的结果,z(k)为当前测量值,是我们外部测量后输入的向量。H为Kalman类初始化给定的测量矩阵。K(k)为Kalman增益,其计算公式为:

      Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)

      计算该增益所依赖的变量要么初始化中给定,要么在kalman理论中通过其它公式可以计算。

      经过步骤三后,我们又重新获得了这一时刻的校正值,后面就不断循环步骤二和步骤三即可完成Kalman滤波过程。

     下面来看看使用Kalman编程的主要步骤:

    1)为每一个新blob创建kalman filter

    blobtrack_sample例程首先调用DetectNewBlob函数检测进入的新团块,之后该函数调用m_pBT->AddBlob(),这个函数有调用cvCreateModuleBlobTrackPredictKalman初始化kalman模块,注意这里每一个新进团块都对应一个kalman filter.

    2)当检测出团块后(我们的目的是在下一帧中找出该团块相对于的团块,即该团块的轨迹),对于下一帧(分两种情况,一种情况是没有新blob,另一种情况是有新blob进入,当然两种情况对于Track blobs模块是透明的), m_pBT->Process(pImg, pFG)函数,即Track blobs模块就可以正常工作了(有效了)。

    首先调用pBT->pPredictor->Update(&(pBT->blob)),当m_Frame < 2时,更新x(t)即m_pKalman->state_post,再进行预测x'(t);当m_Frame>=2时,有了观测值(上一帧blob的预测值与当前帧blobs最佳匹配blob),则用该观测值校正状态变量值矩阵即:corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))。该Update函数意思是:当有观测值时,correct后再进行预测,当没有观测值时直接预测。

    之后,再调用pBT->pPredictor->Predict()得到预测后的x'(t),得到m_BlobPredict。

    3)找到上一帧新blob在当前帧中的最佳预测m_BlobPredict后,用该m_BlobPredict在当前帧中的blob进行匹配(基于距离,基于meanshif直方图),找到最佳匹配的blob做为该新blob(上一帧的blob)在当前帧的轨迹。得到该轨迹最为步骤2的观测值,重新校正,预测,匹配,再校正。。。

    评论

报告相同问题?

悬赏问题

  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误