1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 #define CONNECTIVITY4 4
9 #define CONNECTIVITY8 8
10 #define STACK_INIT_SIZE 256
11 #define STACK_INCRE 256
12 #define TRUE 1
13 #define FALSE 0
14
15 typedef structtagStack16 {17 int **base;18 int **top;19 intstacksize;20 }Stack;21
22
23 Stack* CreatStack(void)24 {25 Stack *pStack = (Stack*)calloc(1, sizeof(Stack));26 pStack->base = (int **)calloc(STACK_INIT_SIZE + 1, sizeof(int *));27 pStack->top = pStack->base;28 pStack->stacksize =STACK_INIT_SIZE;29
30 returnpStack;31 }32
33 int IsStackEmpty(Stack *pStack)34 {35 if (pStack->top == pStack->base)36 returnTRUE;37 else
38 returnFALSE;39 }40
41 void Push(Stack *pStack, int *pnElement)42 {43 if (pStack->top - pStack->base >= pStack->stacksize)44 {45 pStack->base = (int **)realloc(pStack->base, (pStack->stacksize + STACK_INCRE) * sizeof(int *));46 pStack->top = pStack->base + pStack->stacksize;47 pStack->stacksize +=STACK_INCRE;48 }49 ++pStack->top;50 *(pStack->top) =pnElement;51 }52
53 void Pop(Stack *pStack, int *pnElement)54 {55 if (pStack->top == pStack->base && *(pStack->top) ==NULL)56 printf("empty!\n");57 else
58 {59 memcpy(pnElement, *(pStack->top), 4 * sizeof(int));60 (pStack->top)--;61 }62 }63
64 void DestroyStack(Stack *pStack)65 {66 free(pStack->base);67 pStack->top = pStack->base =NULL;68 pStack->stacksize = 0;69
70 free(pStack), pStack =NULL;71 }72
73 /*
74 connected component labeling75 pNumLine: the number of connected line in each row76 LineInfos: the row number;77 the start column number78 the end column number79 labeling number80 */
81 int ConnectedComponentLabeling(uint8_t *pData, int *pResult, int width, int height, int mode, int*pAddress)82 {83 int i = 0, j = 0, k = 0, m = 0, n = 0, L = 0, R = 0, LL = 0, RR = 0, N = 0, X = 0, nFlag = 0;84 int widthPadded = width + 1, heightPadded = height + 1;85 int *pNumLine = NULL, **pLineInfos = NULL, *pTemp =NULL;86 int *p1, *p3;87 uint8_t *p2;88 uint8_t *pnBWPadded;89 Stack *pStack =NULL;90
91 if (mode != CONNECTIVITY4 && mode !=CONNECTIVITY8){92 printf("[error]: wrong mode\n");93 exit(-1);94 }95 //96 pnBWPadded =pData;97 pNumLine = (int *)malloc(heightPadded * sizeof(int));98 pLineInfos = (int **)calloc(heightPadded, sizeof(int *));99 for (i = 0; i < heightPadded; i++){100 pLineInfos[i] = (int *)(pAddress + i*width * 2);101 }102 p1 =pNumLine;103 p2 =pnBWPadded;104
105 //calculate each row‘s connected line, including their row number, starting column number, ending column number
106 for (i = 0; i < height; i++) {107 n = 0;108 p3 =pLineInfos[i];109 for (j = 0; j < widthPadded - 1; j++) {110 if (*p2 == 1) {111 k =j;112 while (*p2 != 0 && k
130 pStack =CreatStack();131 N = 1;132 for (i = 0; i < heightPadded - 1; i++){133 for (j = 0; j < pNumLine[i]; j++){134 //135 if (pLineInfos[i][j * 4 + 3] == 0){136 pTemp = &pLineInfos[i][j * 4];137 //*(pStack->top) = pTemp;
138 pTemp[3] = -1;139 Push(pStack, pTemp);140 Loop:141 pTemp = *(pStack->top);142 X = pTemp[0];143 L = pTemp[1];144 R = pTemp[2];145
146 //connectivity8 or connectivity4
147 LL = (mode == CONNECTIVITY8) ? (L - 1) : L;148 RR = (mode == CONNECTIVITY8) ? (R + 1) : R;149
150 nFlag = 0;151
152 //previous row
153 if (X > 0){154 for (m = 0; m < pNumLine[X - 1]; m++){155 if (pLineInfos[X - 1][m * 4 + 1] <= RR && pLineInfos[X - 1][m * 4 + 2] >= LL && pLineInfos[X - 1][m * 4 + 3] == 0){156 pLineInfos[X - 1][m * 4 + 3] = -1;157 Push(pStack, &pLineInfos[X - 1][m * 4]);158 nFlag = 1;159 }160 }161 }162 //next row
163 if (X < heightPadded - 1) {164 for (n = 0; n < pNumLine[X + 1]; n++){165 if (pLineInfos[X + 1][n * 4 + 1] <= RR && pLineInfos[X + 1][n * 4 + 2] >= LL && pLineInfos[X + 1][n * 4 + 3] == 0){166 pLineInfos[X + 1][n * 4 + 3] = -1;167 Push(pStack, &pLineInfos[X + 1][n * 4]);168 nFlag = 1;169 }170 }171 }172
173 //no line connected to current line or current line has been labeled
174 if (nFlag == 0){175 if(IsStackEmpty(pStack)){176 N++;177 continue;178 }179 else{180 (*(pStack->top))[3] =N;181 Pop(pStack, pTemp);182 if(IsStackEmpty(pStack)){183 N++;184 continue;185 }186 else{187 gotoLoop;188 }189 }190 }else{191 gotoLoop;192 }193
194 }195 }196 }197
198 //label result
199 int *label_cnt = malloc(N*sizeof(int));200 memset(label_cnt,0,N*sizeof(int));201 for (i = 0; imax_label_cnt){212 max_label_cnt =label_cnt[i];213 }214 }215 free(pNumLine), pNumLine =NULL;216 free(pLineInfos), pLineInfos =NULL;217 free(label_cnt);218 DestroyStack(pStack);219
220 returnmax_label_cnt;221 }222
223
224 intmain()225 {226 //binary img
227 uint8_t imgmap[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,230 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0,231 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,232 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,233 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,235 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,236 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,237 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,238 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,239 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,240 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};243
244 int *labelmap = (int*)malloc(16*16*sizeof(int));245 memset(labelmap,0,16*16*sizeof(int));246 int *pAddress = (int*)malloc(1024*sizeof(int));247 memset(pAddress,0,1024*sizeof(int));248 int ind = 0;249
250 int n=0,m=0;251
252 for(n=0; n<16; n++){253 for(m=0; m<16; m++){254 fprintf(stdout,"%2d,",imgmap[ind]);255 ind++;256 }257 fprintf(stdout,"\n");258 }259
260 fprintf(stdout,"\n\n");261
262 //263 ind = 0;264 ConnectedComponentLabeling(imgmap,labelmap,16,16,8,pAddress);265
266 for(n=0; n<16; n++){267 for(m=0; m<16; m++){268 fprintf(stdout,"%3d",labelmap[ind]);269 ind++;270 }271 fprintf(stdout,"\n");272 }273
274
275
276 }