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

C 语言实现二次遍历法提取图像连通分量最大值

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

C语言实现的二次遍历法提取连通分量

http://blog.csdn.net/pc1377318286/article/details/41414381            tip:这是这个算法的OpenCV接口版本链接地址

图像的最外框必须为黑色,添加黑色外框的部分代码我没有植入,使用时要特别注意

第一遍扫描检测联通状态,将其记录如静态线性链表中

第二遍扫描根据指针数组和静态线性链表恢复出图像

如果联通分量溢出,直接修改 int label[4096]={0};int labelcnt[4096]={0};int lcnt[4096]={0};

这三个数组的大小,关于图像数组的建立,请参见我的其它博客

如果提示堆栈溢出,在属性中修改堆栈大小即可,根据处理图像大小选择堆栈保留大小,建议在16M以上

输入图像:

提取结果:

操作源码:


void twopass(unsigned char image[Y_SIZE][X_SIZE],unsigned char imageget[Y_SIZE][X_SIZE])
{
	int i,j,cnt=0;
	int max=0,sec=0;
	int lmax;
	int lsec;
	int label[4096]={0};
	int labelcnt[4096]={0};
	int lcnt[4096]={0};
	int *plabel= label;
	int num,numt;
	int l=0;
	int *pimage[Y_SIZE][X_SIZE];
	int imageout[Y_SIZE][X_SIZE];
	unsigned char a,b,c,d;
	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][j]==BLACK) pimage[i][j]=NULL;
			else
			{
				a=image[i-1][j-1];
				b=image[i-1][j];
				c=image[i-1][j+1];
				d=image[i][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];
				}//1
				else if( (a==0) && (b!=0) && (c==0) && (d==0) )
				{
					pimage[i][j]=pimage[i-1][j];
				}//2
				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) && (d==0) )
				{
					pimage[i][j]=pimage[i-1][j-1];
				}//5
				else if( (a!=0) && (b==0) && (c!=0) && (d==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) && (c==0) && (d!=0) )
				{
					pimage[i][j]=pimage[i-1][j-1];
				}//7
				else if( (a==0) && (b!=0) && (c!=0) && (d==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];
				}//9
				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 if( (a==0) && (b!=0) && (c!=0) && (d!=0) )
				{
					pimage[i][j]=pimage[i-1][j];
				}//11
				else if( (a!=0) && (b==0) && (c!=0) && (d!=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;
				}//12
				else if( (a!=0) && (b!=0) && (c==0) && (d!=0) )
				{
					pimage[i][j]=pimage[i-1][j-1];
				}//13
				else if( (a!=0) && (b!=0) && (c!=0) && (d==0) )
				{
					pimage[i][j]=pimage[i-1][j-1];
				}//14
				else if( (a!=0) && (b!=0) && (c!=0) && (d!=0) )
				{
					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][j]=WHITE;
			else imageget[i][j]=BLACK;
		}
}

期中的逻辑还可以再优化,为便于分析,列出了15条,事实上可以简化为6条

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



抱歉!评论已关闭.