博客已转移至个人网站(http://www.p-chao.com)
函数原型: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;
}