zoukankan      html  css  js  c++  java
  • 实现基于C语言的二值图像连通域标记算法

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

      1 #include <stdio.h>
      2 #include <stdarg.h>
      3 #include <stddef.h>
      4 #include <stdlib.h>
      5 #include <stdint.h>
      6 #include <math.h>
      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 struct tagStack
     16 {
     17     int **base;
     18     int **top;
     19     int stacksize;
     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     return pStack;
     31 }
     32 
     33 int IsStackEmpty(Stack *pStack)
     34 {
     35     if (pStack->top == pStack->base)
     36         return TRUE;
     37     else
     38         return FALSE;
     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!
    ");
     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 labeling
     75   pNumLine: the number of connected line in each row
     76   LineInfos: the row number;
     77   the start column number
     78   the end column number
     79   labeling number
     80 */
     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
    ");
     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 < width) {
    113                     p2++;
    114                     k++;
    115                 }
    116                 *p3++ = i;
    117                 *p3++ = j;
    118                 *p3++ = k - 1;
    119                 *p3++ = 0;
    120                 n++;
    121                 j = k;
    122             }
    123             if(j < widthPadded - 1){
    124                 p2++;
    125             }
    126         }
    127         *p1++ = n;
    128     }
    129  
    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                             goto Loop;
    188                         }
    189                     }
    190                 }else{
    191                     goto Loop;
    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; i<height; i++){
    202         for (j = 0; j<pNumLine[i]; j++){
    203             for (k = pLineInfos[i][j * 4 + 1]; k <= pLineInfos[i][j * 4 + 2]; k++){
    204                 pResult[i*width + k] = pLineInfos[i][j * 4 + 3];
    205                 label_cnt[pLineInfos[i][j * 4 + 3]]++;
    206             }
    207         }
    208     }
    209     int max_label_cnt = 0;
    210     for(i=0;i<N;i++){
    211         if(label_cnt[i] > max_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     return max_label_cnt;
    221 }
    222 
    223 
    224 int main()
    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,"
    ");
    258     }
    259 
    260     fprintf(stdout,"
    
    ");
    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,"
    ");
    272     }
    273 
    274 
    275 
    276 }

    【注】 原文代码在123-125行没有加条件,因此没有跑出正确的结果

  • 相关阅读:
    Ionic2 自学须知的基本知识点
    Ionic2 启动加载优化总结
    Ionic2使用TypeScript调用自定义JavaScript脚本
    GPS坐标转百度地图坐标
    友情链接
    Python学习之路目录(收藏整理)
    基于Docker构建Jenkins CI平台
    KeepLived + nginx 高可用
    k8s-1.16 二进制安装
    Ansible自动化部署K8S集群
  • 原文地址:https://www.cnblogs.com/liuxin0430/p/9822366.html
Copyright © 2011-2022 走看看