c语言实现二值图像的坐标,实现基于C语言的二值图像连通域标记算法

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 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值