#include "cvBlobFinder.h"
cvBlobFinder::cvBlobFinder()
{
m_Blob=NULL;
m_BlobCount=0;
m_Mask=NULL;
}
cvBlobFinder::~cvBlobFinder()
{
Reset();
}
long cvBlobFinder::FindBlobs(IplImage* img,uchar threshold,double minarea,int mode,bool UseMask)
{
CvPoint seed;
CvConnectedComp lastblob;
uchar val;
int flags;
CvScalar new_val,lo_diff,up_diff;
Reset();
if (UseMask){
m_Mask=cvCreateImage(cvSize(img->width+2,img->height+2),IPL_DEPTH_8U,1);
cvZero(m_Mask);
flags=(255<<8)+CV_FLOODFILL_MASK_ONLY+CV_FLOODFILL_FIXED_RANGE+4;
}
else flags=CV_FLOODFILL_FIXED_RANGE+4;
for ( seed.x=0 ; seed.x < img->width ; seed.x++ )
{
for ( seed.y=0 ; seed.y < img->height ; seed.y++ )
{
if (UseMask&&(*(cvPtr2D(m_Mask,seed.y+1,seed.x+1))!=0)) continue;
val=*(cvPtr2D(img,seed.y,seed.x));
if (((mode==1)&&(val>=threshold))||
((mode==0)&&(val==threshold))||
((mode==-1)&&(val<=threshold)))
{
if (mode==1) {
new_val=cvScalarAll(0);
lo_diff=cvScalarAll(val-threshold);
up_diff=cvScalarAll(255-val);
}else if (mode==0) {
new_val=cvScalarAll(!threshold);
lo_diff=cvScalarAll(0);
up_diff=cvScalarAll(0);
}else if (mode==-1) {
new_val=cvScalarAll(255);
lo_diff=cvScalarAll(val);
up_diff=cvScalarAll(threshold-val);
}
cvFloodFill( img,
seed,
new_val,
lo_diff,
up_diff,
&lastblob,
flags,
m_Mask);
if (lastblob.area>=minarea){
m_Blob=(CvBlob*)realloc((void*)m_Blob,sizeof(CvBlob)*(m_BlobCount+1));
m_Blob[m_BlobCount].x=lastblob.rect.x;
m_Blob[m_BlobCount].y=lastblob.rect.y;
m_Blob[m_BlobCount].width=lastblob.rect.width;
m_Blob[m_BlobCount].height=lastblob.rect.height;
m_Blob[m_BlobCount].area=lastblob.area;
m_BlobCount++;
}
}
}
}
return m_BlobCount;
}
CvBlob* cvBlobFinder::GetBlobs()
{
return m_Blob;
}
IplImage* cvBlobFinder::GetMask()
{
return m_Mask;
}
long cvBlobFinder::GetBlobCount()
{
return m_BlobCount;
}
void cvBlobFinder::Reset()
{
if (m_Mask!=NULL) cvReleaseImage(&m_Mask);
m_Mask=NULL;
if (m_Blob!=NULL) free(m_Blob);
m_Blob=NULL;
m_BlobCount=0;
}