📄 enteringblobdetection.cpp
字号:
/* 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 is present, delete blob from list*/
Blobs.DelBlob(i-1);
break;
}
}/* checl 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;i<N;++i)
{
for(j=i;j>0;--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;i<MIN(N,10);++i)
{
m_pBlobLists[0]->AddBlob(Blobs.GetBlob(i));
}
}/* sort blobs by size */
cvReleaseMemStorage(&storage);
}/* create Blobs */
{/* shift each track */
int j;
for(j=0;j<m_TrackNum;++j)
{
int i;
DefSeq* pTrack = m_TrackSeq+j;
for(i=SEQ_SIZE-1;i>0;--i)pTrack->pBlobs[i]=pTrack->pBlobs[i-1];
pTrack->pBlobs[0] = NULL;
if(pTrack->size == SEQ_SIZE)pTrack->size--;
}
}/* shift each track */
/* analize blob list to find best blob trajectory */
{/* analize 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;j<m_TrackNum;++j)
{
double dx,dy;
DefSeq* pTrack = m_TrackSeq+j;
CvBlob* pLastBlob = pTrack->size>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)<SEQ_NUM)
{ /* duplicate existed track */
m_TrackSeq[m_TrackNum+NewTrackNum] = pTrack[0];
m_TrackSeq[m_TrackNum+NewTrackNum].pBlobs[0] = pBNew;
NewTrackNum++;
}
}/* next track */
if(AsignedTrack==0 && (m_TrackNum+NewTrackNum)<SEQ_NUM )
{/* init new track */
m_TrackSeq[m_TrackNum+NewTrackNum].size = 1;
m_TrackSeq[m_TrackNum+NewTrackNum].pBlobs[0] = pBNew;
NewTrackNum++;
}
}/* next new blob */
m_TrackNum += NewTrackNum;
/* check each track */
for(i=0;i<m_TrackNum;++i)
{
int Good = 1;
DefSeq* pTrack = m_TrackSeq+i;
CvBlob* pBNew = pTrack->pBlobs[0];
if(pTrack->size != SEQ_SIZE) continue;
if(pBNew == NULL ) continue;
/* 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 */
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 moveing */
if(Good)
{/* check uniform moveing */
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;j<N;++j)
{
float x = pBL[j]->x;
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;j<N;++j)
{
Error +=
pow(a[0]*j+b[0]-pBL[j]->x,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 moveing */
}/* next track */
#if 0
{/**/
printf("BlobDetector configurations = %d [",m_TrackNum);
int i;
for(i=0;i<SEQ_SIZE;++i)
{
printf("%d,",m_pBlobLists[i]?m_pBlobLists[i]->GetBlobNum():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--;
res = 1;
}/* put new blob to output and mark in blob list to delete*/
}/* analize 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 res;
}/* cvDetectNewBlob */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -