X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=cvaux%2Fsrc%2Fvs%2Fenteringblobdetection.cpp;fp=cvaux%2Fsrc%2Fvs%2Fenteringblobdetection.cpp;h=0000000000000000000000000000000000000000;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hp=5f3bb250adc22299d708b9c89d73374a4dde1f26;hpb=454138ff8a20f6edb9b65a910101403d8b520643;p=opencv diff --git a/cvaux/src/vs/enteringblobdetection.cpp b/cvaux/src/vs/enteringblobdetection.cpp deleted file mode 100644 index 5f3bb25..0000000 --- a/cvaux/src/vs/enteringblobdetection.cpp +++ /dev/null @@ -1,1062 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// Intel License Agreement -// -// Copyright (C) 2000, Intel Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of Intel Corporation may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -/* -This file implements the virtual interface defined as "CvBlobDetector". -This implementation based on a simple algorithm: -A new blob is detected when several successive frames contains connected components -which have uniform motion not at an unreasonably high speed. -Separation from border and already tracked blobs are also considered. - -For an entrypoint into the literature see: - - Appearance Models for Occlusion Handling - Andrew Senior &t al, 8p 2001 - http://www.research.ibm.com/peoplevision/PETS2001.pdf - -*/ - -//#define USE_OBJECT_DETECTOR - -#include "_cvaux.h" - -static int CompareContour(const void* a, const void* b, void* ) -{ - float dx,dy; - float h,w,ht,wt; - CvPoint2D32f pa,pb; - CvRect ra,rb; - CvSeq* pCA = *(CvSeq**)a; - CvSeq* pCB = *(CvSeq**)b; - ra = ((CvContour*)pCA)->rect; - rb = ((CvContour*)pCB)->rect; - pa.x = ra.x + ra.width*0.5f; - pa.y = ra.y + ra.height*0.5f; - pb.x = rb.x + rb.width*0.5f; - pb.y = rb.y + rb.height*0.5f; - w = (ra.width+rb.width)*0.5f; - h = (ra.height+rb.height)*0.5f; - - dx = (float)(fabs(pa.x - pb.x)-w); - dy = (float)(fabs(pa.y - pb.y)-h); - - //wt = MAX(ra.width,rb.width)*0.1f; - wt = 0; - ht = MAX(ra.height,rb.height)*0.3f; - return (dx < wt && dy < ht); -} - -void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage) -{ /* Create contours: */ - IplImage* pIB = NULL; - CvSeq* cnt = NULL; - CvSeq* cnt_list = cvCreateSeq(0,sizeof(CvSeq),sizeof(CvSeq*), storage ); - CvSeq* clasters = NULL; - int claster_cur, claster_num; - - pIB = cvCloneImage(pFG); - cvThreshold(pIB,pIB,128,255,CV_THRESH_BINARY); - cvFindContours(pIB,storage, &cnt, sizeof(CvContour), CV_RETR_EXTERNAL); - cvReleaseImage(&pIB); - - /* Create cnt_list. */ - /* Process each contour: */ - for(; cnt; cnt=cnt->h_next) - { - cvSeqPush( cnt_list, &cnt); - } - - claster_num = cvSeqPartition( cnt_list, storage, &clasters, CompareContour, NULL ); - - for(claster_cur=0; claster_curtotal; ++cnt_cur) - { - CvRect rect; - CvSeq* cnt; - int k = *(int*)cvGetSeqElem( clasters, cnt_cur ); - if(k!=claster_cur) continue; - cnt = *(CvSeq**)cvGetSeqElem( cnt_list, cnt_cur ); - rect = ((CvContour*)cnt)->rect; - - if(rect_res.height<0) - { - rect_res = rect; - } - else - { /* Unite rects: */ - int x0,x1,y0,y1; - x0 = MIN(rect_res.x,rect.x); - y0 = MIN(rect_res.y,rect.y); - x1 = MAX(rect_res.x+rect_res.width,rect.x+rect.width); - y1 = MAX(rect_res.y+rect_res.height,rect.y+rect.height); - rect_res.x = x0; - rect_res.y = y0; - rect_res.width = x1-x0; - rect_res.height = y1-y0; - } - } - - if(rect_res.height < 1 || rect_res.width < 1) - { - X = 0; - Y = 0; - XX = 0; - YY = 0; - } - else - { - cvMoments( cvGetSubRect(pFG,&mat,rect_res), &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(rect_res.x+(float)X,rect_res.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY))); - pBlobs->AddBlob(&NewBlob); - - } /* Next cluster. */ - - #if 0 - { // Debug info: - IplImage* pI = cvCreateImage(cvSize(pFG->width,pFG->height),IPL_DEPTH_8U,3); - cvZero(pI); - for(claster_cur=0; claster_curtotal; ++cnt_cur) - { - CvSeq* cnt; - int k = *(int*)cvGetSeqElem( clasters, cnt_cur ); - if(k!=claster_cur) continue; - cnt = *(CvSeq**)cvGetSeqElem( cnt_list, cnt_cur ); - cvDrawContours( pI, cnt, color, color, 0, 1, 8); - } - - CvBlob* pB = pBlobs->GetBlob(claster_cur); - int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB)); - cvEllipse( pI, - cvPointFrom32f(CV_BLOB_CENTER(pB)), - cvSize(MAX(1,x), MAX(1,y)), - 0, 0, 360, - color, 1 ); - } - - cvNamedWindow( "Clusters", 0); - cvShowImage( "Clusters",pI ); - - cvReleaseImage(&pI); - - } /* Debug info. */ - #endif - -} /* cvFindBlobsByCCClasters */ - -/* Simple blob detector. */ -/* Number of successive frame to analyse: */ -#define EBD_FRAME_NUM 5 -class CvBlobDetectorSimple:public CvBlobDetector -{ -public: - CvBlobDetectorSimple(); - ~CvBlobDetectorSimple(); - int DetectNewBlob(IplImage* pImg, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList); - void Release(){delete this;}; - -protected: - IplImage* m_pMaskBlobNew; - IplImage* m_pMaskBlobExist; - /* Lists of connected components detected on previous frames: */ - CvBlobSeq* m_pBlobLists[EBD_FRAME_NUM]; -}; - -/* Blob detector creator (sole interface function for this file) */ -CvBlobDetector* cvCreateBlobDetectorSimple(){return new CvBlobDetectorSimple;}; - -/* Constructor of BlobDetector: */ -CvBlobDetectorSimple::CvBlobDetectorSimple() -{ - int i = 0; - m_pMaskBlobNew = NULL; - m_pMaskBlobExist = NULL; - for(i=0;iwidth,pFGMask->height); - if(m_pMaskBlobNew == NULL ) m_pMaskBlobNew = cvCreateImage(S,IPL_DEPTH_8U,1); - if(m_pMaskBlobExist == NULL ) m_pMaskBlobExist = cvCreateImage(S,IPL_DEPTH_8U,1); - - /* Shift blob list: */ - { - int i; - if(m_pBlobLists[0]) delete m_pBlobLists[0]; - for(i=1;ih_next) - { - CvBlob NewBlob; - - /* Image moments: */ - double M00,X,Y,XX,YY; - CvMoments m; - CvRect r = ((CvContour*)cnt)->rect; - CvMat mat; - - if(r.height < S.height*0.02 || r.width < S.width*0.02) continue; - - cvMoments( cvGetSubRect(m_pMaskBlobNew,&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))); - - Blobs.AddBlob(&NewBlob); - - } /* Next contour. */ - - cvReleaseImage(&pIB); - - } /* One contour - one blob. */ -#endif - - { /* Delete small and intersected blobs: */ - int i; - for(i=Blobs.GetBlobNum(); i>0; i--) - { - CvBlob* pB = Blobs.GetBlob(i-1); - - if(pB->h < S.height*0.02 || pB->w < S.width*0.02) - { - Blobs.DelBlob(i-1); - continue; - } - if(pOldBlobList) - { - int j; - for(j=pOldBlobList->GetBlobNum(); j>0; j--) - { - CvBlob* pBOld = pOldBlobList->GetBlob(j-1); - if((fabs(pBOld->x-pB->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pB))) && - (fabs(pBOld->y-pB->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pB)))) - { /* Intersection is present, so delete blob from list: */ - Blobs.DelBlob(i-1); - break; - } - } /* Check next old blob. */ - } /* if pOldBlobList */ - } /* Check next blob. */ - } /* Delete small and intersected blobs. */ - - { /* Bubble-sort blobs by size: */ - int N = Blobs.GetBlobNum(); - int i,j; - for(i=1; i0; --j) - { - CvBlob temp; - float AreaP, AreaN; - CvBlob* pP = Blobs.GetBlob(j-1); - CvBlob* pN = Blobs.GetBlob(j); - AreaP = CV_BLOB_WX(pP)*CV_BLOB_WY(pP); - AreaN = CV_BLOB_WX(pN)*CV_BLOB_WY(pN); - if(AreaN < AreaP)break; - temp = pN[0]; - pN[0] = pP[0]; - pP[0] = temp; - } - } - - /* Copy only first 10 blobs: */ - for(i=0; iAddBlob(Blobs.GetBlob(i)); - } - - } /* Sort blobs by size. */ - - cvReleaseMemStorage(&storage); - - } /* Create blobs. */ - - /* Analyze blob list to find best blob trajectory: */ - { - int Count = 0; - int pBLIndex[EBD_FRAME_NUM]; - int pBL_BEST[EBD_FRAME_NUM]; - int i; - int finish = 0; - double BestError = -1; - int Good = 1; - - for(i=0; iGetBlobNum() == 0) - Good = 0; - - if(Good) - do{ /* For each configuration: */ - CvBlob* pBL[EBD_FRAME_NUM]; - int Good = 1; - double Error = 0; - CvBlob* pBNew = m_pBlobLists[EBD_FRAME_NUM-1]->GetBlob(pBLIndex[EBD_FRAME_NUM-1]); - - for(i=0; iGetBlob(pBLIndex[i]); - - Count++; - - /* Check intersection last blob with existed: */ - if(Good && pOldBlobList) - { /* Check intersection last blob with existed: */ - int k; - for(k=pOldBlobList->GetBlobNum(); k>0; --k) - { - CvBlob* pBOld = pOldBlobList->GetBlob(k-1); - if((fabs(pBOld->x-pBNew->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pBNew))) && - (fabs(pBOld->y-pBNew->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pBNew)))) - Good = 0; - } - } /* Check intersection last blob with existed. */ - - /* Check distance to image border: */ - if(Good) - { /* Check distance to image border: */ - CvBlob* pB = pBNew; - float dx = MIN(pB->x,S.width-pB->x)/CV_BLOB_RX(pB); - float dy = MIN(pB->y,S.height-pB->y)/CV_BLOB_RY(pB); - - if(dx < 1.1 || dy < 1.1) Good = 0; - } /* Check distance to image border. */ - - /* Check uniform motion: */ - if(Good) - { - int N = EBD_FRAME_NUM; - float sum[2] = {0,0}; - float jsum[2] = {0,0}; - float a[2],b[2]; /* estimated parameters of moving x(t) = a*t+b*/ - - int j; - for(j=0; jx; - float y = pBL[j]->y; - sum[0] += x; - jsum[0] += j*x; - sum[1] += y; - jsum[1] += j*y; - } - - a[0] = 6*((1-N)*sum[0]+2*jsum[0])/(N*(N*N-1)); - b[0] = -2*((1-2*N)*sum[0]+3*jsum[0])/(N*(N+1)); - a[1] = 6*((1-N)*sum[1]+2*jsum[1])/(N*(N*N-1)); - b[1] = -2*((1-2*N)*sum[1]+3*jsum[1])/(N*(N+1)); - - for(j=0; jx,2)+ - pow(a[1]*j+b[1]-pBL[j]->y,2); - } - - Error = sqrt(Error/N); - - if( Error > S.width*0.01 || - fabs(a[0])>S.width*0.1 || - fabs(a[1])>S.height*0.1) - Good = 0; - - } /* Check configuration. */ - - - /* New best trajectory: */ - if(Good && (BestError == -1 || BestError > Error)) - { - for(i=0; iGetBlobNum()) break; - pBLIndex[i]=0; - } /* Next time shift. */ - - if(i==EBD_FRAME_NUM)finish=1; - - } while(!finish); /* Check next time configuration of connected components. */ - - #if 0 - {/**/ - printf("BlobDetector configurations = %d [",Count); - int i; - for(i=0; iGetBlobNum():0); - } - printf("]\n"); - - } - #endif - - if(BestError != -1) - { /* Write new blob to output and delete from blob list: */ - CvBlob* pNewBlob = m_pBlobLists[EBD_FRAME_NUM-1]->GetBlob(pBL_BEST[EBD_FRAME_NUM-1]); - pNewBlobList->AddBlob(pNewBlob); - - for(i=0; iDelBlob(pBL_BEST[i]); - } /* Remove blob from each list. */ - - result = 1; - - } /* Write new blob to output and delete from blob list. */ - } /* Analyze blob list to find best blob trajectory. */ - - return result; - -} /* cvDetectNewBlob */ - - - - -/* Simple blob detector2. */ -/* Number of successive frames to analyse: */ -#define SEQ_SIZE_MAX 30 -#define SEQ_NUM 1000 -typedef struct -{ - int size; - CvBlob* pBlobs[SEQ_SIZE_MAX]; -} DefSeq; - -class CvBlobDetectorCC:public CvBlobDetector -{ -public: - CvBlobDetectorCC(); - ~CvBlobDetectorCC(); - int DetectNewBlob(IplImage* pImg, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList); - void Release(){delete this;}; - - virtual void ParamUpdate() - { - if(SEQ_SIZE<1)SEQ_SIZE=1; - if(SEQ_SIZE>SEQ_SIZE_MAX)SEQ_SIZE=SEQ_SIZE_MAX; - -#ifdef USE_OBJECT_DETECTOR - if( m_param_split_detector_file_name ) - { - m_split_detector = new CvObjectDetector(); - if( !m_split_detector->Load( m_param_split_detector_file_name ) ) - { - delete m_split_detector; - m_split_detector = 0; - } - else - { - m_min_window_size = m_split_detector->GetMinWindowSize(); - m_max_border = m_split_detector->GetMaxBorderSize(); - } - } -#endif - } - -private: - /* Lists of connected components detected on previous frames: */ - CvBlobSeq* m_pBlobLists[SEQ_SIZE_MAX]; - DefSeq m_TrackSeq[SEQ_NUM]; - int m_TrackNum; - float m_HMin; - float m_WMin; - float m_MinDistToBorder; - int m_Clastering; - int SEQ_SIZE; - - /* If not 0 then the detector is loaded from the specified file - * and it is applied for splitting blobs which actually correspond - * to groups of objects: - */ - char* m_param_split_detector_file_name; - float m_param_roi_scale; - int m_param_only_roi; - - CvObjectDetector* m_split_detector; - CvSize m_min_window_size; - int m_max_border; - - CvBlobSeq m_detected_blob_seq; - CvSeq* m_roi_seq; - - CvBlobSeq m_debug_blob_seq; -}; - -/* Blob detector creator (sole interface function for this file): */ -CvBlobDetector* cvCreateBlobDetectorCC(){return new CvBlobDetectorCC;} - -/* Constructor for BlobDetector: */ -CvBlobDetectorCC::CvBlobDetectorCC() : - m_split_detector(0), - m_detected_blob_seq(sizeof(CvDetectedBlob)), - m_roi_seq(0), - m_debug_blob_seq(sizeof(CvDetectedBlob)) -{ - /*CvDrawShape shapes[] = - { - { CvDrawShape::RECT, {{255,255,255}} }, - { CvDrawShape::RECT, {{0,0,255}} }, - { CvDrawShape::ELLIPSE, {{0,255,0}} } - }; - int num_shapes = sizeof(shapes) / sizeof(shapes[0]);*/ - - int i = 0; - SEQ_SIZE = 10; - AddParam("Latency",&SEQ_SIZE); - for(i=0;istorage ); - m_roi_seq = 0; - } - //cvDestroyWindow( "EnteringBlobDetectionDebug" ); -} /* cvReleaseBlobDetector */ - - -/* cvDetectNewBlobs - * Return 1 and fill blob pNewBlob with - * blob parameters if new blob is detected: - */ -int CvBlobDetectorCC::DetectNewBlob(IplImage* /*pImg*/, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList) -{ - int result = 0; - CvSize S = cvSize(pFGMask->width,pFGMask->height); - - /* Shift blob list: */ - { - int i; - if(m_pBlobLists[SEQ_SIZE-1]) delete m_pBlobLists[SEQ_SIZE-1]; - - for(i=SEQ_SIZE-1; i>0; --i) m_pBlobLists[i] = m_pBlobLists[i-1]; - - m_pBlobLists[0] = new CvBlobSeq; - - } /* Shift blob list. */ - - /* Create contours and add new blobs to blob list: */ - { /* Create blobs: */ - CvBlobSeq Blobs; - CvMemStorage* storage = cvCreateMemStorage(); - - if(m_Clastering) - { /* Glue contours: */ - cvFindBlobsByCCClasters(pFGMask, &Blobs, storage ); - } /* Glue contours. */ - else - { /**/ - IplImage* pIB = cvCloneImage(pFGMask); - CvSeq* cnts = NULL; - CvSeq* cnt = NULL; - cvThreshold(pIB,pIB,128,255,CV_THRESH_BINARY); - cvFindContours(pIB,storage, &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 < S.height*m_HMin || r.width < S.width*m_WMin) continue; - cvMoments( cvGetSubRect(pFGMask,&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))); - Blobs.AddBlob(&NewBlob); - - } /* Next contour. */ - - cvReleaseImage(&pIB); - - } /* One contour - one blob. */ - - { /* Delete small and intersected blobs: */ - int i; - for(i=Blobs.GetBlobNum(); i>0; i--) - { - CvBlob* pB = Blobs.GetBlob(i-1); - - if(pB->h < S.height*m_HMin || pB->w < S.width*m_WMin) - { - Blobs.DelBlob(i-1); - continue; - } - - if(pOldBlobList) - { - int j; - for(j=pOldBlobList->GetBlobNum(); j>0; j--) - { - CvBlob* pBOld = pOldBlobList->GetBlob(j-1); - if((fabs(pBOld->x-pB->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pB))) && - (fabs(pBOld->y-pB->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pB)))) - { /* Intersection detected, delete blob from list: */ - Blobs.DelBlob(i-1); - break; - } - } /* Check next old blob. */ - } /* if pOldBlobList. */ - } /* Check next blob. */ - } /* Delete small and intersected blobs. */ - - { /* Bubble-sort blobs by size: */ - int N = Blobs.GetBlobNum(); - int i,j; - for(i=1; i0; --j) - { - CvBlob temp; - float AreaP, AreaN; - CvBlob* pP = Blobs.GetBlob(j-1); - CvBlob* pN = Blobs.GetBlob(j); - AreaP = CV_BLOB_WX(pP)*CV_BLOB_WY(pP); - AreaN = CV_BLOB_WX(pN)*CV_BLOB_WY(pN); - if(AreaN < AreaP)break; - temp = pN[0]; - pN[0] = pP[0]; - pP[0] = temp; - } - } - - /* Copy only first 10 blobs: */ - for(i=0; iAddBlob(Blobs.GetBlob(i)); - } - - } /* Sort blobs by size. */ - - cvReleaseMemStorage(&storage); - - } /* Create blobs. */ - - { /* Shift each track: */ - int j; - for(j=0; j0; --i) - pTrack->pBlobs[i] = pTrack->pBlobs[i-1]; - - pTrack->pBlobs[0] = NULL; - if(pTrack->size == SEQ_SIZE)pTrack->size--; - } - } /* Shift each track. */ - - /* Analyze blob list to find best blob trajectory: */ - { - double BestError = -1; - int BestTrack = -1;; - CvBlobSeq* pNewBlobs = m_pBlobLists[0]; - int i; - int NewTrackNum = 0; - for(i=pNewBlobs->GetBlobNum(); i>0; --i) - { - CvBlob* pBNew = pNewBlobs->GetBlob(i-1); - int j; - int AsignedTrack = 0; - for(j=0; jsize>0?pTrack->pBlobs[1]:NULL; - if(pLastBlob == NULL) continue; - dx = fabs(CV_BLOB_X(pLastBlob)-CV_BLOB_X(pBNew)); - dy = fabs(CV_BLOB_Y(pLastBlob)-CV_BLOB_Y(pBNew)); - if(dx > 2*CV_BLOB_WX(pLastBlob) || dy > 2*CV_BLOB_WY(pLastBlob)) continue; - AsignedTrack++; - - if(pTrack->pBlobs[0]==NULL) - { /* Fill existed track: */ - pTrack->pBlobs[0] = pBNew; - pTrack->size++; - } - else if((m_TrackNum+NewTrackNum)pBlobs[0]; - if(pTrack->size != SEQ_SIZE) continue; - if(pBNew == NULL ) continue; - - /* Check intersection last blob with existed: */ - if(Good && pOldBlobList) - { - int k; - for(k=pOldBlobList->GetBlobNum(); k>0; --k) - { - CvBlob* pBOld = pOldBlobList->GetBlob(k-1); - if((fabs(pBOld->x-pBNew->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pBNew))) && - (fabs(pBOld->y-pBNew->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pBNew)))) - Good = 0; - } - } /* Check intersection last blob with existed. */ - - /* Check distance to image border: */ - if(Good) - { /* Check distance to image border: */ - float dx = MIN(pBNew->x,S.width-pBNew->x)/CV_BLOB_RX(pBNew); - float dy = MIN(pBNew->y,S.height-pBNew->y)/CV_BLOB_RY(pBNew); - if(dx < m_MinDistToBorder || dy < m_MinDistToBorder) Good = 0; - } /* Check distance to image border. */ - - /* Check uniform motion: */ - if(Good) - { /* Check uniform motion: */ - double Error = 0; - int N = pTrack->size; - CvBlob** pBL = pTrack->pBlobs; - float sum[2] = {0,0}; - float jsum[2] = {0,0}; - float a[2],b[2]; /* estimated parameters of moving x(t) = a*t+b*/ - int j; - - for(j=0; jx; - float y = pBL[j]->y; - sum[0] += x; - jsum[0] += j*x; - sum[1] += y; - jsum[1] += j*y; - } - - a[0] = 6*((1-N)*sum[0]+2*jsum[0])/(N*(N*N-1)); - b[0] = -2*((1-2*N)*sum[0]+3*jsum[0])/(N*(N+1)); - a[1] = 6*((1-N)*sum[1]+2*jsum[1])/(N*(N*N-1)); - b[1] = -2*((1-2*N)*sum[1]+3*jsum[1])/(N*(N+1)); - - for(j=0; jx,2)+ - pow(a[1]*j+b[1]-pBL[j]->y,2); - } - - Error = sqrt(Error/N); - - if( Error > S.width*0.01 || - fabs(a[0])>S.width*0.1 || - fabs(a[1])>S.height*0.1) - Good = 0; - - /* New best trajectory: */ - if(Good && (BestError == -1 || BestError > Error)) - { /* New best trajectory: */ - BestTrack = i; - BestError = Error; - } /* New best trajectory. */ - } /* Check uniform motion. */ - } /* Next track. */ - - #if 0 - { /**/ - printf("BlobDetector configurations = %d [",m_TrackNum); - int i; - for(i=0; iGetBlobNum():0); - } - printf("]\n"); - } - #endif - - if(BestTrack >= 0) - { /* Put new blob to output and delete from blob list: */ - assert(m_TrackSeq[BestTrack].size == SEQ_SIZE); - assert(m_TrackSeq[BestTrack].pBlobs[0]); - pNewBlobList->AddBlob(m_TrackSeq[BestTrack].pBlobs[0]); - m_TrackSeq[BestTrack].pBlobs[0] = NULL; - m_TrackSeq[BestTrack].size--; - result = 1; - } /* Put new blob to output and mark in blob list to delete. */ - } /* Analyze blod list to find best blob trajectory. */ - - { /* Delete bad tracks: */ - int i; - for(i=m_TrackNum-1; i>=0; --i) - { /* Delete bad tracks: */ - if(m_TrackSeq[i].pBlobs[0]) continue; - if(m_TrackNum>0) - m_TrackSeq[i] = m_TrackSeq[--m_TrackNum]; - } /* Delete bad tracks: */ - } - -#ifdef USE_OBJECT_DETECTOR - if( m_split_detector && pNewBlobList->GetBlobNum() > 0 ) - { - int num_new_blobs = pNewBlobList->GetBlobNum(); - int i = 0; - - if( m_roi_seq ) cvClearSeq( m_roi_seq ); - m_debug_blob_seq.Clear(); - for( i = 0; i < num_new_blobs; ++i ) - { - CvBlob* b = pNewBlobList->GetBlob(i); - CvMat roi_stub; - CvMat* roi_mat = 0; - CvMat* scaled_roi_mat = 0; - - CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 0 ); - m_debug_blob_seq.AddBlob(&d_b); - - float scale = m_param_roi_scale * m_min_window_size.height / CV_BLOB_WY(b); - - float b_width = MAX(CV_BLOB_WX(b), m_min_window_size.width / scale) - + (m_param_roi_scale - 1.0F) * (m_min_window_size.width / scale) - + 2.0F * m_max_border / scale; - float b_height = CV_BLOB_WY(b) * m_param_roi_scale + 2.0F * m_max_border / scale; - - CvRect roi = cvRectIntersection( cvRect( cvFloor(CV_BLOB_X(b) - 0.5F*b_width), - cvFloor(CV_BLOB_Y(b) - 0.5F*b_height), - cvCeil(b_width), cvCeil(b_height) ), - cvRect( 0, 0, pImg->width, pImg->height ) ); - if( roi.width <= 0 || roi.height <= 0 ) - continue; - - if( m_roi_seq ) cvSeqPush( m_roi_seq, &roi ); - - roi_mat = cvGetSubRect( pImg, &roi_stub, roi ); - scaled_roi_mat = cvCreateMat( cvCeil(scale*roi.height), cvCeil(scale*roi.width), CV_8UC3 ); - cvResize( roi_mat, scaled_roi_mat ); - - m_detected_blob_seq.Clear(); - m_split_detector->Detect( scaled_roi_mat, &m_detected_blob_seq ); - cvReleaseMat( &scaled_roi_mat ); - - for( int k = 0; k < m_detected_blob_seq.GetBlobNum(); ++k ) - { - CvDetectedBlob* b = (CvDetectedBlob*) m_detected_blob_seq.GetBlob(k); - - /* scale and shift each detected blob back to the original image coordinates */ - CV_BLOB_X(b) = CV_BLOB_X(b) / scale + roi.x; - CV_BLOB_Y(b) = CV_BLOB_Y(b) / scale + roi.y; - CV_BLOB_WX(b) /= scale; - CV_BLOB_WY(b) /= scale; - - CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 1, - b->response ); - m_debug_blob_seq.AddBlob(&d_b); - } - - if( m_detected_blob_seq.GetBlobNum() > 1 ) - { - /* - * Split blob. - * The original blob is replaced by the first detected blob, - * remaining detected blobs are added to the end of the sequence: - */ - CvBlob* first_b = m_detected_blob_seq.GetBlob(0); - CV_BLOB_X(b) = CV_BLOB_X(first_b); CV_BLOB_Y(b) = CV_BLOB_Y(first_b); - CV_BLOB_WX(b) = CV_BLOB_WX(first_b); CV_BLOB_WY(b) = CV_BLOB_WY(first_b); - - for( int j = 1; j < m_detected_blob_seq.GetBlobNum(); ++j ) - { - CvBlob* detected_b = m_detected_blob_seq.GetBlob(j); - pNewBlobList->AddBlob(detected_b); - } - } - } /* For each new blob. */ - - for( i = 0; i < pNewBlobList->GetBlobNum(); ++i ) - { - CvBlob* b = pNewBlobList->GetBlob(i); - CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 2 ); - m_debug_blob_seq.AddBlob(&d_b); - } - } // if( m_split_detector ) -#endif - - return result; - -} /* cvDetectNewBlob */ - -