二值图像连通域标记算法与代码

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

原文链接


这里列举二值图像连通域标记算法包括直接扫描标记算法和二值图像连通域标记快速算法

一、直接扫描标记算法把连续区域作同一个标记,常见的四邻域标记算法和八邻域标记算法。

1、  四邻域标记算法:

1)   判断此点四邻域中的最左,最上有没有点,如果都没有点,则表示一个新的区域的开始。

2)   如果此点四邻域中的最左有点,最上没有点,则标记此点为最左点的值;如果此点四邻域中的最左没有点,最上有点,则标记此点为最上点的值。

3)   如果此点四邻域中的最左有点,最上都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。

2、  八邻域标记算法:

1)   判断此点八邻域中的最左,左上,最上,上右点的情况。如果都没有点,则表示一个新的区域的开始。

2)   如果此点八邻域中的最左有点,上右都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。

3)   如果此点八邻域中的左上有点,上右都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。

4)   否则按照最左,左上,最上,上右的顺序,标记此点为四个中的一个。

代码实现:

 

#include <list>#include <vector>#include <algorithm>//连通区域属性结构typedef struct tagMarkRegion{
    std::list<POINT> MarkPointList;//点列表RECT rect;}MarkRegion; //定义MarkMap 结构,用来存放等价对typedef struct tagEqualMark{
        int MarkValue1;    //标记值int MarkValue2;    //标记值} EqualMark; //定义MarkMapping 结构,用来存放标记映射关系typedef struct tagMarkMapping{
        int nOriginalMark;   //第一次扫描的标记int nMappingMark;  //等价整理之后对应标记} MarkMapping; /*功能说明:八连通标记参数说明:I,表示图像数据指针           ImageWidth,表示图像宽           ImageHeight,表示图像高           off,表示偏移量          nFlag,表示指定标记           iColorType,表示颜色类型,(黑点,白点)           markInfo,表示连通区域属性信息返回值:连通点数量,int类型*/int FillAreaFlag33(LPINT I,int ImageWidth,int ImageHeight,long off,int nFlag,int iColorType,MarkRegion &markInfo){     bool bNew;     RECT rect;     int m,n,i,j,k,nDot=1,offset,offtemp,yMin;     int dxy[8],x,y;     dxy[0]=-ImageWidth-1;     dxy[1]=-ImageWidth;                  dxy[2]=-ImageWidth+1;     dxy[3]=-1;                                                                                     dxy[4]=1;     dxy[5]=ImageWidth-1;       dxy[6]=ImageWidth;          dxy[7]=ImageWidth+1;     rect.left=65535; rect.right=-1;     rect.bottom=65535;   rect.top=-1;    markInfo.MarkPointList.clear();     POINT ptTmp;     if(I[off]==iColorType && I[off]!=nFlag)//黑点同时未被标记的情况     {         I[off]=nFlag;         x=off%ImageWidth;         y=off/ImageWidth;         ptTmp.x = x;         ptTmp.y = y;         markInfo.MarkPointList.push_back(ptTmp);         if(x<rect.left)              rect.left=x;         if(x>rect.right)              rect.right=x;         if(y<rect.bottom)              rect.bottom=y;         if(y>rect.top)              rect.top=y;     }     else     {         return 0;     }      for(i=y; i<ImageHeight; i++)     {         bNew=false;         yMin=i;         for(j=0; j<ImageWidth; j++)         {              offset=i*ImageWidth+j;              if(I[offset]==nFlag)              {                   for(k=0; k<8; k++)//八邻域搜索                   {                       if(i==0 && k<=2)                            continue;                       if(i==ImageHeight-1 && k>=5)                            continue;                       if(j==0 && (k==0 || k==3 || k==5))                            continue;                       if(j==ImageWidth-1 && (k==2 || k==4 || k==7))                            continue;                       offtemp=offset+dxy[k];                       if(I[offtemp]==iColorType && I[offtemp]!=nFlag)                       {                            I[offtemp]=nFlag;                            nDot++;                            m=offtemp/ImageWidth;                            n=offtemp%ImageWidth;                            ptTmp.x = n;                            ptTmp.y = m;                            markInfo.MarkPointList.push_back(ptTmp);                            if(n < rect.left)                                 rect.left=n;                            if(n > rect.right)                                 rect.right=n;                            if(m < rect.bottom)                                 rect.bottom=m;                            if(m > rect.top)                                 rect.top=m;                            y=offtemp/ImageWidth;                            if(y<=yMin)                            {                                 yMin=y;                                 if(!bNew)                                     bNew=true;                            }                       }                   }              }         }         if(bNew)         {              i=yMin-1;         }     }     markInfo.rect.left = rect.left;     markInfo.rect.right = rect.right;     markInfo.rect.top = rect.top;     markInfo.rect.bottom = rect.bottom;     return nDot;} /*功能说明:四连通标记参数说明:I,表示图像数据指针ImageWidth,表示图像宽ImageHeight,表示图像高off,表示偏移量nFlag,表示指定标记iColorType,表示颜色类型,(黑点,白点)markInfo,表示连通区域属性信息返回值:连通点数量,int类型*/int FillAreaFlag22(LPINT I,int ImageWidth,int ImageHeight,long off,int nFlag,int iColorType,MarkRegion &markInfo){     bool bNew;     RECT rect;     int m,n,i,j,k,nDot=1,offset,offtemp,yMin;     int dxy[4],x,y;     dxy[0]=-ImageWidth;     dxy[1]=1;                     dxy[2]=ImageWidth;      dxy[3]=-1;     rect.left=65535; rect.right=-1;     rect.bottom=65535;   rect.top=-1;     markInfo.MarkPointList.clear();     POINT ptTmp;     if(I[off]==iColorType && I[off]!=nFlag)//黑点同时未被标记的情况     {         I[off]=nFlag;         x=off%ImageWidth;         y=off/ImageWidth;         ptTmp.x = x;         ptTmp.y = y;         markInfo.MarkPointList.push_back(ptTmp);         if(x<rect.left)              rect.left=x;         if(x>rect.right)              rect.right=x;         if(y<rect.bottom)              rect.bottom=y;         i
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值