您的位置:首页 > 编程语言

[代码片段]YEAH!连通域标记和计数

2014-03-30 05:41 169 查看
//标记的连通域存储在buff[]里
//返回值为连通域个数
int LinkBlob(unsigned char **imagedata,unsigned char buff[], int height, int width)
{
int x,y,domain_num=0;
int i;
unsigned long offset;
//unsigned char imagedata[];

for(i=0; i<width*height; i++)
buff[i]=0;
i=1;

//for(offset = 0; offset<height*width; offset++)        //遍历图像的点
for (y = 0; y<height; y++)
{
for (x = 0; x<width; x++)
{
offset = y*width + x;
/*x = offset % width;
y = offset / width;*/
if(y == 0)//第0行
{
if(x == 0)//第0列第0行
{
//if(imagedata[y][x] == FORECOLOR)//如果第0点有值则将其分配到区域一
//{
buff[offset]=i;
domain_num++;    //联通域数量增一
//}
}
else//如果是第0行的其它点
{
//if(imagedata[y][x]==FORECOLOR)    //如果有值
//{

if(imagedata[y][x-1] == imagedata[y][x])    //如果它的前一点有值,则将它归属到它的前一点的联通域
{
i=buff[offset-1];//获取前一点的联通域序号,传给i
buff[offset]=i;//将该点赋给i指定的联通域
}
else//如果它的前一点没有值,则将它归到另一个联通域
{
domain_num++;//联通域数量增一
i=domain_num;
buff[offset]=i;//将它标记为i联通域
}
//}
}
}
else if( x==0 && y>0)//如果是第一行下的行和第0列,则只检测其上方及其右上方的点
{
//if(imagedata[y][x]==FORECOLOR)//如果有值
//{
if(imagedata[y-1][x] == imagedata[y][x])//如果其上方的点有值则将它归属到上方点所属的连通域里
{
i = buff[x+(y-1)*width];        //上方点的连同域的序号
buff[offset]=i;        //将此点归属到上方点的连同域
}
else if(imagedata[y-1][x+1] == imagedata[y][x])        //则检测其右上方的点,如果右上方的点有值
{
i = buff[x+1+(y-1)*width];    //右上方点的连同域的序号
buff[offset] = i;    //将此点归属到右上方点的连同域
}
else //如果在上方的点和右上方的点都没有值,则另设一个连同域
{
domain_num++;        //联通域数量增一
i = domain_num;
buff[offset] = i;        //将它标记为i联通域
}
//}
}
else if(x == (width-1) && y > 0)//如果是靠最右则第0行以下的点
{
//if(imagedata[y][x]==FORECOLOR)//如果此点有值
//{
if(imagedata[y][x-1] == imagedata[y][x])    //如果它的前一点有值,则将它规属到前一点的连同域里
{
i = buff[offset-1];    //获取前一点的联通域序号,传给i
buff[offset] = i;    //将该点赋给i指定的联通域
}
else if(imagedata[y-1][x-1] == imagedata[y][x])    //否则如果其左上方有值,则将它归属到左上方的连同域里
{
i = buff[x-1+(y-1)*width];    //获取左上方点的联通域序号,传给i
buff[offset] = i;    //将该点赋给i指定的联通域
}
else if(imagedata[y-1][x] == imagedata[y][x])    //否则如果其上方的点有值,则归属到其上方的点的连同域里
{
i = buff[x+(y-1)*width];//上方点的连同域的序号
buff[offset] = i;//将此点归属到上方点的连同域
}
else//它的前方,左上方,上方的点都没有值,则另设连同域
{
domain_num++;//联通域数量增一
i=domain_num;
buff[offset]=i;//将它标记为i联通域
}
//}
}
else //如果是其它正常的点
{
//if(imagedata[y][x]==FORECOLOR)//如果此点有值
//{
if(imagedata[y][x-1] == imagedata[y][x])//如果它的前一点有值,则将它规属到前一点的连同域里
{
i = buff[offset-1];//获取前一点的联通域序号,传给i
buff[offset]=i;//将该点赋给i指定的联通域

if(imagedata[y-1][x] == imagedata[y][x])    //继续检测其上方的点,如果上方点有值
{
//if(buff[x+(y-1)*width]<buff[offset])//如果上方的点
}
else if(imagedata[y-1][x+1] == imagedata[y][x])    //否则如果其右上方才有值
{
if(buff[x+1+(y-1)*width] < buff[offset])//如果右上方的点的域序号小
{
for(i=0;i<width*height;i++)        //则将其所有的属于本点连通域的点都归到右上方的点的连通域
{
if(buff[i]==buff[offset])
{
buff[i]=buff[x+1+(y-1)*width];
}
else if(buff[i]>buff[offset])//所有大于本点的连通域序号的连通域序号自减1
{
buff[i]--;
}
}
domain_num--;//连通域序号减1
}
else if(buff[x+1+(y-1)*width] > buff[offset])//否则则反之
{
for(i=0;i<width*height;i++)
{
if(buff[i]==buff[x+1+(y-1)*width])
{
buff[i]=buff[offset];
}
else if(buff[i]>buff[x+1+(y-1)*width])
{
buff[i]--;
}
}
domain_num--;//连通域序号减1
}
}
}
else if(imagedata[y-1][x-1] == imagedata[y][x])//否则如果其左上方有值,则将它归属到左上方的连同域里
{
i=buff[x-1+(y-1)*width];//获取左上方点的联通域序号,传给i
buff[offset]=i;//将该点赋给i指定的联通域

if(imagedata[y-1][x+1] == imagedata[y][x])//继续检测其右上方的点
{
if(buff[x+1+(y-1)*width] < buff[offset])//如果右上方的点的域序号小
{
for(i=0;i<width*height;i++)//则将其所有的属于本点连同域的点都归到右上方的点的连同域
{
if(buff[i]==buff[offset])
{
buff[i]=buff[x+1+(y-1)*width];
}
else if(buff[i]>buff[offset])//所有大于本点连通域序号的连通域序号自减1
{
buff[i]--;
}
}
domain_num--;//连通域序号减1
}
else if(buff[x+1+(y-1)*width] > buff[offset])//否则则反之
{
for(i=0;i<width*height;i++)
{
if(buff[i]==buff[x+1+(y-1)*width])
{
buff[i]=buff[offset];
}
else if(buff[i]>buff[x+1+(y-1)*width])
{
buff[i]--;
}
}
domain_num--;//连通域序号减1
}
}
}
else if(imagedata[y-1][x] == imagedata[y][x])//否则如果其上方的点有值,则归属到其上方的点的连同域里
{
i = buff[x+(y-1)*width];//上方点的连同域的序号
buff[offset] = i;//将此点归属到上方点的连同域
}
else if(imagedata[y-1][x+1] == imagedata[y][x])//否则如果其右上方的点有值,则将其归到其右上方点的连通域里
{
i = buff[x+1+(y-1)*width];//右上方点的连同域的序号
buff[offset] = i;//将此点归属到右上方点的连同域
}
else //如果以上检测都没有值,则另建连同域
{
domain_num++;//联通域数量增一
i = domain_num;
buff[offset] = i;//将它标记为i联通域
}
//}
}
}//x end
}//y end

return domain_num;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: