[代码片段]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 }