Blob_Tracking_Modules Opencv

     前段时间跟着实验室师兄,做智能交通的项目,研究了一下opencv里自带的Blob_Tracking(块追踪)模块,这里记录一下自己的收获。

     首先是从opencv里面三个文档里开始作了解的,这三个文档在opencv2.4.8\opencv\sources\doc\vidsurv里面,分别是Blob_Tracking——Modules.doc、Blob_Tracking_Test.doc、TestSeq.doc。这三个文档网上有很多资料,我也作一下自己的见解。

       Blob_Tracking里面介绍了块追踪所使用到的数据结构与类。块处理的流程如下:

                                         

        其中主要用到了两个数据结构:CvBlob和CvBlobList。

     CvBlob描述了一个目标块的位置、大小和ID。

typedef struct CvBlob
{
    float   x,y; /* blob position   */
    float   w,h; /* blob sizes      */
    int     ID;  /* blbo ID         */     
}CvBlob;
    CvBlobList则是一个类,即一系列CvBlob的集合,可以是轨迹或者同一帧的目标块。
class CvBlobSeq
{	
public:
    CvBlobSeq(int BlobSize = sizeof(CvBlob));
    virtual ~CvBlobSeq();
    virtual CvBlob* GetBlob(int BlobIndex);
    virtual CvBlob* GetBlobByID(int BlobID);
    virtual void DelBlob(int BlobIndex);
    virtual void DelBlobByID(int BlobID);
    virtual void Clear();
    virtual void AddBlob(CvBlob* pB);
    virtual int GetBlobNum();
};
     CvFGDetector:

        

class CvFGDetector
{
public:
    virtual IplImage* GetMask() = 0;
    /* process current image */
    virtual void    Process(IplImage* pImg) = 0;
    /* release foreground detector */
    virtual void    Release() = 0;
};
    前景检测模块 CvFGDetector:它的输入数据为当前帧图像,输出结果数据为当前帧图像的前景图像 (mask)。前景图像是一个和输入的视频帧具有同样大小的二值图像,即如果当前帧中的像素点被判断为运动前景,则前景掩码中相应位置的像素点值为 1,否则,相应的像素点值为 0

     开发者需要继承CvFGDetector类,并实现其中的纯虚函数。其中在函数Virtual void process(IplImage *pImg){}中写入自己开发的运动目标检测算法。而函数Virtual IplImage *GetMask()是得到前景检测的结果图像,并负责传递到后续的模块中。而函数Virtual void Release()负责一些动态分配内存的释放。

       CvBlobDetector:

      

class CvBlobDetector
{
public:
    /* try to detect new blob entrance based on foreground mask */
    /* pFGMask - image of foreground mask */
    /* pNewBlobList - pointer to sequence to save new detected blobs  */
    /* pOldBlobList - pointer to blob list which already exist on image */
    virtual int DetectNewBlob(IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList) = 0;
	/* return number of detected blobs */
    /* release blob detector */
    virtual void Release()=0;
};
      新团块检测模块 CvBlobDetector:该模块的作用是检测进入监控范围的新目标的位置和大小。模块的输入是当前帧的前景图像 (前景检测模块的结果 )和已经检测并标定的团块,输出的结果是新检测到的团块。

      开发者可以将虚类实例化,然后将自己的新团块检测算法写入到相应的函数中。

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

       CvBlobTracker:

       

class CvBlobTracker
{
public:
    /* Add new blob to track it and assign to this blob personal ID */
    /* pBlob - pinter 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 pinter to blob by its unique ID */
    virtual int     GetBlobIndexByID(int BlobID);
    /* return pinter 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);
};
       团块跟踪模块 CvBlobTracker:该模块的作用就是在前面两个模块 (前景检测模块、新团块检测模块 )对运动目标检测的基础上,实现对运动目标的跟踪。此模块的输入为当前帧的前景图像和团块列表以及当前帧图像,输出结果是当前视频帧中所有运动目标的信息,以团块表示 (ID,pos,size)。使用新团块检测模块的结果初始化该模块,并跟踪新进入的团块。

       开发者根据自己的算法开发相应的跟踪系统时,可以继承该类,然后用自己的算法实现函数Virtural void process(IplImage *pImg,IplImage *pImgFG=NULL)。此虚类中还定义了许多其他的辅助处理函数接口,例如跟踪索引或ID返回指定团块指针的函数,根据索引或ID为指定团块设置参数函数等。

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

       CvBlobTrackerList:是Blob Tracking模块中一个产生追踪模块的类,其中一个重要的参数是CvBlobTrackerOne,它们的关系为:
CvBlobTracker* cvCreateBlobTrackerList(CvBlobTrackerOne* (*create)());



      

      CvBlobTrackerOne相当于一个指针。它生产一个轨迹的追踪模块,每来一帧,就会调用Process函数来估计模块新的位置和大小,并返回到这个模块。

class CvBlobTrackerOne
{
public:
    virtual void Init(CvBlob* pBlobInit, IplImage* pImg, IplImage* pImgFG = NULL) = 0;
    virtual CvBlob* Process(CvBlob* pBlobPrev, IplImage* pImg, IplImage* pImgFG = NULL) = 0;
    virtual void Release() =  0;
};
       CvBlobTrackGen:

    

class CvBlobTrackGen
{
public:
    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;
};

       轨迹生成模块CvBlobTrackGen:该模块的作用是生成运动目标的运动轨迹,然后将轨迹导出到指定数据库或文件中(.txt.csv文件)。该模块的输入是代表当前处理视频帧中各个运动目标的团块,输出结果是存储在指定位置下的轨迹文件。该模块主要是保存操作,它收集所有团块的位置,并在每条轨迹结束时(例如跟踪丢失时或者物体离开场景时)将其保存到硬盘上,同时也可以为每个团块计算一些特征并保存。

       CvBlobTrackPostProc:

       

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);
};
       轨迹后处理模块 CvBlobTrackPostProc:该模块的作用是在前一个模块所产生的团块轨迹上做一些处理,例如采用 Kalman滤波或平滑滤波处理等。此模块是可选的,可以不包含在处理流程中。它的输入是当前处理图像的所有团块,输出结果是处理后所处理图像的团块列表。

     轨迹后处理模块跟团块跟踪模块一样有CvBlobTrackPostProcList跟CvBolbtrackPostProcOne这两个辅助类。

     在代码里面还有,轨迹分析模块CvBlobTrackAnalysis:当某个目标跟踪结束后,会产生一个轨迹,CvBlobTrackAnalysis的子类用于对轨迹进行数据分析;

        跟踪流程模块CvBlobTracterAuto:为了方便开发者开发自己的系统,同时也为了保证系统的模块化设计,OpenCV设计了此虚类描述整个跟踪流程,这个代表整个跟踪流程的虚类将各个模块相互联系起来成为一个有机的整体。本模块将前面提到的五个模块连接起来,形成一个完整的处理流程。

       此类中的函数Process负责调用其它各个子模块,首先对背景图像进行更新并检测前景,将获取的前景图像保存于成员变量m_pFG中。获取前景图像后,便依次调用团块跟踪模块(注意:而不是新团块检测模块,这样做的主要目的是先执行跟踪可将当前帧的跟踪结果传入新团块检测模块,以提供新团块检测的准确度。如果团块跟踪在后,则新团块跟踪模块只能与上一帧的团块列表进行比较,新团块检测的准确度将会有所降低),轨迹后处理模块,团块检测模块,轨迹生成模块,轨迹分析模块。

      如果想将自己实现的算法加入到以上模块中也很方便,如将背景差分算法加入到前景检测模块中,只要继承 CvFGDetector 类,然后主要在Process函数中实现自己的算法就可以了。

 

    原始代码中,用红色标注运动目标的表示跟踪不稳定,绿色则表示稳定跟踪。

 

    轨迹生成模块中默认有两种方法实现数据的保存,其中一种是RawTracks方法,每行存放一个运动目标数据,单位为像素,依次为运动目标出现的起始帧,运动目标中心x坐标,运动目标中心y坐标,运动目标宽度,运动目标高度,运动目标中心x坐标,运动目标中心y坐标,运动目标宽度,运动目标高度,……

    

     模块说明大部分来至参考文献3,因为我觉得作者理解得比我好,直接引用了,特此感谢该作者。以后还会做这方面的工作,有理解不对的地方以后更正,更欢迎大家为我指出,谢谢!


参考文献:

1.http://www.doc88.com/p-896576154875.html

2.http://blog.csdn.net/wk119911/article/details/7664478

3.http://blog.csdn.net/fengbingchun/article/details/7872325



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值