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

本文介绍了二值图像连通域标记的直接扫描算法(四邻域和八邻域)以及种子填充(四向连通和八向连通)算法。详细阐述了算法原理及其实现代码,探讨了不同算法在填充效果和空间效率上的差异。
摘要由CSDN通过智能技术生成
               

原文链接


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

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

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;         if(y>rect.top)              rect.top=y;     }     else     {         return 0;     }      for(i=y; i<ImageHeight; i++) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值