OpenCV 团块跟踪

一、概述

       OpenCV 团块跟踪过程细分为:前景检测模块、新团块(blob)检测模块、团块跟踪模块、轨迹生成模块和轨迹后处理模块。而跟踪流程模块CvBlobTrackerAuto把这五个模块连接起来。如下图所示:

                   

     各个模块的功能:

    (1)、前景检测模块:对每个像素判断其是前景还是背景;

    (2)、新团块检测模块:使用前景检测的结果检测新进入场景的团块;

    (3)、团块跟踪模块:使用新团块检测模块的结果初始化该模块,并跟踪新进入的团块;

    (4)、轨迹生成模块:主要是保存操作。它收集所有团块的位置,并在每条轨迹结束时将其保存到硬盘上;

    (5)、轨迹后处理模块:进行轨迹的平滑操作。此模块是可选的,可以不包含在处理流程中;

    (6)、跟踪流程模块:将前面提到的五个模块连接起来,形成一个处理流程;

 

二、前景检测模块

       前景检测模块将当前帧上的像素分为前景像素和背景像素。OpenCV 实现了两种前景检测方法:混合高斯模型和Liyuan Li 的ACM Multimedia 2003 会议论文中的算法。

       CvFGDetector 是个虚类,描述了前景检测模块接口。前景检测模块的输入数据为当前帧图像,输出数据为当前帧的前景掩码(mask)。其结构定义如下:

       class CvFGDetector

      {

        public: virtual  IplImage*GetMask( ) = 0;

                    virtual void   Process(IplImage*plmg) = 0;

                    virtual void  Release( ) = 0;

       }

 

三、新团块检测模块

       CvBlobDetector 是一个虚类,用来描述新团块检测模块的接口。新团块检测模块的输入数据为当前的前景掩码和已有的团块,输出数据为新检测到的团块。新团块检测模块作用是将新进入物体的位置和大小检测到。模块结构如下:

   class CvBlobDetector

  {

    public:

             /*利用前景掩码检测新的团块*/

            /*pFGMask-图像的前景掩码*/

            /*pNewBlobList-新检测到的团块序列指针*/

            /*pOldBlobList-已有团块序列指针*/

           virtual int DetectNewBlob(IplImage*pFGMask, CvBlobSeq *pNewBlobList,

                                                    CvBlobSeq *pOldBlobList) = 0;

           virtual void Release( ) = 0;

  }

     CvBlobDetector 两个子类 CvBlobDetectorSimple 和 CvBlobDetectorCC。下面简单介绍CvBlobDetectorCC:DetectNewBlob 的处理流程。首先从前景图像pFGMask中检测出所有团块,然后将较小的团块(可能是由噪声引起的)和已经被跟踪团块有重叠的团块丢弃,并对剩余的团块按照大小排序,仅保留10个最大的团块。将这几个团块作为候选新的团块,对它们利用各种筛选,筛除掉不符合标准的团块,将最后真正的新团块保存到变量pNewBlobList中。

 

四、团块跟踪模块

CvBlobTracker 是一个虚类,用来描述团块跟踪模块的接口。团块跟踪模块的输入数据为当前帧(是BGR图像)、当前帧的前景掩码和新团块,输出数据为当前帧的团块信息(ID,pos,size)。模块结构如下:

    class CvBlobTracker:

   {
    public:
    CvBlobTracker();

    /* Add new blob to track it and assign to this blob personal ID */
    /* pBlob - pointer to structure with blob parameters (ID is ignored)*/
    /* pImg - current image */
    /* pImgFG - current foreground mask */
    /* Return pointer to new added blob: */
    virtual CvBlob* AddBlob(CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG = NULL ) = 0;

    /* Return number of currently tracked blobs: */
    virtual int     GetBlobNum() = 0;

    /* Return pointer to specified by index blob: */
    virtual CvBlob* GetBlob(int BlobIndex) = 0;

    /* Delete blob by its index: */
    virtual void    DelBlob(int BlobIndex) = 0;

    /* Process current image and track all existed blobs: */
    virtual void    Process(IplImage* pImg, IplImage* pImgFG = NULL) = 0;

    /* Release blob tracker: */
    virtual void    Release() = 0;

    /* Return pointer to blob by its unique ID: */
    virtual int     GetBlobIndexByID(int BlobID);

    /* Return pointer to blob by its unique ID: */
    virtual CvBlob* GetBlobByID(int BlobID);

    /* Delete blob by its ID: */
    virtual void    DelBlobByID(int BlobID);

    /* Set new parameters for specified (by index) blob: */
    virtual void    SetBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/);

    /* Set new parameters for specified (by ID) blob: */
    virtual void    SetBlobByID(int BlobID, CvBlob* pBlob);

   };

      CvBlobTrackerCC::Process 处理流程是:首先从前景图像pImgFG提取所有团块,并计算团块的质心、宽度和高度。然后对每一个已经被跟踪的轨迹,利用卡尔曼滤波器预测该轨迹在当前帧的团块的位置和大小。如果变了m_Collision值非零,则对当前跟踪的所有团块进行碰撞检测。如果某两个团块存在碰撞,则设置其属性Collision为1。最后一步是对每个跟踪的轨迹进行处理,寻找离上一帧的团块最近的当前帧里的团块,将此团块加入到跟踪轨迹。下图是团块跟踪列表:

   

 

五、轨迹生成模块

       CvBlobTrackerGen 是用来实现轨迹生成模块的一个虚类。此模块的目的是将整个轨迹保存到指定文件中,同时,也可以为每一个团块计算一些特征并保存。轨迹生成模块的输入数据为当前帧的所有团块,输出数据为保存的轨迹列表。模块数据结构如下:

   classCvBlobTrackGen

  {
    public:
       CvBlobTrackGen(){SetTypeName("BlobTrackGen");};
       virtual void    SetFileName(char* pFileName) = 0;
       virtual void    AddBlob(CvBlob* pBlob) = 0;
       virtual void    Process(IplImage* pImg = NULL, IplImage* pFG = NULL) = 0;
       virtual void    Release() = 0;
  };

 

六、轨迹后处理模块

CvBlobTrackPostProc 是用来实现轨迹后处理模块的一个虚类。此模块的目的是在团块轨迹上做一些滤波处理。例如此模块可以是Kalman 滤波或其他的平滑滤波。轨迹后处理模块的输入数据为当前帧的所有团块,输出数据为当前帧的所有团块。模块结构如下:

    class CvBlobTrackPostProc

   {
     public:
        virtual void    AddBlob(CvBlob* pBlob) = 0;
        virtual void    Process() = 0;
        virtual int     GetBlobNum() = 0;
        virtual CvBlob* GetBlob(int index) = 0;
        virtual void    Release() = 0;

       /* Additional functionality: */
       virtual CvBlob* GetBlobByID(int BlobID)
      {
          int i;
         for(i=GetBlobNum();i>0;i--)
         {
             CvBlob* pB=GetBlob(i-1);
             if(pB->ID==BlobID) return pB;
         }
         return NULL;
      };
   };

    轨迹后处理的流程如图如下:

    

 

七、处理流程模块

      CvBlobTrackerAuto 是一个虚类,用于集成其他模块,构成一个跟踪流程。该模块定义的结构如下:

    class CvBlobTrackerAuto

   {
    public:
 
       virtual void    Process(IplImage* pImg, IplImage* pMask = NULL) = 0;
        virtual CvBlob*     GetBlob(int index) = 0;
        virtual CvBlob*     GetBlobByID(int ID) = 0;
        virtual int         GetBlobNum() = 0;
        virtual IplImage*   GetFGMask(){return NULL;};
        virtual float       GetState(int BlobID) = 0;
        virtual const char*       GetStateDesc(int BlobID) = 0;
        /* return 0 if trajectory is normal;
        * return >0 if trajectory abnormal. */
       virtual void    Release() = 0;
   };

该类关键函数是CvBlobTrackerAuto1::Process,它负责调用其他各子模块。具体流程图如下:

    

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值