一次性输出最大连通图,速度比较快,目前还没有发现什么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); }