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

  1 //标记的连通域存储在buff[]里
  2 //返回值为连通域个数
  3 int LinkBlob(unsigned char **imagedata,unsigned char buff[], int height, int width)
  4 {
  5     int x,y,domain_num=0;
  6     int i;
  7     unsigned long offset;
  8     //unsigned char imagedata[];
  9 
 10     for(i=0; i<width*height; i++)  
 11         buff[i]=0;
 12     i=1;
 13 
 14     //for(offset = 0; offset<height*width; offset++)        //遍历图像的点
 15     for (y = 0; y<height; y++)
 16     {
 17         for (x = 0; x<width; x++)
 18         {
 19             offset = y*width + x;
 20         /*x = offset % width;
 21         y = offset / width;*/
 22             if(y == 0)//第0行
 23             {
 24                 if(x == 0)//第0列第0行
 25                 {
 26                     //if(imagedata[y][x] == FORECOLOR)//如果第0点有值则将其分配到区域一
 27                     //{
 28                         buff[offset]=i;
 29                         domain_num++;    //联通域数量增一
 30                     //}
 31                 }
 32                 else//如果是第0行的其它点
 33                 {
 34                     //if(imagedata[y][x]==FORECOLOR)    //如果有值
 35                     //{
 36 
 37                         if(imagedata[y][x-1] == imagedata[y][x])    //如果它的前一点有值,则将它归属到它的前一点的联通域
 38                         {
 39                             i=buff[offset-1];//获取前一点的联通域序号,传给i
 40                             buff[offset]=i;//将该点赋给i指定的联通域
 41                         }
 42                         else//如果它的前一点没有值,则将它归到另一个联通域
 43                         {
 44                             domain_num++;//联通域数量增一
 45                             i=domain_num;
 46                             buff[offset]=i;//将它标记为i联通域
 47                         }
 48                     //}
 49                 }
 50             }
 51             else if( x==0 && y>0)//如果是第一行下的行和第0列,则只检测其上方及其右上方的点
 52             {
 53                 //if(imagedata[y][x]==FORECOLOR)//如果有值
 54                 //{
 55                     if(imagedata[y-1][x] == imagedata[y][x])//如果其上方的点有值则将它归属到上方点所属的连通域里
 56                     {
 57                         i = buff[x+(y-1)*width];        //上方点的连同域的序号
 58                         buff[offset]=i;        //将此点归属到上方点的连同域
 59                     }
 60                     else if(imagedata[y-1][x+1] == imagedata[y][x])        //则检测其右上方的点,如果右上方的点有值
 61                     {
 62                         i = buff[x+1+(y-1)*width];    //右上方点的连同域的序号
 63                         buff[offset] = i;    //将此点归属到右上方点的连同域            
 64                     }
 65                     else //如果在上方的点和右上方的点都没有值,则另设一个连同域
 66                     {
 67                         domain_num++;        //联通域数量增一
 68                         i = domain_num;
 69                         buff[offset] = i;        //将它标记为i联通域
 70                     }
 71                 //}
 72             }
 73             else if(x == (width-1) && y > 0)//如果是靠最右则第0行以下的点
 74             {
 75                 //if(imagedata[y][x]==FORECOLOR)//如果此点有值
 76                 //{
 77                     if(imagedata[y][x-1] == imagedata[y][x])    //如果它的前一点有值,则将它规属到前一点的连同域里
 78                     {
 79                         i = buff[offset-1];    //获取前一点的联通域序号,传给i
 80                         buff[offset] = i;    //将该点赋给i指定的联通域
 81                     }
 82                     else if(imagedata[y-1][x-1] == imagedata[y][x])    //否则如果其左上方有值,则将它归属到左上方的连同域里
 83                     {
 84                         i = buff[x-1+(y-1)*width];    //获取左上方点的联通域序号,传给i
 85                         buff[offset] = i;    //将该点赋给i指定的联通域
 86                     }
 87                     else if(imagedata[y-1][x] == imagedata[y][x])    //否则如果其上方的点有值,则归属到其上方的点的连同域里
 88                     {
 89                         i = buff[x+(y-1)*width];//上方点的连同域的序号
 90                         buff[offset] = i;//将此点归属到上方点的连同域
 91                     }
 92                     else//它的前方,左上方,上方的点都没有值,则另设连同域
 93                     {
 94                         domain_num++;//联通域数量增一
 95                         i=domain_num;
 96                         buff[offset]=i;//将它标记为i联通域
 97                     }
 98                 //}
 99             }
100             else //如果是其它正常的点
101             {
102                 //if(imagedata[y][x]==FORECOLOR)//如果此点有值
103                 //{
104                     if(imagedata[y][x-1] == imagedata[y][x])//如果它的前一点有值,则将它规属到前一点的连同域里
105                     {
106                         i = buff[offset-1];//获取前一点的联通域序号,传给i
107                         buff[offset]=i;//将该点赋给i指定的联通域
108 
109                         if(imagedata[y-1][x] == imagedata[y][x])    //继续检测其上方的点,如果上方点有值
110                         {
111                             //if(buff[x+(y-1)*width]<buff[offset])//如果上方的点
112                         }
113                         else if(imagedata[y-1][x+1] == imagedata[y][x])    //否则如果其右上方才有值
114                         {
115                             if(buff[x+1+(y-1)*width] < buff[offset])//如果右上方的点的域序号小
116                             {
117                                 for(i=0;i<width*height;i++)        //则将其所有的属于本点连通域的点都归到右上方的点的连通域
118                                 {
119                                     if(buff[i]==buff[offset])
120                                     {
121                                         buff[i]=buff[x+1+(y-1)*width];
122                                     }
123                                     else if(buff[i]>buff[offset])//所有大于本点的连通域序号的连通域序号自减1
124                                     {
125                                         buff[i]--;
126                                     }
127                                 }
128                                 domain_num--;//连通域序号减1
129                             }
130                             else if(buff[x+1+(y-1)*width] > buff[offset])//否则则反之
131                             {
132                                 for(i=0;i<width*height;i++)
133                                 {
134                                     if(buff[i]==buff[x+1+(y-1)*width])
135                                     {
136                                         buff[i]=buff[offset];
137                                     }
138                                     else if(buff[i]>buff[x+1+(y-1)*width])
139                                     {
140                                         buff[i]--;
141                                     }
142                                 }
143                                 domain_num--;//连通域序号减1
144                             }
145                         }
146                     }
147                     else if(imagedata[y-1][x-1] == imagedata[y][x])//否则如果其左上方有值,则将它归属到左上方的连同域里
148                     {
149                         i=buff[x-1+(y-1)*width];//获取左上方点的联通域序号,传给i
150                         buff[offset]=i;//将该点赋给i指定的联通域
151 
152                         if(imagedata[y-1][x+1] == imagedata[y][x])//继续检测其右上方的点
153                         {
154                             if(buff[x+1+(y-1)*width] < buff[offset])//如果右上方的点的域序号小
155                             {
156                                 for(i=0;i<width*height;i++)//则将其所有的属于本点连同域的点都归到右上方的点的连同域
157                                 {
158                                     if(buff[i]==buff[offset])
159                                     {
160                                         buff[i]=buff[x+1+(y-1)*width];
161                                     }
162                                     else if(buff[i]>buff[offset])//所有大于本点连通域序号的连通域序号自减1
163                                     {
164                                         buff[i]--;
165                                     }
166                                 }
167                                 domain_num--;//连通域序号减1
168                             }
169                             else if(buff[x+1+(y-1)*width] > buff[offset])//否则则反之
170                             {
171                                 for(i=0;i<width*height;i++)
172                                 {
173                                     if(buff[i]==buff[x+1+(y-1)*width])
174                                     {
175                                         buff[i]=buff[offset];
176                                     }
177                                     else if(buff[i]>buff[x+1+(y-1)*width])
178                                     {
179                                         buff[i]--;
180                                     }
181                                 }
182                                 domain_num--;//连通域序号减1
183                             }
184                         }
185                     }
186                     else if(imagedata[y-1][x] == imagedata[y][x])//否则如果其上方的点有值,则归属到其上方的点的连同域里
187                     {
188                         i = buff[x+(y-1)*width];//上方点的连同域的序号
189                         buff[offset] = i;//将此点归属到上方点的连同域
190                     }
191                     else if(imagedata[y-1][x+1] == imagedata[y][x])//否则如果其右上方的点有值,则将其归到其右上方点的连通域里
192                     {
193                         i = buff[x+1+(y-1)*width];//右上方点的连同域的序号
194                         buff[offset] = i;//将此点归属到右上方点的连同域
195                     }
196                     else //如果以上检测都没有值,则另建连同域
197                     {
198                         domain_num++;//联通域数量增一
199                         i = domain_num;
200                         buff[offset] = i;//将它标记为i联通域
201                     }
202                 //}
203             }
204         }//x end
205     }//y end
206 
207     return domain_num;
208 }
原文地址:https://www.cnblogs.com/rongfangliu/p/linkblob.html