virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
	{/*输入是 已跟踪目标的index 和目标的团块
	 如果不考虑碰撞, 在新前景团块链表总 找最近的,更新
	 考虑碰撞: 团块位置= 预测值
	 */
		//pBlob 是 外界目标Id对应的团块  BlobIndex是他的INdex

		//pB是内部cc类 自己的目标团块
		//pBT是 内部团块的特殊表示
		int             ID = pBlob->ID;
		CvBlob*         pB = m_BlobList.GetBlob(BlobIndex);
		DefBlobTrackerColorTracker* pBT = (DefBlobTrackerColorTracker*)pB;
		//CvBlob*         pBBest = NULL;
		//double          DistBest = -1;
		int             BlobID;

		if (pB == NULL) return;

		BlobID = pB->ID;//看看ID 同不同?

		//对于考虑碰撞的,并且团块发生了碰撞 。 团块位置=团块的预测位置
		if (m_Collision && pBT->Collision)
		{   /* Tracking in collision: */
			pB[0] = pBT->BlobPredict;//将预测的值赋值到团块的位置
			CV_BLOB_ID(pB) = BlobID;
		}   /* Tracking in collision. */
		else
		{   /* Non-collision tracking: */
			CvBlob* pBBest = GetNearestBlob(pB);//用PB和新团块比较 ,获得最近的团块

			if (pBBest)
			{
				float   w = pBlob->w*(1 - m_AlphaSize) + m_AlphaSize*pBBest->w;
				float   h = pBlob->h*(1 - m_AlphaSize) + m_AlphaSize*pBBest->h;
				float   x = pBlob->x*(1 - m_AlphaPos) + m_AlphaPos*pBBest->x;
				float   y = pBlob->y*(1 - m_AlphaPos) + m_AlphaPos*pBBest->y;
				//按比例更新 目标团块的大小和位置
				pB->w = w;
				pB->h = h;
				pB->x = x;
				pB->y = y;
				CV_BLOB_ID(pB) = BlobID;
			}//这种最近邻匹配只能处理没有碰撞的目标跟踪
		}   /* Non-collision tracking. */

		pBlob[0] = pB[0];
		pBlob->ID = ID;
	};
    virtual void    AddBlob(CvBlob* pBlob)
    {
        DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
        if(pF == NULL)
        {   /* Create new filter: */
            DefBlobFilter F;
            F.blob = pBlob[0];
            F.m_LastFrame = m_Frame;
            F.pFilter = m_CreatePostProc();
            TransferParamsToChild(F.pFilter,NULL);
            m_BlobFilterList.AddBlob((CvBlob*)&F);
            pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
        }

        assert(pF);
        pF->blob = pBlob[0];
        pF->m_LastFrame = m_Frame;
    };
예제 #3
0
    virtual void    AddBlob(CvBlob* pBlob)
    {
        DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
        if(pF == NULL)
        {   /* Create new filter: */
            DefTrackAnalyser F;
            F.state = 0;
            F.blob = pBlob[0];
            F.m_LastFrame = m_Frame;
            F.pFilter = m_CreateAnalysis();
            m_TrackAnalyserList.AddBlob((CvBlob*)&F);
            pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
        }

        assert(pF);
        pF->blob = pBlob[0];
        pF->m_LastFrame = m_Frame;
    };
예제 #4
0
    void    AddBlob(CvBlob* pBlob) {
        DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));

        if (pTrack == NULL) {
            /* Add new track: */
            DefBlobTrack    Track;
            Track.blob = pBlob[0];
            Track.FrameBegin = m_Frame;
            Track.pSeq = new CvBlobSeq;
            Track.Saved = 0;
            m_TrackList.AddBlob((CvBlob*)&Track);
            pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
        }   /* Add new track. */

        assert(pTrack);
        pTrack->FrameLast = m_Frame;
        assert(pTrack->pSeq);
        pTrack->pSeq->AddBlob(pBlob);
    };
예제 #5
0
파일: blobtrack.cpp 프로젝트: 93sam/opencv
/* Return pointer to blob by its unique ID: */
int     CvBlobTracker::GetBlobIndexByID(int BlobID)
{
    int i;
    for(i=GetBlobNum();i>0;i--)
    {
        CvBlob* pB=GetBlob(i-1);
        if(CV_BLOB_ID(pB) == BlobID) return i-1;
    }
    return -1;
}
예제 #6
0
    /*----------------- Interface: --------------------*/
    virtual void    AddBlob(CvBlob* pBlob) {
        DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));

        if (pF == NULL) {
            /* Create new TRack record: */
            DefTrackForDist F;
            F.state = 0;
            F.blob = pBlob[0];
            F.LastFrame = m_Frame;
            F.pTrack = new DefTrackRec(CV_BLOB_ID(pBlob));
            m_Tracks.AddBlob((CvBlob*)&F);
            pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
        }

        assert(pF);
        assert(pF->pTrack);
        pF->pTrack->AddPoint(pBlob->x, pBlob->y, pBlob->w * 0.5f);
        pF->blob = pBlob[0];
        pF->LastFrame = m_Frame;
    };
예제 #7
0
 virtual void    Process(IplImage* pImg, IplImage* pFG)
 {
     int i;
     for(i=m_TrackAnalyserList.GetBlobNum(); i>0; --i)
     {
         DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlob(i-1);
         if(pF->m_LastFrame == m_Frame)
         {   /* Process: */
             int ID = CV_BLOB_ID(pF);
             pF->state = pF->pFilter->Process(&(pF->blob), pImg, pFG);
             CV_BLOB_ID(pF) = ID;
         }
         else
         {   /* Delete blob filter: */
             pF->pFilter->Release();
             m_TrackAnalyserList.DelBlob(i-1);
         }
     } /* Next blob. */
     m_Frame++;
 };
    virtual void    Process()
    {
        int i;
        for(i=m_BlobFilterList.GetBlobNum(); i>0; --i)
        {
            DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlob(i-1);

            if(pF->m_LastFrame == m_Frame)
            {   /* Process: */
                int ID = CV_BLOB_ID(pF);
                pF->blob = *(pF->pFilter->Process(&(pF->blob)));
                CV_BLOB_ID(pF) = ID;
            }
            else
            {   /* Delete blob filter: */
                pF->pFilter->Release();
                m_BlobFilterList.DelBlob(i-1);
            }
        }   /* Next blob. */
        m_Frame++;
    };
예제 #9
0
void moBlobTrackerModule::applyFilter(IplImage *src) {
	IplImage* fg_map = NULL;

	assert( src != NULL );
	CvSize size = cvGetSize(src);

	if ( src->nChannels != 1 ) {
		this->setError("BlobTracker input image must be a single channel binary image.");
		this->stop();
		return;
	}

	this->tracker->Process(src, fg_map);

	cvSet(this->output_buffer, CV_RGB(0,0,0));
	this->clearBlobs();

	for ( int i = this->tracker->GetBlobNum(); i > 0; i-- ) {
		CvBlob* pB = this->tracker->GetBlob(i-1);

		int minsize = this->property("min_size").asInteger();
		int maxsize = this->property("max_size").asInteger();
		// Assume circular blobs
		if (pB->w < minsize || maxsize < pB->w || pB->h < minsize || maxsize < pB->h)
			continue;
		// draw the blob on output image
		if ( this->output->getObserverCount() > 0 ) {
			CvPoint p = cvPoint(cvRound(pB->x*256),cvRound(pB->y*256));
			CvSize  s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB)*256)), MAX(1,cvRound(CV_BLOB_RY(pB)*256)));
			int c = cvRound(255*this->tracker->GetState(CV_BLOB_ID(pB)));

			cvEllipse(this->output_buffer, p, s, 0, 0, 360,
				CV_RGB(c,255-c,0), cvRound(1+(3*0)/255), CV_AA, 8);
		}

		LOGM(MO_DEBUG, "Blob: id="<< pB->ID <<" pos=" << pB->x \
			<< "," << pB->y << "size=" << pB->w << "," << pB->h);

		// add the blob in data
		moDataGenericContainer *touch = new moDataGenericContainer();
		touch->properties["type"] = new moProperty("blob");
		touch->properties["id"] = new moProperty(pB->ID);
		touch->properties["x"] = new moProperty(pB->x / size.width);
		touch->properties["y"] = new moProperty(pB->y / size.height);
		touch->properties["w"] = new moProperty(pB->w);
		touch->properties["h"] = new moProperty(pB->h);
		this->blobs.push_back(touch);
	};

	this->output_data->push(&this->blobs);
}
예제 #10
0
    virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
    {
        int             ID = pBlob->ID;
        CvBlob*         pB = m_BlobList.GetBlob(BlobIndex);
        DefBlobTracker* pBT = (DefBlobTracker*)pB;
        //CvBlob*         pBBest = NULL;
        //double          DistBest = -1;
        int             BlobID;

        if(pB==NULL) return;

        BlobID = pB->ID;

        if(m_Collision && pBT->Collision)
        {   /* Tracking in collision: */
            pB[0]=pBT->BlobPredict;
            CV_BLOB_ID(pB)=BlobID;
        }   /* Tracking in collision. */
        else
        {   /* Non-collision tracking: */
            CvBlob* pBBest = GetNearestBlob(pB);
            if(pBBest)
            {
                float   w = pBlob->w*(1-m_AlphaSize)+m_AlphaSize*pBBest->w;
                float   h = pBlob->h*(1-m_AlphaSize)+m_AlphaSize*pBBest->h;
                float   x = pBlob->x*(1-m_AlphaPos)+m_AlphaPos*pBBest->x;
                float   y = pBlob->y*(1-m_AlphaPos)+m_AlphaPos*pBBest->y;
                pB->w = w;
                pB->h = h;
                pB->x = x;
                pB->y = y;
                CV_BLOB_ID(pB) = BlobID;
            }
        }   /* Non-collision tracking. */

        pBlob[0] = pB[0];
        pBlob->ID = ID;
    };
    virtual void SaveState(CvFileStorage* fs)
    {
        int     b,bN = m_BlobList.GetBlobNum();
        cvWriteInt(fs,"BlobNum",m_BlobList.GetBlobNum());
        cvStartWriteStruct(fs,"BlobList",CV_NODE_SEQ);

        for(b=0; b<bN; ++b)
        {
            DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(b);
            cvStartWriteStruct(fs,NULL,CV_NODE_MAP);
            cvWriteInt(fs,"ID",CV_BLOB_ID(pF));
            cvStartWriteStruct(fs,"Blob",CV_NODE_SEQ|CV_NODE_FLOW);
            cvWriteRawData(fs,&(pF->blob),1,"ffffi");
            cvEndWriteStruct(fs);
            cvStartWriteStruct(fs,"BlobPredict",CV_NODE_SEQ|CV_NODE_FLOW);
            cvWriteRawData(fs,&(pF->BlobPredict),1,"ffffi");
            cvEndWriteStruct(fs);
            cvStartWriteStruct(fs,"BlobPrev",CV_NODE_SEQ|CV_NODE_FLOW);
            cvWriteRawData(fs,&(pF->BlobPrev),1,"ffffi");
            cvEndWriteStruct(fs);
            pF->pBlobHyp->Write(fs,"BlobHyp");
            cvWriteInt(fs,"Collision",pF->Collision);
            
            cvStartWriteStruct(fs,"Predictor",CV_NODE_MAP);
            pF->pPredictor->SaveState(fs);
            cvEndWriteStruct(fs);
            
            cvStartWriteStruct(fs,"Resolver",CV_NODE_MAP);
            pF->pResolver->SaveState(fs);
            cvEndWriteStruct(fs);
            cvEndWriteStruct(fs);
        }

        cvEndWriteStruct(fs);

    }   /* SaveState. */
예제 #12
0
    virtual void    Process(IplImage* pImg, IplImage* pImgFG = NULL)
    {
        CvSeq*      cnts;
        CvSeq*      cnt;
        int i;

        m_pImg = pImg;
        m_pImgFG = pImgFG;

        if(m_BlobList.GetBlobNum() <= 0 ) return;

        /* Clear bloblist for new blobs: */
        m_BlobListNew.Clear();

        assert(m_pMem);
        cvClearMemStorage(m_pMem);
        assert(pImgFG);


        /* Find CC: */
#if 0
        {   // By contour clustering:
            cvFindBlobsByCCClasters(pImgFG, &m_BlobListNew, m_pMem);
        }
#else
        {   /* One contour - one blob: */
            IplImage* pBin = cvCloneImage(pImgFG);
            assert(pBin);
            cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
            cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);

            /* Process each contour: */
            for(cnt = cnts; cnt; cnt=cnt->h_next)
            {
                CvBlob  NewBlob;

                /* Image moments: */
                double      M00,X,Y,XX,YY;
                CvMoments   m;
                CvRect      r = ((CvContour*)cnt)->rect;
                CvMat       mat;
                if(r.height < 3 || r.width < 3) continue;
                cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
                M00 = cvGetSpatialMoment( &m, 0, 0 );
                if(M00 <= 0 ) continue;
                X = cvGetSpatialMoment( &m, 1, 0 )/M00;
                Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
                XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
                YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
                NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
                m_BlobListNew.AddBlob(&NewBlob);
            }   /* Next contour. */

            cvReleaseImage(&pBin);
        }
#endif
        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Predict new blob position: */
            CvBlob*         pB=NULL;
            DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(i-1);

            /* Update predictor by previous value of blob: */
            pBT->pPredictor->Update(&(pBT->blob));

            /* Predict current position: */
            pB = pBT->pPredictor->Predict();

            if(pB)
            {
                pBT->BlobPredict = pB[0];
            }
            else
            {
                pBT->BlobPredict = pBT->blob;
            }
        }   /* Predict new blob position. */

        if(m_Collision)
        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Predict collision. */
            int             Collision = 0;
            int             j;
            DefBlobTracker* pF = (DefBlobTracker*)m_BlobList.GetBlob(i-1);

            for(j=m_BlobList.GetBlobNum(); j>0; --j)
            {   /* Predict collision: */
                CvBlob* pB1;
                CvBlob* pB2;
                DefBlobTracker* pF2 = (DefBlobTracker*)m_BlobList.GetBlob(j-1);
                if(i==j) continue;
                pB1 = &pF->BlobPredict;
                pB2 = &pF2->BlobPredict;

                if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
                    fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;

                pB1 = &pF->blob;
                pB2 = &pF2->blob;

                if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
                    fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;

                if(Collision) break;

            }   /* Check next blob to cross current. */

            pF->Collision = Collision;

        }   /* Predict collision. */

        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Find a neighbour on current frame
             * for each blob from previous frame:
             */
            CvBlob*         pBl = m_BlobList.GetBlob(i-1);
            DefBlobTracker* pBT = (DefBlobTracker*)pBl;
            //int             BlobID = CV_BLOB_ID(pB);
            //CvBlob*         pBBest = NULL;
            //double          DistBest = -1;
            //int j;

            if(pBT->pBlobHyp->GetBlobNum()>0)
            {   /* Track all hypotheses: */
                int h,hN = pBT->pBlobHyp->GetBlobNum();
                for(h=0; h<hN; ++h)
                {
                    int         j, jN = m_BlobListNew.GetBlobNum();
                    CvBlob*     pB = pBT->pBlobHyp->GetBlob(h);
                    int         BlobID = CV_BLOB_ID(pB);
                    CvBlob*     pBBest = NULL;
                    double      DistBest = -1;
                    for(j=0; j<jN; j++)
                    {   /* Find best CC: */
                        double  Dist = -1;
                        CvBlob* pBNew = m_BlobListNew.GetBlob(j);
                        double  dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
                        double  dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
                        if(dx > 2*CV_BLOB_WX(pB) || dy > 2*CV_BLOB_WY(pB)) continue;

                        Dist = sqrt(dx*dx+dy*dy);
                        if(Dist < DistBest || pBBest == NULL)
                        {
                            DistBest = Dist;
                            pBBest = pBNew;
                        }
                    }   /* Find best CC. */

                    if(pBBest)
                    {
                        pB[0] = pBBest[0];
                        CV_BLOB_ID(pB) = BlobID;
                    }
                    else
                    {   /* Delete this hypothesis. */
                        pBT->pBlobHyp->DelBlob(h);
                        h--;
                        hN--;
                    }
                }   /* Next hypothysis. */
            }   /*  Track all hypotheses. */
        }   /*  Track next blob. */

        m_ClearHyp = 1;

    } /* Process. */
    virtual void    Process(IplImage* pImg, IplImage* pImgFG = NULL)
    {
        CvSeq*      cnts;
        CvSeq*      cnt;
        int i;
        //CvMat*      pMC = NULL;

        if(m_BlobList.GetBlobNum() <= 0 ) return;
        
        /* Clear blob list for new blobs: */
        m_BlobListNew.Clear();

        assert(m_pMem);
        cvClearMemStorage(m_pMem);
        assert(pImgFG);

        {   /* One contour - one blob: */
            IplImage* pBin = cvCloneImage(pImgFG);
            assert(pBin);
            cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
            cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);

            /* Process each contour: */
            for(cnt = cnts; cnt; cnt=cnt->h_next)
            {
                CvBlob  NewBlob;

                /* Image moments: */
                double      M00,X,Y,XX,YY;
                CvMoments   m;
                CvRect      r = ((CvContour*)cnt)->rect;
                CvMat       mat;
                if(r.height < 3 || r.width < 3) continue;
                cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
                M00 = cvGetSpatialMoment( &m, 0, 0 );
                if(M00 <= 0 ) continue;
                X = cvGetSpatialMoment( &m, 1, 0 )/M00;
                Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
                XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
                YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
                NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
                m_BlobListNew.AddBlob(&NewBlob);

            }   /* Next contour. */

            cvReleaseImage(&pBin);
        }

        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Predict new blob position. */
            CvBlob*             pB = NULL;
            DefBlobTrackerCR*   pBT = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);

            /* Update predictor. */
            pBT->pPredictor->Update(&(pBT->blob));
            pB = pBT->pPredictor->Predict();
            if(pB)
            {
                pBT->BlobPredict = pB[0];
            }
            pBT->BlobPrev = pBT->blob;
        }   /* Predict new blob position. */


        if(m_BlobList.GetBlobNum()>0 && m_BlobListNew.GetBlobNum()>0)
        {   /* Resolve new blob to old: */
            int i,j;
            int NOld = m_BlobList.GetBlobNum();
            int NNew = m_BlobListNew.GetBlobNum();
            
            for(i=0; i<NOld; i++)
            {   /* Set 0 collision and clear all hyp: */
                DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
                pF->Collision = 0;
                pF->pBlobHyp->Clear();
            }   /* Set 0 collision. */

            /* Create correspondence records: */
            for(j=0; j<NNew; ++j)
            {
                CvBlob*             pB1 = m_BlobListNew.GetBlob(j);
                DefBlobTrackerCR*   pFLast = NULL;
                
                for(i=0; i<NOld; i++)
                {   /* Check intersection: */
                    int Intersection = 0;
                    DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
                    CvBlob* pB2 = &(pF->BlobPredict);

                    if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
                        fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Intersection = 1;

                    if(Intersection)
                    {
                        if(pFLast)
                        {
                            pF->Collision = pFLast->Collision = 1;
                        }
                        pFLast = pF;
                        pF->pBlobHyp->AddBlob(pB1);
                    }
                }   /* Check intersection. */
            }   /*  Check next new blob. */
        }   /*  Resolve new blob to old. */

        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Track each blob. */
            CvBlob*             pB = m_BlobList.GetBlob(i-1);
            DefBlobTrackerCR*   pBT = (DefBlobTrackerCR*)pB;
            int                 BlobID = CV_BLOB_ID(pB);
          //CvBlob*             pBBest = NULL;
          //double              DistBest = -1;
            int j;

            if(pBT->pResolver)
            {
                pBT->pResolver->SetCollision(pBT->Collision);
            }
            
            if(pBT->Collision)
            {   /* Tracking in collision: */
                if(pBT->pResolver)
                {
                    pB[0] = pBT->pResolver->Process(&(pBT->BlobPredict),pImg, pImgFG)[0];
                }
            }   /* Tracking in collision. */
            else
            {   /* Non-collision tracking: */
                CvBlob  NewCC = pBT->BlobPredict;
                if(pBT->pBlobHyp->GetBlobNum()==1)
                {   /* One blob to one CC: */
                    NewCC = pBT->pBlobHyp->GetBlob(0)[0];
                }
                else
                {   /* One blob several CC: */
                    CvBlob* pBBest = NULL;
                    double  DistBest = -1;
                    double  CMax = 0;
                    for(j=pBT->pBlobHyp->GetBlobNum();j>0;--j)
                    {   /* Find best CC: */
                        CvBlob* pBNew = pBT->pBlobHyp->GetBlob(j-1);
                        if(pBT->pResolver)
                        {     /* Choose CC by confidence: */
//                            double  dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
//                            double  dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
                            double  C = pBT->pResolver->GetConfidence(pBNew,pImg, pImgFG);
                            if(C > CMax || pBBest == NULL)
                            {
                                CMax = C;
                                pBBest = pBNew;
                            }
                        }
                        else
                        {    /* Choose CC by distance: */
                            double  dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
                            double  dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
                            double  Dist = sqrt(dx*dx+dy*dy);
                            if(Dist < DistBest || pBBest == NULL)
                            {
                                DistBest = Dist;
                                pBBest = pBNew;
                            }
                        }
                    }   /* Find best CC. */
                    if(pBBest)
                        NewCC = pBBest[0];
                }   /* One blob several CC. */
                pB->x = NewCC.x;
                pB->y = NewCC.y;
                pB->w = (m_AlphaSize)*NewCC.w+(1-m_AlphaSize)*pB->w;
                pB->h = (m_AlphaSize)*NewCC.h+(1-m_AlphaSize)*pB->h;
                pBT->pResolver->SkipProcess(&(pBT->BlobPredict),pImg, pImgFG);
            }   /* Non-collision tracking. */
            
            pBT->pResolver->Update(pB, pImg, pImgFG);

            CV_BLOB_ID(pB)=BlobID;

        }   /* Track next blob. */

        if(m_Wnd)
        {
            IplImage* pI = cvCloneImage(pImg);
            int i;
            for(i=m_BlobListNew.GetBlobNum(); i>0; --i)
            {   /* Draw each new CC: */
                CvBlob* pB = m_BlobListNew.GetBlob(i-1);
                CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
                int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
                CvSize  s = cvSize(MAX(1,x), MAX(1,y));
                //int c = 255;
                cvEllipse( pI,
                    p,
                    s,
                    0, 0, 360,
                    CV_RGB(255,255,0), 1 );
            }

            for(i=m_BlobList.GetBlobNum(); i>0; --i)
            {   /* Draw each new CC: */
                DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);
                CvBlob* pB = &(pF->BlobPredict);
                CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
                int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
                CvSize  s = cvSize(MAX(1,x), MAX(1,y));
                cvEllipse( pI,
                    p,
                    s,
                    0, 0, 360,
                    CV_RGB(0,0,255), 1 );
                
                pB = &(pF->blob);
                p = cvPointFrom32f(CV_BLOB_CENTER(pB));
                x = cvRound(CV_BLOB_RX(pB)); y = cvRound(CV_BLOB_RY(pB));
                s = cvSize(MAX(1,x), MAX(1,y));
                cvEllipse( pI,
                    p,
                    s,
                    0, 0, 360,
                    CV_RGB(0,255,0), 1 );
            }

            //cvNamedWindow("CCwithCR",0);
            //cvShowImage("CCwithCR",pI);
            cvReleaseImage(&pI);
        }
        
    } /* Process. */
//将所有模块连接使用的函数
//根据这个来修改自己的
 int RunBlobTrackingAuto2323(CvCapture* pCap, CvBlobTrackerAuto* pTracker, char* fgavi_name , char* btavi_name )
{
	int                     OneFrameProcess = 0;
	int                     key;
	int                     FrameNum = 0;
	CvVideoWriter*          pFGAvi = NULL;
	CvVideoWriter*          pBTAvi = NULL;

	/* Main loop: */
	/*OneFrameProcess =0 时,为waitkey(0) 不等待了,返回-1,waitkey(1)表示等1ms,如果按键了返回按键,超时返回-1*/
	for (FrameNum = 0; pCap && (key = cvWaitKey(OneFrameProcess ? 0 : 1)) != 27;//按下esc键整个程序结束。 
		FrameNum++)
	{   /* Main loop: */// 整个程序的主循环。这个循环终止,意味着这个程序结束。
		IplImage*   pImg = NULL;
		IplImage*   pMask = NULL;

		if (key != -1)
		{
			OneFrameProcess = 1;
			if (key == 'r')OneFrameProcess = 0;
		}

		pImg = cvQueryFrame(pCap);//读取视频
		if (pImg == NULL) break;


		/* Process: */
		pTracker->Process(pImg, pMask);//处理图像。这个函数应该执行完了所有的处理过程。

		if (fgavi_name)//参数设置了fg前景要保存的文件名
		if (pTracker->GetFGMask())//前景的图像的mask存在的话,保存前景。画出团块 
		{   /* Debug FG: */
			IplImage*           pFG = pTracker->GetFGMask();//得到前景的mask
			CvSize              S = cvSize(pFG->width, pFG->height);
			static IplImage*    pI = NULL;

			if (pI == NULL)pI = cvCreateImage(S, pFG->depth, 3);
			cvCvtColor(pFG, pI, CV_GRAY2BGR);

			if (fgavi_name)//保存前景到视频
			{   /* Save fg to avi file: */
				if (pFGAvi == NULL)
				{
					pFGAvi = cvCreateVideoWriter(
						fgavi_name,
						CV_FOURCC('x', 'v', 'i', 'd'),
						25,
						S);
				}
				cvWriteFrame(pFGAvi, pI);//写入一张图
			}

			//画出团块的椭圆
			if (pTracker->GetBlobNum() > 0) //pTracker找到了blob
			{   /* Draw detected blobs: */
				int i;
				for (i = pTracker->GetBlobNum(); i > 0; i--)
				{
					CvBlob* pB = pTracker->GetBlob(i - 1);//得到第i-1个blob
					CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));//团块中心
					//这个宏竟然是个强制转换得来的。见下行。
					//#define CV_BLOB_CENTER(pB) cvPoint2D32f(((CvBlob*)(pB))->x,((CvBlob*)(pB))->y)
					CvSize  s = cvSize(MAX(1, cvRound(CV_BLOB_RX(pB))), MAX(1, cvRound(CV_BLOB_RY(pB))));
					//通过宏 获得团块的w 和h 的size
					int c = cvRound(255 * pTracker->GetState(CV_BLOB_ID(pB)));
					cvEllipse(pI,//在图中,对团块画圆
						p,
						s,
						0, 0, 360,
						CV_RGB(c, 255 - c, 0), cvRound(1 + (3 * c) / 255));
				}   /* Next blob: */;
			}
			cvNamedWindow("FG", 0);
			cvShowImage("FG", pI);
		}   /* Debug FG. *///如果要保存结果,对前景保存,画出团块


		//在原图上:找到的blob附近写下id
		/* Draw debug info: */
		if (pImg)//原始的每帧图像。
		{   /* Draw all information about test sequence: */
			char        str[1024];
			int         line_type = CV_AA;   // Change it to 8 to see non-antialiased graphics.
			CvFont      font;
			int         i;
			IplImage*   pI = cvCloneImage(pImg);

			cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 0.7, 0.7, 0, 1, line_type);

			for (i = pTracker->GetBlobNum(); i > 0; i--)
			{
				CvSize  TextSize;
				CvBlob* pB = pTracker->GetBlob(i - 1);
				CvPoint p = cvPoint(cvRound(pB->x * 256), cvRound(pB->y * 256));
				CvSize  s = cvSize(MAX(1, cvRound(CV_BLOB_RX(pB) * 256)), MAX(1, cvRound(CV_BLOB_RY(pB) * 256)));
				int c = cvRound(255 * pTracker->GetState(CV_BLOB_ID(pB)));


				//画团块到原始图像上
				cvEllipse(pI,
					p,
					s,
					0, 0, 360,
					CV_RGB(c, 255 - c, 0), cvRound(1 + (3 * 0) / 255), CV_AA, 8);


				//下面代码的大概意思就是在找到的blob附近写下id
				p.x >>= 8;
				p.y >>= 8;
				s.width >>= 8;
				s.height >>= 8;
				sprintf(str, "%03d", CV_BLOB_ID(pB));
				cvGetTextSize(str, &font, &TextSize, NULL);
				p.y -= s.height;
				cvPutText(pI, str, p, &font, CV_RGB(0, 255, 255));
				{
					const char* pS = pTracker->GetStateDesc(CV_BLOB_ID(pB));

					if (pS)
					{
						char* pStr = MY_STRDUP(pS);
						char* pStrFree = pStr;

						while (pStr && strlen(pStr) > 0)
						{
							char* str_next = strchr(pStr, '\n');

							if (str_next)
							{
								str_next[0] = 0;
								str_next++;
							}

							p.y += TextSize.height + 1;
							cvPutText(pI, pStr, p, &font, CV_RGB(0, 255, 255));
							pStr = str_next;
						}
						free(pStrFree);
					}
				}

			}   /* Next blob. */;

			cvNamedWindow("Tracking", 0);
			cvShowImage("Tracking", pI);

			if (btavi_name && pI)//如果这一帧存在且,你想把图像存起来,就是传过来的参数不为空例如  btavi_name=“1.avi"   就能存起来了。
			{   /* Save to avi file: */
				CvSize      S = cvSize(pI->width, pI->height);
				if (pBTAvi == NULL)
				{
					pBTAvi = cvCreateVideoWriter(
						btavi_name,
						CV_FOURCC('x', 'v', 'i', 'd'),
						25,
						S);
				}
				cvWriteFrame(pBTAvi, pI);
			}

			cvReleaseImage(&pI);
		}   /* Draw all information about test sequence. */
	}   /*  Main loop. */

	if (pFGAvi)cvReleaseVideoWriter(&pFGAvi);
	if (pBTAvi)cvReleaseVideoWriter(&pBTAvi);
	return 0;
}   /* RunBlobTrackingAuto */
	virtual void    Process(IplImage* pImg, IplImage* pImgFG = NULL)
	{//第一步:从前景里提取团块:位置+大小 ==》保存到m_BlobListNew链表里
		//第二步:预测团块位置 更新到各自的BlobPredict里
		//第三步:标记每个目标的碰撞
		//已经跟踪的团块链表里, 相互匹配预测位置 和当前位置。如果重合了,就将Collision=1 
		//第四步: 对于每个目标, 用他可能的位置 和新的团块链表比较,
		//求最近的一个 作为他新的可能位置。


		CvSeq*      cnts;
		CvSeq*      cnt;
		int i;

		m_pImg = pImg;
		m_pImgFG = pImgFG;

		if (m_BlobList.GetBlobNum() <= 0) return;

		/* Clear bloblist for new blobs: */
		m_BlobListNew.Clear();

		assert(m_pMem);
		cvClearMemStorage(m_pMem);
		assert(pImgFG);

		//第一步:从前景里提取团块:位置+大小 ==》保存到m_BlobListNew链表里



		//第二步:预测团块位置 更新到各自的BlobPredict里
		for (i = m_BlobList.GetBlobNum(); i>0; --i)
		{   /* Predict new blob position: */

			CvBlob*         pB = NULL;
			DefBlobTrackerColorTracker* pBT = (DefBlobTrackerColorTracker*)m_BlobList.GetBlob(i - 1);

			/* Update predictor by previous value of blob: */
			//更新上一帧的位置
			pBT->pPredictor->Update(&(pBT->blob));

			//预测下一帧位置
			/* Predict current position: */
			pB = pBT->pPredictor->Predict();

			if (pB)
			{
				pBT->BlobPredict = pB[0];
			}
			else
			{
				pBT->BlobPredict = pBT->blob;
			}
		}   /* Predict new blob position. */

		//第三步:标记每个目标的碰撞
		//已经跟踪的团块链表里, 相互匹配预测位置 和当前位置。如果重合了,就将Collision=1 
		if (m_Collision)//如果需要考虑碰撞
		for (i = m_BlobList.GetBlobNum(); i>0; --i)
		{   /* Predict collision. */
			int             Collision = 0;
			int             j;
			DefBlobTrackerColorTracker* pF = (DefBlobTrackerColorTracker*)m_BlobList.GetBlob(i - 1);

			for (j = m_BlobList.GetBlobNum(); j>0; --j)
			{   /* Predict collision: */
				CvBlob* pB1;
				CvBlob* pB2;
				DefBlobTrackerColorTracker* pF2 = (DefBlobTrackerColorTracker*)m_BlobList.GetBlob(j - 1);
				if (i == j) continue;
				pB1 = &pF->BlobPredict;
				pB2 = &pF2->BlobPredict;

				//两个团块预测位置是否碰撞了
				if (fabs(pB1->x - pB2->x)<0.6*(pB1->w + pB2->w) &&
					fabs(pB1->y - pB2->y)<0.6*(pB1->h + pB2->h)) Collision = 1;

				pB1 = &pF->blob;
				pB2 = &pF2->blob;

				//当前位置是否碰撞了
				if (fabs(pB1->x - pB2->x)<0.6*(pB1->w + pB2->w) &&
					fabs(pB1->y - pB2->y)<0.6*(pB1->h + pB2->h)) Collision = 1;

				if (Collision) break;

			}   /* Check next blob to cross current. */

			pF->Collision = Collision;

		}   /* Predict collision. */


		//第四步: 对于每个目标, 用他可能的位置 和新的团块链表比较,
		//求最近的一个 作为他新的可能位置。
		for (i = m_BlobList.GetBlobNum(); i>0; --i)
		{   /* Find a neighbour on current frame
			* for each blob from previous frame:
			*/
			CvBlob*         pBl = m_BlobList.GetBlob(i - 1);
			DefBlobTrackerColorTracker* pBT = (DefBlobTrackerColorTracker*)pBl;
			//int             BlobID = CV_BLOB_ID(pB);
			//CvBlob*         pBBest = NULL;
			//double          DistBest = -1;
			//int j;

			if (pBT->pBlobHyp->GetBlobNum()>0)//pBlobHyp难道是每个目标可能的下一个位置???
			{   /* Track all hypotheses: */

				int h, hN = pBT->pBlobHyp->GetBlobNum();
				for (h = 0; h<hN; ++h)
				{//提取每一个可能的位置 pBlobHyp,
					//和当前的前景团块链表m_BlobListNew 比较,求得最近团块,
					//将最近团块值==》赋值给pBlobHyp
					//如果最近团块也很远就删除 这个可能
					int         j, jN = m_BlobListNew.GetBlobNum();
					CvBlob*     pB = pBT->pBlobHyp->GetBlob(h);//可能的位置
					int         BlobID = CV_BLOB_ID(pB);
					CvBlob*     pBBest = NULL;
					double      DistBest = -1;
					for (j = 0; j<jN; j++)
					{   /* Find best CC: */
						double  Dist = -1;
						CvBlob* pBNew = m_BlobListNew.GetBlob(j);
						double  dx = fabs(CV_BLOB_X(pB) - CV_BLOB_X(pBNew));
						double  dy = fabs(CV_BLOB_Y(pB) - CV_BLOB_Y(pBNew));
						if (dx > 2 * CV_BLOB_WX(pB) || dy > 2 * CV_BLOB_WY(pB)) continue;

						Dist = sqrt(dx*dx + dy*dy);
						if (Dist < DistBest || pBBest == NULL)
						{
							DistBest = Dist;
							pBBest = pBNew;
						}
					}   /* Find best CC. */

					if (pBBest)
					{
						pB[0] = pBBest[0];
						CV_BLOB_ID(pB) = BlobID;
					}
					else
					{   /* Delete this hypothesis. */
						pBT->pBlobHyp->DelBlob(h);
						h--;
						hN--;
					}
				}   /* Next hypothysis. */
			}   /*  Track all hypotheses. */
		}   /*  Track next blob. */

		m_ClearHyp = 1;

	} /* Process. */
void CvBlobTrackerAuto1::Process(IplImage* pImg, IplImage* pMask)
{
    int         CurBlobNum = 0;
    int         i;
    IplImage*   pFG = pMask;

    /* Bump frame counter: */
    m_FrameCount++;

    if(m_TimesFile)
    {
        static int64  TickCount = cvGetTickCount();
        static double TimeSum = 0;
        static int Count = 0;
        Count++;

        if(Count%100==0)
        {
#ifndef WINCE
            time_t ltime;
            time( &ltime );
			char* stime = ctime( &ltime );
#else
			/* WINCE does not have above POSIX functions (time,ctime) */
			const char* stime = " wince ";
#endif
            FILE* out = fopen(m_TimesFile,"at");
            double Time;
            TickCount = cvGetTickCount()-TickCount;
            Time = TickCount/FREQ;
            if(out){fprintf(out,"- %sFrame: %d ALL_TIME - %f\n",stime,Count,Time/1000);fclose(out);}

            TimeSum = 0;
            TickCount = cvGetTickCount();
        }
    }

    /* Update BG model: */
    TIME_BEGIN()

    if(m_pFG)
    {   /* If FG detector is needed: */
        m_pFG->Process(pImg);
        pFG = m_pFG->GetMask();
    }   /* If FG detector is needed. */

    TIME_END("FGDetector",-1)

    m_pFGMask = pFG; /* For external use. */

    /*if(m_pFG && m_pFG->GetParam("DebugWnd") == 1)
    {// debug foreground result
        IplImage *pFG = m_pFG->GetMask();
        if(pFG)
        {
            cvNamedWindow("FG",0);
            cvShowImage("FG", pFG);
        }
    }*/

    /* Track blobs: */
    TIME_BEGIN()
    if(m_pBT)
    {
        int i;
        m_pBT->Process(pImg, pFG);

        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Update data of tracked blob list: */
            CvBlob* pB = m_BlobList.GetBlob(i-1);
            int     BlobID = CV_BLOB_ID(pB);
            int     i = m_pBT->GetBlobIndexByID(BlobID);
            m_pBT->ProcessBlob(i, pB, pImg, pFG);
            pB->ID = BlobID;
        }
        CurBlobNum = m_pBT->GetBlobNum();
    }
    TIME_END("BlobTracker",CurBlobNum)

    /* This part should be removed: */
    if(m_BTReal && m_pBT)
    {   /* Update blob list (detect new blob for real blob tracker): */
        int i;

        for(i=m_pBT->GetBlobNum(); i>0; --i)
        {   /* Update data of tracked blob list: */
            CvBlob* pB = m_pBT->GetBlob(i-1);
            if(pB && m_BlobList.GetBlobByID(CV_BLOB_ID(pB)) == NULL )
            {
                CvBlobTrackAuto     NewB;
                NewB.blob = pB[0];
                NewB.BadFrames = 0;
                m_BlobList.AddBlob((CvBlob*)&NewB);
            }
        }   /* Next blob. */

        /* Delete blobs: */
        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Update tracked-blob list: */
            CvBlob* pB = m_BlobList.GetBlob(i-1);
            if(pB && m_pBT->GetBlobByID(CV_BLOB_ID(pB)) == NULL )
            {
                m_BlobList.DelBlob(i-1);
            }
        }   /* Next blob. */
    }   /* Update bloblist. */


    TIME_BEGIN()
    if(m_pBTPostProc)
    {   /* Post-processing module: */
        int i;
        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Update tracked-blob list: */
            CvBlob* pB = m_BlobList.GetBlob(i-1);
            m_pBTPostProc->AddBlob(pB);
        }
        m_pBTPostProc->Process();

        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Update tracked-blob list: */
            CvBlob* pB = m_BlobList.GetBlob(i-1);
            int     BlobID = CV_BLOB_ID(pB);
            CvBlob* pBN = m_pBTPostProc->GetBlobByID(BlobID);

            if(pBN && m_UsePPData && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
            {   /* Set new data for tracker: */
                m_pBT->SetBlobByID(BlobID, pBN );
            }

            if(pBN)
            {   /* Update blob list with results from postprocessing: */
                pB[0] = pBN[0];
            }
        }
    }   /* Post-processing module. */

    TIME_END("PostProcessing",CurBlobNum)

    /* Blob deleter (experimental and simple): */
    TIME_BEGIN()
    if(pFG)
    {   /* Blob deleter: */
        int i;
        if(!m_BTReal)for(i=m_BlobList.GetBlobNum();i>0;--i)
        {   /* Check all blobs on list: */
            CvBlobTrackAuto* pB = (CvBlobTrackAuto*)(m_BlobList.GetBlob(i-1));
            int     Good = 0;
            int     w=pFG->width;
            int     h=pFG->height;
            CvRect  r = CV_BLOB_RECT(pB);
            CvMat   mat;
            double  aver = 0;
            double  area = CV_BLOB_WX(pB)*CV_BLOB_WY(pB);
            if(r.x < 0){r.width += r.x;r.x = 0;}
            if(r.y < 0){r.height += r.y;r.y = 0;}
            if(r.x+r.width>=w){r.width = w-r.x-1;}
            if(r.y+r.height>=h){r.height = h-r.y-1;}

            if(r.width > 4 && r.height > 4 && r.x < w && r.y < h &&
                r.x >=0 && r.y >=0 &&
                r.x+r.width < w && r.y+r.height < h && area > 0)
            {
                aver = cvSum(cvGetSubRect(pFG,&mat,r)).val[0] / area;
                /* if mask in blob area exists then its blob OK*/
                if(aver > 0.1*255)Good = 1;
            }
            else
            {
                pB->BadFrames+=2;
            }

            if(Good)
            {
                pB->BadFrames = 0;
            }
            else
            {
                pB->BadFrames++;
            }
        }   /* Next blob: */

        /* Check error count: */
        for(i=0; i<m_BlobList.GetBlobNum(); ++i)
        {
            CvBlobTrackAuto* pB = (CvBlobTrackAuto*)m_BlobList.GetBlob(i);

            if(pB->BadFrames>3)
            {   /* Delete such objects */
                /* from tracker...     */
                m_pBT->DelBlobByID(CV_BLOB_ID(pB));

                /* ... and from local list: */
                m_BlobList.DelBlob(i);
                i--;
            }
        }   /* Check error count for next blob. */
    }   /*  Blob deleter. */

    TIME_END("BlobDeleter",m_BlobList.GetBlobNum())

    /* Update blobs: */
    TIME_BEGIN()
    if(m_pBT)
        m_pBT->Update(pImg, pFG);
    TIME_END("BlobTrackerUpdate",CurBlobNum)

    /* Detect new blob: */
    TIME_BEGIN()
    if(!m_BTReal && m_pBD && pFG && (m_FrameCount > m_FGTrainFrames) )
    {   /* Detect new blob: */
        static CvBlobSeq    NewBlobList;
        CvBlobTrackAuto     NewB;

        NewBlobList.Clear();

        if(m_pBD->DetectNewBlob(pImg, pFG, &NewBlobList, &m_BlobList))
        {   /* Add new blob to tracker and blob list: */
            int i;
            IplImage* pMask = pFG;

            /*if(0)if(NewBlobList.GetBlobNum()>0 && pFG )
            {// erode FG mask (only for FG_0 and MS1||MS2)
                pMask = cvCloneImage(pFG);
                cvErode(pFG,pMask,NULL,2);
            }*/

            for(i=0; i<NewBlobList.GetBlobNum(); ++i)
            {
                CvBlob* pBN = NewBlobList.GetBlob(i);
                pBN->ID = m_NextBlobID;

                if(pBN && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
                {
                    CvBlob* pB = m_pBT->AddBlob(pBN, pImg, pMask );
                    if(pB)
                    {
                        NewB.blob = pB[0];
                        NewB.BadFrames = 0;
                        m_BlobList.AddBlob((CvBlob*)&NewB);
                        m_NextBlobID++;
                    }
                }
            }   /* Add next blob from list of detected blob. */

            if(pMask != pFG) cvReleaseImage(&pMask);

        }   /* Create and add new blobs and trackers. */

    }   /*  Detect new blob. */

    TIME_END("BlobDetector",-1)

    TIME_BEGIN()
    if(m_pBTGen)
    {   /* Run track generator: */
        for(i=m_BlobList.GetBlobNum(); i>0; --i)
        {   /* Update data of tracked blob list: */
            CvBlob* pB = m_BlobList.GetBlob(i-1);
            m_pBTGen->AddBlob(pB);
        }
        m_pBTGen->Process(pImg, pFG);
    }   /* Run track generator: */
    TIME_END("TrajectoryGeneration",-1)

    TIME_BEGIN()
    if(m_pBTA)
    {   /* Trajectory analysis module: */
        int i;
        for(i=m_BlobList.GetBlobNum(); i>0; i--)
            m_pBTA->AddBlob(m_BlobList.GetBlob(i-1));

        m_pBTA->Process(pImg, pFG);

    }   /* Trajectory analysis module. */

    TIME_END("TrackAnalysis",m_BlobList.GetBlobNum())

} /* CvBlobTrackerAuto1::Process */
예제 #17
0
    /*************************************************************************
    Process
        Process the frames in a video one by one.
            1) FG detection
            2) Blob Detection
            3) Blob Tracking and Association
            4) Blob Post Processing
            5) Blob Analysis
            6) Store the results
    Exceptions
        None
    *************************************************************************/
    void Camera::Process(const int startFrameIndex, const int endFrameIndex)
    {
        ASSERT_TRUE ( m_initializied );
        ASSERT_TRUE ( m_pTracker != NULL );

        InitializeDisplayWindows( );

        LOG_CONSOLE( "Start processing " + m_videoFileName );

        int key, oneFrameProcess=0, frameNum; 
        for ( frameNum = 1; 
             m_videoCap.grab() &&
            ( key = cvWaitKey( oneFrameProcess ? 0 : 1 ) ) != 27 &&
            ( frameNum <=  endFrameIndex || endFrameIndex < 0 );
            frameNum++ )
        {
            if ( frameNum >= startFrameIndex )
            {
                std::cout << "frameNum:  " << frameNum << '\r';

                // get the video frame
                m_videoCap.retrieve( m_originalFrameMat );

                // downscale the image if required
                if ( m_downScaleImage )
                {
                    cv::resize( m_originalFrameMat, m_frame,  m_frame.size() );
                }
                else
                {
                    m_frame = m_originalFrameMat;
                }

                m_frameIpl = m_frame; 

                if ( key != -1 )
                {
                    oneFrameProcess = ( key == 'r' ) ? 0 : 1;
                }

                // Process the current frame
                m_pTracker->Process( &m_frameIpl, m_pFGMaskIpl);
                m_fgMask        = m_pTracker->GetFGMask();


                // Process the current video frame using the blob tracker
                IplImage fgMaskIpl = m_fgMask;


                // Save Blob Information in a file
                for( int i = m_pTracker->GetBlobNum(); i> 0; i-- )
                {
                    CvBlob* pBlob = m_pTracker->GetBlob(i-1);

                    ASSERT_TRUE( pBlob != NULL );

                    // Save blob record
                    SaveBlobRecord( pBlob, frameNum );
                }

                if ( m_displayIntermediateResult || m_saveIntermediateResult )
                {
                    char tempString[128];
                    std::string textMessage;
                    //display intermediate result if necessary
                    CvFont    font; 
                    CvSize  TextSize;
                    cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 0.7, 0.7, 0, 1, CV_AA );

                    sprintf(tempString,"frame # %d", frameNum);
                    textMessage = tempString;
                    cv::putText( m_originalFrameMat, textMessage, cv::Point(10,20), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar((0,255,255)));
                    cv::putText( m_fgMask,textMessage, cv::Point(10,20), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar((0,255,255)));
                    cv::putText( m_frame, textMessage, cv::Point(10,20), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar((0,255,255)));

                    //drawing blobs if any with green ellipse with m_cvBlob id displayed next to it.
                    int c = 0; // 0: g; 255: red
                    for ( int i = m_pTracker->GetBlobNum(); i > 0; i-- )
                    {
                        CvBlob* pBlob = m_pTracker->GetBlob(i-1);

                        ASSERT_TRUE( pBlob != NULL );

                        cv::Point blobCorner( cvRound( pBlob->x * 256 ), cvRound( pBlob->y * 256 ) );

                        CvSize  blobSize = cvSize( MAX( 1, cvRound( CV_BLOB_RX(pBlob) * 256 ) ), 
                                                   MAX( 1, cvRound( CV_BLOB_RY(pBlob) * 256 ) ) );

                        cv::Scalar boundingBoxColor( c, 255-c, 0 );

                        if ( m_pTracker->GetState( CV_BLOB_ID( pBlob ) ) != 0 )
                        {
                            boundingBoxColor = cv::Scalar( 255-c, c, 0 );
                        }

                        cv::ellipse( m_frame, 
                                    cv::RotatedRect( cv::Point2f( pBlob->x, pBlob->y ), cv::Size2f( pBlob->w, pBlob->h ), 0 ),
                                    cv::Scalar( c, 255-c, 0 ) );
                        blobCorner.x >>= 8;      
                        blobCorner.y >>= 8;
                        
                        blobSize.width >>= 8;
                        blobSize.height >>= 8;
                        blobCorner.y -= blobSize.height;

                        sprintf( tempString, "BlobId=%03d", CV_BLOB_ID(pBlob) );
                        cvGetTextSize( tempString, &font, &TextSize, NULL );
                        
                        cv::putText( m_frame,
                                     std::string( tempString ),
                                     blobCorner,
                                     CV_FONT_HERSHEY_PLAIN,
                                     1,
                                     cv::Scalar( 255, 255, 0, 0 ) );
                    }
                }

                if ( m_displayIntermediateResult )
                {
                    cv::imshow(m_videoFileName+"_FGMask", m_fgMask);
                    cv::imshow(m_videoFileName+"_Tracking", m_frame);
                }

                if ( m_saveIntermediateResult )
                {
                    cv::Mat tmpFrame;
                    cv::cvtColor( m_fgMask, tmpFrame, CV_GRAY2BGR );
                    *m_pFGAvi << tmpFrame;             
                    *m_pBTAvi << m_frame;
                }
            }