博客已转移至个人网站(http://www.p-chao.com)
一次性输出最大连通图,速度比较快,目前还没有发现什么Bug,之前写过这个算法,这回和之前那个算法一样,只不过开放一个OpenCV接口
直接调用cvMaxLable就可以了,了解OpenCV的都懂,就不多讲了,上源码
int cvMaxLable( IplImage* imgin , IplImage* imgout )
{
int x , y;
for( y = 0; y < imgin->height; y++ )
{
uchar* ptr = (uchar*)( imgin->imageData + y * imgin->widthStep );
for( x = 0; x < imgin->width; x++ )
{
if( x == 0 || y == 0 || x == imgin->width - 1 )
ptr[x] = 0;
}
}
twopass( (unsigned char *)imgin->imageData,(unsigned char *)imgout->imageData,imgin->width,imgout->height,imgin->widthStep);
}
void twopass(unsigned char* image,unsigned char* imageget,int X_SIZE,int Y_SIZE,int X_STEP)
{
int i,j,cnt=0;
int max=0,sec=0;
int lmax;
int lsec;
int label[40960]={0};
int labelcnt[40960]={0};
int lcnt[40960]={0};
int *plabel= label;
int num,numt;
int l=0;
unsigned char a,b,c,d,e;
// int **pimage;int *imageout;
// int *pimage[Y_SIZE][X_SIZE];
// int imageout[Y_SIZE][X_SIZE];
// *(image + i*Y_SIZE + j)
int **imageout;
int ***pimage;
imageout = (int **)malloc(Y_SIZE*sizeof(int));
pimage = (int ***)malloc(Y_SIZE*sizeof(int *));
for(i=0;i<Y_SIZE;i++)
{
imageout[i] = (int *)malloc(X_SIZE*sizeof(int));
pimage[i] = (int **)malloc(X_SIZE*sizeof(int *));
}
for(i=1;i<Y_SIZE;i++)
for(j=1;j<X_SIZE-1;j++)
{
if( (i==1) && (j==1) )
{
pimage[i-1][j-1]=NULL;
pimage[i-1][j]=NULL;
pimage[i-1][j+1]=NULL;
pimage[i][j-1]=NULL;
}
else if( (i==1) && (j!=1) && (j!=X_SIZE-2) )
{
pimage[i-1][j+1]=NULL;
}
else if( (i==1) && (j==X_SIZE-2) )
{
pimage[i-1][j+1]=NULL;
pimage[i][j+1]=NULL;
}
else if( (i!=1) && (j==1))
{
pimage[i][j-1]=NULL;
}
else if( (i!=1) && (j==X_SIZE-2) )
{
pimage[i][j+1]=NULL;
}
if(*(image + i*X_STEP + j) == BLACK)
{
pimage[i][j]=NULL;
}
else
{
a= *(image + (i-1)*X_STEP + j-1);
b= *(image + (i-1)*X_STEP + j);
c= *(image + (i-1)*X_STEP + j+1);
d= *(image + i*X_STEP + j-1);
e= *(image + i*X_STEP + j);
if( (a==0) && (b==0) && (c==0) && (d==0) )
{
plabel++;cnt++;
pimage[i][j]=plabel;
}//0
else if( (a==0) && (b==0) && (c!=0) && (d==0) )
{
pimage[i][j]=pimage[i-1][j+1];
}//3
else if( (a==0) && (b==0) && (c==0) && (d!=0) )
{
pimage[i][j]=pimage[i][j-1];
}//4
else if( (a!=0) && (b==0) && (c!=0) )
{
pimage[i][j]=pimage[i-1][j-1];
numt=*(pimage[i-1][j-1]);
if(numt==0)
{
numt=(((int)pimage[i-1][j-1]-(int)label)/sizeof(int));
}
else
{
while(1)
{
if(label[numt]==0) break;
else numt=label[numt];
}
}
num=*(pimage[i-1][j+1]);
if(num==0)
{
num=(((int)pimage[i-1][j+1]-(int)label)/sizeof(int));
}
else
{
while(1)
{
if(label[num]==0) break;
else num=label[num];
}
}
if(numt!=num) label[num]=numt;
}//6
else if( (a==0) && (b!=0) )
{
pimage[i][j]=pimage[i-1][j];
}//8
else if( (a==0) && (b==0) && (c!=0) && (d!=0) )
{
pimage[i][j]=pimage[i-1][j+1];
numt=*(pimage[i][j-1]);
if(numt==0)
{
numt=(((int)pimage[i][j-1]-(int)label)/sizeof(int));
}
else
{
while(1)
{
if(label[numt]==0) break;
else numt=label[numt];
}
}
num=*(pimage[i-1][j+1]);
if(num==0)
{
num=(((int)pimage[i-1][j+1]-(int)label)/sizeof(int));
}
else
{
while(1)
{
if(label[num]==0) break;
else num=label[num];
}
}
if(numt!=num) label[num]=numt;
}//10
else
{
pimage[i][j]=pimage[i-1][j-1];
}//15
}
}
for(i=0;i<Y_SIZE;i++)
{
for(j=0;j<X_SIZE;j++)
{
if(pimage[i][j]!=NULL)
{
num=*(pimage[i][j]);
if(num==0)
{
num=(((int)pimage[i][j]-(int)label)/sizeof(int));
}
else
{
while(1)
{
if(label[num]==0) break;
else num=label[num];
}
}
if(labelcnt[num]==0)
{
l++;
labelcnt[num]=l;
}
imageout[i][j]=labelcnt[num];
lcnt[labelcnt[num]]++;
}
else imageout[i][j]=0;
}
}
for(i=0;i<l+1;i++)
{
if(lcnt[i]>max)
{
max=lcnt[i];
lmax=i;
}
}
for(i=0;i<l;i++)
if( (lcnt[i]>sec) && (lcnt[i]<max) )
{
sec=lcnt[i];
lsec=i;
}
for(i=0;i<Y_SIZE;i++)
for(j=0;j<X_SIZE;j++)
{
if(imageout[i][j]==lmax) *(imageget + i*X_STEP +j) = WHITE;
else *(imageget + i*X_STEP +j) = BLACK;
}
/* int **imageout;
int ***pimage;
imageout = (int **)malloc(Y_SIZE*sizeof(int));
pimage = (int ***)malloc(Y_SIZE*sizeof(int *));
for(i=0;i<Y_SIZE;i++)
{
imageout[i] = (int *)malloc(X_SIZE*sizeof(int));
pimage[i] = (int **)malloc(X_SIZE*sizeof(int *));
}*/
for(i=0;i<Y_SIZE;i++)
{
free(imageout[i]);
free(pimage[i]);
}
free(imageout);
free(pimage);
}