现在的位置: 首页 > 综合 > 正文

C语言(高速算法)去除二值图中的小面积连通区域

2018年11月06日 ⁄ 综合 ⁄ 共 3651字 ⁄ 字号 评论关闭

函数原型: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;
}



抱歉!评论已关闭.