Listing 6 Source code for the region-growing algorithm outlined in Figure 12

    /**********************************************
    *
    *   pixel_grow(...
    *
    *   The function grows regions. It is similar
    *   to the grow function in segment.c, but it
    *   has several new capabilities. It can
    *   eliminate regions if they are too large or
    *   too small.
    *
    *   It ignores pixels = FORGET_IT. This allows
    *   it to ignore edges or regions already
    *   eliminated from consideration.
    *
    *   It adds pixels to a growing region only if
    *   the pixel is close enough to the average gray
    *   level of that region.
    *
    ***********************************************/

pixel_grow(input, output, diff, min_area, max_area)
   short input[ROWS][COLS],
        output [ROWS][COLS],
        max_area,
        min_area,
        diff;
{
   char name[80];

   int  count,
       first_call,
       i,
       ii,
       j,
       jj,
       object_found,
       pointer,
       pop_i,
       pop_j,
       stack_empty,
       stack_file_in_use;

   short g_label, target, sum, stack[STACK_SIZE][2];

   for(i=0; i<ROWS; i++)
      for(j=0; j<COLS; j++)
         output[i][j] = 0;

   g_label       = 2;
   object_found  = 0;
   first_call    = 1;

           /*************************************
           *
           *   Now begin the process of growing
           *   regions.
           *
           *************************************/

   for(i-0; i<ROWS; i++){
if( (i%4) == 0) printf("\n");
printf("-i=%3d label=%3d", i, g_label);
     for(j=0; j<COLS; j++){

        target            = input[i][j];
        sum               = target;
        count             = 0;
        stack_file_in_use = 0;
        stack_empty       = 1;
        pointer           = -1;

             /**********************************
             *
             *  Search for the first pixel of
             *  a region. It must not equal
             *  FORGET_IT, and it must be close
             *  enough to the target (ave value).
             *
             ***********************************/

        if(input[i][j]  !=  FORGET_IT          &&
           is_close(input[i][j], target, diff) &&
           output[i][j] == 0){
           pixel_label_and_check_neighbor(input,
                        output, &target, &sum,
                        &count, stack, g_label,
                        &stack_empty, &pointer,
                        i, j, diff,
                        &stack_file_in_use,
                        &first_call);
           object_found  =  1;
        }  /* ends if is_close */
             /*******************************
             *
             *  If the stack is not empty,
             *  pop the coordinates of
             *  the pixel off the stack
             *  and check its 8 neighbors.
             *
             *******************************/

        while(stack_empty == 0){
           pop_i = stack[pointer][0]; /* POP        */
           pop_j = stack[pointer][1]; /* OPERATION  */
           --pointer;
           if(pointer <= 0){
              if(stack_file_in_use){
                 pop_data_off_of_stack_file(
                              stack,
                              &pointer,
                              &stack_file_in_use);
              }  /* ends if stack_file_in use_*/
              else{
                 pointer     = 0;
                 stack_empty = 1;
              }  /* ends else stack file is
                   not in use */
           }  /* ends if point <= 0 */
           pixel_label_and_check_neighbor(input,
                        output, &target, &sum,
                        &count, stack, g_label,
                        &stack_empty, &pointer,
                        pop_i, pop_j,
                        diff, &stack_file_in_use,
                        &first_call);
        } /* ends while stack_empty == 0 */

        if(object_found == 1){
           object_found = 0;

                /**********************************
                *
                *  The object must be in the
                *  size constraints given by
                *  min_area and max_area
                *
                **********************************/

           if(count >= min_area &&
              count <= max_area)
              ++g_label;
                 /**********************************
                 *
                 *   Remove the object from the
                 *   output. Set all pixels in the
                 *   object you are removing to
                 *   FORGET_IT.
                 *
                 **********************************/

           else{
              for(ii=0; ii<ROWS; ii++){
                 for(jj=0; jj<COLS; jj++){
                    if(output[ii][jj] == g_label){
                       output[ii][jj] = 0;
                       input[ii][jj]  = FORGET_IT;
                    }  /* ends if output == g_label */
                 }  /* ends loop over jj */
              }  /* ends loop over ii */
           }  /* ends else remove object */
        }  /* ends if object_found == 1 */

      }  /* ends loop over j */
   }  /* ends loop over i */

   printf("\nGROW> found %d objects", g_label);

} /* ends pixel_grow */

   /***********************************************
   *
   *  pixel_label_and_check_neighbors(...
   *
   *  This function labels a pixel with an object
   *  label and then checks the pixel's 8
   *  neighbors. If any of the neigbors are
   *  set, then they are also labeled.
   *
   *  It also updates the target or ave pixel
   *  value of the pixels in the region being
   *  grown.
   *
   ***********************************************/

pixel_label_and_check_neighbor(input_image,
                     output_image, target,
                     sum, count, stack,
                     g_label, stack_empty,
                     pointer, r, e, diff,
                     stack_file_in_use,
                     first_call)
int   *count,
     e,
     *first_call,
     *pointer,
     r,
     *stack_empty,
     *stack_file_in_use;

short input_image[ROWS][COLS],
     output_image[ROWS][COLS],
     g_label,
     *sum,
     *target,
     stack[STACK_SIZE][2],
     diff;
{
   int already_labeled = 0,
      i, j;

   if (output_image[r][e] != 0)
      already_labeled = 1;

   output_image[r][e] = g_label;
   *count = *count + 1;
   if(*count > 1){
      *sum    = *sum + input_image[r][e];
      *target = *sum / *count;
   }

      /***************************************
      *
      *   Look at the 8 neighors of the
      *   point r,e.
      *
      *   Ensure the points are close enough
      *   to the target and do not equal
      *   FORGET_IT.
      *
      *   Ensure the points you are checking
      *   are in the image, i.e. not less
      *   than zero and not greater than
      *   ROWS-1 or COLS-1.
      *
      ***************************************/

   for(i=(r-1); i<=(r+1); i++){
      for(j=(e-1); j<=(e+1); j++){

         if((i>=0)    &&
            (i<=ROWS-1)  &&
            (j>=0)   &&
            (j<=COLS-1)){

            if( input_image[i][j] != FORGET_IT &&
                is_close(input_image[i][j], *target, diff) &&
                output_image[i][j] == 0) {
               *pointer = *pointer + 1;
               stack[*pointer][0] = i; /* PUSH      */
               stack[*pointer][1] = j; /* OPERATION */
               *stack_empty       = 0;

               if(*pointer >= (STACK_SIZE - STACK_FILE_LENGTH)){
                  push_data_onto_stack_file(stack, pointer, first_call);
                  *stack_file_in_use = 1;
               }  /* ends if *pointer >= STACK_SIZE - STACK_FILE_LENGTH*/

            }  /* ends if is_close */
         }  /* end if i and j are on the image */
      }  /* ends loop over i rows            */
   }  /* ends loop over j columns        */
}  /* ends pixel_label_and_check_neighbors  */

   /********************************************
   *
   *  is_close(...
   *
   *  This function tests to see if two pixel
   *  values are close enough together. It
   *  uses the delta parameter to make this
   *  judgement.
   *
   **********************************************/

is_close(a, b, delta)
   short a, b, delta;
{
   int   result = 0;
   short diff;

   diff = a-b;
   if(diff < 0) diff = diff*(-1);
   if(diff < delta)
      result = 1;
   return(result);
}  /* ends is_close */

/* End of File */