/* BWlabel label groups of 4-connected pixels. This is an implementation of the Matlab function bwlabel */ unsigned long bwlabel(ImageMatrix &Im, int level) { long x, y, base_x,base_y,stack_count, w = Im.width, h = Im.height; unsigned long group_counter = 1; point *stack=new point[w*h]; pixData &pix_plane = Im.WriteablePixels(); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if ( pix_plane(y,x) == 1) { /* start a new group */ group_counter++; pix_plane(y,x) = group_counter; stack[0].x=x; stack[0].y=y; stack_count=1; while (stack_count > 0) { base_x=stack[0].x; base_y=stack[0].y; if (base_x > 0 && pix_plane(base_y,base_x-1) == 1) { pix_plane(base_y,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y; stack_count++; } if (base_x < w-1 && pix_plane(base_y,base_x+1) == 1) { pix_plane(base_y,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y; stack_count++; } if (base_y > 0 && pix_plane(base_y-1,base_x) == 1) { pix_plane(base_y-1,base_x) = group_counter; stack[stack_count].x=base_x; stack[stack_count].y=base_y-1; stack_count++; } if (base_y < h-1 && pix_plane(base_y+1,base_x) == 1) { pix_plane(base_y+1,base_x) = group_counter; stack[stack_count].x=base_x; stack[stack_count].y=base_y+1; stack_count++; } /* look for 8 connected pixels */ if (level==8) { if (base_x > 0 && base_y > 0 && pix_plane(base_y-1,base_x-1) == 1) { pix_plane(base_y-1,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y-1; stack_count++; } if (base_x < w-1 && base_y > 0 && pix_plane(base_y-1,base_x+1) == 1) { pix_plane(base_y-1,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y-1; stack_count++; } if (base_x > 0 && base_y < h-1 && pix_plane(base_y+1,base_x-1) == 1) { pix_plane(base_y+1,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y+1; stack_count++; } if (base_x < w-1 && base_y < h-1 && pix_plane(base_y+1,base_x+1) == 1) { pix_plane(base_y+1,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y+1; stack_count++; } } stack_count-=1; memmove(stack,&(stack[1]),sizeof(point)*stack_count); } } } } /* now decrease every non-zero pixel by one because the first group was "2" */ for (y=0;y<h;y++) for (x=0;x<w;x++) if (pix_plane(y,x) != 0) pix_plane(y,x) -= 1; delete [] stack; return(group_counter-1); }