源码在最后,这是函数原型说明
函数效果演示,参见我的其它博客
http://blog.csdn.net/pc1377318286/article/details/41414507
以及:
http://blog.csdn.net/pc1377318286/article/details/30966877
#define WHITE 255 #define BLACK 0 #include <stdio.h> #include <malloc.h> #include "cv.h" int cvMaxLable( IplImage* imgin , IplImage* imgout ); int twopass(unsigned char* image,unsigned char* imageget,int size[2]); int imareaopen(unsigned char *image,unsigned char *imageget,int areasize,int size[2]);
以上是调用声明,其中后两个函数不需要OpenCV的声明
第一个:
int cvtwopass(unsigned char* image,unsigned char* imageget,int size[2]) { int i,j,cnt=0; int max=0,sec=0; int lmax; int lsec; int *label=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //索引数组,plabel直接指向的标记索引号区间 int *labelcnt=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //标注数组,处理过标记冲突的索引号,其数组最终大小即为连通图个数 int *lcnt=(int *)calloc(size[0]*size[1]/8,sizeof(int)); //计数数组,统计每个连通图的大小 int *plabel= label; int num,numt; int l=0; int xstep; unsigned char a,b,c,d,e; int **imageout; int ***pimage; imageout = (int **)malloc(size[1]*sizeof(int)); pimage = (int ***)malloc(size[1]*sizeof(int *)); for(i=0;i<size[1];i++) { imageout[i] = (int *)malloc(size[0]*sizeof(int)); pimage[i] = (int **)malloc(size[0]*sizeof(int *)); } if(size[0]%4 == 0) xstep = size[0]; else xstep = size[0] + 4 - size[0]%4; for(i=1;i<size[1];i++) for(j=1;j<size[0]-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!=size[0]-2) ) { pimage[i-1][j+1]=NULL; } else if( (i==1) && (j==size[0]-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==size[0]-2) ) { pimage[i][j+1]=NULL; } if(*(image + i*xstep + j) == BLACK) { pimage[i][j]=NULL; } else { a= *(image + (i-1)*xstep + j-1); b= *(image + (i-1)*xstep + j); c= *(image + (i-1)*xstep + j+1); d= *(image + i*xstep + j-1); e= *(image + i*xstep + 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<size[1];i++) { for(j=0;j<size[0];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<size[1];i++) for(j=0;j<size[0];j++) { if(imageout[i][j]==lmax) *(imageget + i*xstep +j) = WHITE; else *(imageget + i*xstep +j) = BLACK; } for(i=0;i<size[1];i++) { free(imageout[i]); free(pimage[i]); } free(imageout); free(pimage); free(label); free(labelcnt); free(lcnt); return 0; } int cvMaxLable( IplImage* imgin , IplImage* imgout ) { int x , y; int size[2] = { imgin->width , imgout->height }; 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; } } cvtwopass( (unsigned char *)imgin->imageData,(unsigned char *)imgout->imageData,size); return 0; }
第二个:
int twopass(unsigned char* image,unsigned char* imageget,int size[2]) { int i,j,cnt=0; int max=0,sec=0; int lmax; int lsec; int *label=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //索引数组,plabel直接指向的标记索引号区间 int *labelcnt=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //标注数组,处理过标记冲突的索引号,其数组最终大小即为连通图个数 int *lcnt=(int *)calloc(size[0]*size[1]/8,sizeof(int)); //计数数组,统计每个连通图的大小 int *plabel= label; int num,numt; int l=0; unsigned char a,b,c,d,e; int **imageout; int ***pimage; imageout = (int **)malloc(size[1]*sizeof(int)); pimage = (int ***)malloc(size[1]*sizeof(int *)); for(i=0;i<size[1];i++) { imageout[i] = (int *)malloc(size[0]*sizeof(int)); pimage[i] = (int **)malloc(size[0]*sizeof(int *)); } for(i=1;i<size[1];i++) for(j=1;j<size[0]-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!=size[0]-2) ) { pimage[i-1][j+1]=NULL; } else if( (i==1) && (j==size[0]-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==size[0]-2) ) { pimage[i][j+1]=NULL; } if(*(image + i*size[0] + j) == BLACK) { pimage[i][j]=NULL; } else { a= *(image + (i-1)*size[0] + j-1); b= *(image + (i-1)*size[0] + j); c= *(image + (i-1)*size[0] + j+1); d= *(image + i*size[0] + j-1); e= *(image + i*size[0] + 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<size[1];i++) { for(j=0;j<size[0];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<size[1];i++) for(j=0;j<size[0];j++) { if(imageout[i][j]==lmax) *(imageget + i*size[0] +j) = WHITE; else *(imageget + i*size[0] +j) = BLACK; } /* int **imageout; int ***pimage; imageout = (int **)malloc(size[1]*sizeof(int)); pimage = (int ***)malloc(size[1]*sizeof(int *)); for(i=0;i<size[1];i++) { imageout[i] = (int *)malloc(size[0]*sizeof(int)); pimage[i] = (int **)malloc(size[0]*sizeof(int *)); }*/ for(i=0;i<size[1];i++) { free(imageout[i]); free(pimage[i]); } free(imageout); free(pimage); return 0; }
第三个:
int imareaopen(unsigned char *image,unsigned char *imageget,int areasize,int size[2]) { int i,j,cnt=0; int max=0,sec=0; int lmax; int *label=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //索引数组,plabel直接指向的标记索引号区间 int *labelcnt=(int *)calloc(size[0]*size[1]/2,sizeof(int)); //标注数组,处理过标记冲突的索引号,其数组最终大小即为连通图个数 int *lcnt=(int *)calloc(size[0]*size[1]/8,sizeof(int)); //计数数组,统计每个连通图的大小 int *plabel= label; int num,numt; int l=0; unsigned char a,b,c,d; int **imageout; int ***pimage; //申请等大数组空间 imageout = (int **)malloc(size[1]*sizeof(int)); pimage = (int ***)malloc(size[1]*sizeof(int *)); for(i=0;i<size[1];i++) { imageout[i] = (int *)malloc(size[0]*sizeof(int)); pimage[i] = (int **)malloc(size[0]*sizeof(int *)); } for(i=1;i<size[1];i++) for(j=1;j<size[0]-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!=size[0]-2) ) { pimage[i-1][j+1]=NULL; } else if( (i==1) && (j==size[0]-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==size[0]-2) ) { pimage[i][j+1]=NULL; } if(*(image + i * size[0] + j)==BLACK) pimage[i][j]=NULL; else { a=*(image + (i-1) * size[0] + j - 1); b=*(image + (i-1) * size[0] + j); c=*(image + (i-1) * size[0] + j + 1); d=*(image + i * size[0] + j - 1); 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<size[1];i++) { for(j=0;j<size[0];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<size[1];i++) { for(j=0;j<size[0];j++) { if(lcnt[imageout[i][j]] > areasize ) { *(imageget + i * size[0] + j) = WHITE; } else { *(imageget + i * size[0] + j) = BLACK; } } } for(i=0;i<size[1];i++) { free(imageout[i]); free(pimage[i]); } free(imageout); free(pimage); free(label); free(labelcnt); free(lcnt); return 0; }
欢迎学习,批评,指正