函数原型:image为输入图像指针
imageout为输出图像指针
去除面积比 areasize 小的区域
size[0] 为x尺寸,size[1]为Y尺寸
演示图像:
imareaopen(imagetr,imageop,15);
去除图像中面积小于15的连通区域
处理之前:
处理之后:小面积区域被去除了(小于15的连通域都被去除了)
#include"include.h" 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 lsec; int label[40000]={0}; //索引数组,plabel直接指向的标记索引号区间 int labelcnt[40000]={0}; //标注数组,处理过标记冲突的索引号,其数组最终大小即为连通图个数 int lcnt[40000]={0}; //计数数组,统计每个连通图的大小 int allow[11]; //运行输出最大连通域个数 int *plabel= label; int num,numt; int l=0; int *pimage[YSIZE][XSIZE]; int imageout[YSIZE][XSIZE]; unsigned char a,b,c,d; 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<YSIZE;i++) { for(j=0;j<XSIZE;j++) { if(lcnt[imageout[i][j]] > areasize ) { *(imageget + i * size[0] + j) = WHITE; } else { *(imageget + i * size[0] + j) = BLACK; } } } /* for(i=0;i<l+1;i++) { if(lcnt[i]>max) { max=lcnt[i]; lmax=i; } } j = 0; for(i=0;i<l+1;i++) { if(lcnt[i] > areasize && lcnt[i]>(int)(0.1*max)) { allow[j]= i; j++; } if(j>10) break; } */ /* for(i=0;i<l;i++) if( (lcnt[i]>sec) && (lcnt[i]<max) ) { sec=lcnt[i]; lsec=i; }*/ /* for(i=0;i<YSIZE;i++) for(j=0;j<XSIZE;j++) { if(imageout[i][j]==allow[0]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[1]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[2]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[3]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[4]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[5]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[6]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[7]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[8]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[9]) imageget[i][j]=WHITE; else if(imageout[i][j]==allow[10]) imageget[i][j]=WHITE; else imageget[i][j]=BLACK; } */ return 0; }