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 }