Listing 3 Functions that implement region growing

    /*********************************************
    *  grow(...
    *  This function is an object detector.
    *  Its input is an binary image array
    *  containing 0's and value's.
    *  It searches through the image and connects
    *  the adjacent values.
    **********************************************/

grow(binary, value)
   short binary[ROWS][COLS],
         value;
{
   char name[80];
   
   int first_call,
       i,
       j,
       object_found,
       pointer,
       pop_i,
       pop_j,
       stack_empty,
       stack_file_in_use;
   
   short g_label, stack[STACK_SIZE][2];
   
            /***********************************
            *   Now begin the process of growing
            *   regions.
            *************************************/
   
   g_label        = 2;
   object_found  = 0;
   first_call    = 1;
   
   for(i=0; i<ROWS; i++){
      for(j=0; j<COLS; j++){
         stack file in use = 0;
         stack_empty =  1;
         pointer = -1;

/*********************************
*  Search for the first pixel of
*  a region.
**********************************/
         
         if(binary[i][j] == value){
            label_and_check_neighbor(binary, stack, g_label,
                            &stack_empty, &pointer, i, j,
                            value, &stack_file_in_use,
                            &first_call);
            object_found = 1;
         }  /* ends if binary[i]j] == value */
         
/******************************
*  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   */
            
            label_and_check_neighbor(binary,
                        stack, g_label,
                        &stack_empty,
                        &pointer, pop_i,
                        pop_j, value,
                        &stack_file_in_use,
                        &first_call);
         }  /* ends while stack_empty == 0 */
         
         if(object_found == 1){
            object_found = 0;
            ++g_label;
         }  /* ends if object_found == 1 */
      
      }   /* ends loop over j */
   }  /* ends loop over i */
   
   printf("\nGROW> found %d objects", g_label);

} /* ends grow */

   /********************************************
   *  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.
   **********************************************/

label_and_check_neighbor(binary_image, stack,
                         g_label, stack_empty,
                         pointer, r, e, value,
                         stack_file_in_use,
                         first_call)
int    e,
      *first_call,
      *pointer,
      r,
      *stack_empty,
      *stack_file_in_use;

short binary_image [ROWS] [COLS],
      g_label,
      stack[STACK_SIZE][2],
      value;
{
   int already_labeled = 0,
      i, j;

   if (binary_image[r][e] == g_label)
      already_labeled = 1;

   binary_image[r][e] = g_label;

      /*************************************
      *   Look at the 8 neighors of the
      *   point r,e.
      *   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(binary_image[i][j] == value){
               *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*/

            }  /* end of if binary_image == value */
         }  /* end if i and j are on the image */
      }  /* ends loop over i rows             */
   }  /* ends loop over j columns        */
}  /* ends label_and_check_neighbors  */

   /***************************************
   *   push_data_onto_stack_file(...
   *   This function takes the stack array
   *   and pushes it onto the stack file.
   *****************************************/

push_data_onto_stack_file(stack, pointer, first_call)
   int   *first_call, *pointer;
   short stack[STACK_SIZE][2];
{
   char  backup_file_name[MAX_NAME_LENGTH];
   FILE  *backup_file_pointer, *stack_file_pointer;
   int   diff, i;
   short holder[STACK_FILE_LENGTH][2];
   
   printf("\nSFO> Start of push_data_onto_stack ");
   
   diff = STACK_SIZE - STACK_FILE_LENGTH;
   
       /*****************************************
       *   Copy the elements to be stored to the
       *   stack file into holder
       ******************************************/
   
   for(i=0; i<STACK_FILE_LENGTH; i++){
      holder[i][0] = stack[i][0];
      holder[i][1] = stack[i][1];
   }
       /*****************************************
       *   Move the elements of the stack down
       *****************************************/
   
   for(i=0; i<diff; i++){
      stack[i][0] = stack[i + STACK_FILE_LENGTH][0];
      stack[i][1] = stack[i + STACK_FILE_LENGTH][1];
   }
   
       /*****************************************
       *   Fill the top of the stack with zeros
       *****************************************/
   
   for(i=diff; i<STACK_SIZE; i++){
      stack[i][0] = 0;
      stack[i][1] = 0;
      }
   
   *pointer = *pointer - STACK_FILE_LENGTH;
   
       /*************************************************
       *   Store the holder array into the stack file.
       *   Open the stack file for writing in binary
       *   mode. If the file does not exist it will be
       *   created. If the file does exist it will be
       *   over written.
       *   PUSH - IF first_time == 1 then write to stack
       *           ELSE write to stack.bak
       *           append stack onto stack.bak
       *           copy stack.bak to stack
       *           this has the effect of writing
       *           to the beginning of the stack.
       ************************************************/
   
   if(*first_call == 1){
   
      *first_call = *first_call + 1;
      if((stack_file_pointer = fopen(STACK_FILE,"wb"))
                                     == NULL)
         printf("\nSFO> Could not open stack file");
      else{
         /*printf("\n\nSFO> Writing to stack file");*/
         fwrite(holder, sizeof(holder), 1, stack_file_pointer);
         fclose(stack_file_pointer);
      }  /*  ends else could not open stack_file   */
   
   }  /*  ends if *first_call == 1  */
   else{  /* else stack file has been used already  */
      strcpy(backup_file_name, STACK_FILE);
      append_string(".bak\0", backup_file_name);
      if((backup_file_pointer =
          fopen(backup_file_name, "wb")) == NULL)
         printf("\nSFO> Could not open backup file");
      else{
         /*printf("\n\nSFO> Writing to backup file");*/
         fwrite(holder, sizeof(holder), 1, backup_file_pointer);
         fclose(backup_file_pointer);
      }  /*  ends else could not open backup_file  */
      
      append_stack_files(backup_file_name, STACK_FILE, holder);
      copy_stack_files(backup_file_name, STACK_FILE, holder);
   
   }  /*  ends else first_call != 1  */
   
   printf("--- End of push_data_onto_stack");

}  /* ends push_data_onto_stack_file  */

   /***************************************
   *   pop_data_off_of_stack_file(...
   *   This function pops the stack array
   *   off of the stack file.
   ****************************************/

pop_data_off_of_stack_file(stack, pointer, stack_file_in_use)
   int   *pointer, *stack_file_in_use;
   short stack[STACK_SIZE][2];
{
   char  backup_file_name[MAX_NAME_LENGTH];
   FILE  *backup_file_pointer, *stack_file_pointer;
   int   i;
   long  write_counter;
   short holder[STACK_FILE_LENGTH][2],
         holder2[STACK_FILE_LENGTH][2];
       
       /********************************************
       *   POP - Read 1 time from stack
       *          Copy the remainder of stack to
       *              stack.bak
       *          Copy stack.bak to stack
       *          This has the effect of popping off
       *          of the stack.
       *   Read the holder array from the stack file.
       *   Open the stack file for reading in binary
       *   mode.
       *   If it requires more than one write to
       *   copy the remainder of stack to
       *   stack.bak then there is still data in the
       *   stack file so set stack_file_in_use = 1.
       *   Else set it to 0.
       ***********************************************/
   
   printf("\nSFO> Start of pop_data_off_of_stack ");
   write_counter = 0;
   
   strcpy(backup_file_name, STACK_FILE);
   append_string(".bak\0", backup_file_name);
   
   if( (stack_file_pointer = fopen(STACK_FILE, "rb")) == NULL)
      printf("\nSFO> Could not open stack file");
   else{
      /*printf("\n\nSFO> Reading from stack file");*/
      fread(holder, sizeof(holder),
            1, stack_file_pointer);
      backup_file pointer =
            fopen(backup_file_name, "wb");
      while( fread(holder2, sizeof(holder2),
                   1, stack_file pointer) ){
         fwrite(holder2, sizeof(holder2),
                1, backup_file_pointer);
         ++write_counter;
         }  /* ends while reading  */
      if(write_counter > 0)
         *stack_file_in_use = 1;
      else
         *stack_file_in_use = 0;
      
      fclose(backup_file_pointer);
      fclose(stack_file_pointer);
      }  /* ends else could not open stack file  */
   
   copy_stack_files(backup_file_name,
                    STACK_FILE, holder2);
   
   for(i=0; i<STACK_FILE_LENGTH; i++){
      stack[i][0] = holder[i][0];
      stack[i][1] = holder[i][1];
      }
   *pointer = *pointer + STACK_FILE_LENGTH - 1;
   
   printf("--- End of pop_data_off_of_stack");
}  /* ends pop_data_off_of_stack_file */

   /*********************************************
   *   append_stack_files(...
   *   Append the second file onto the end
   *   of the first.
   ***********************************************/

append_stack_files(first_file, second_file, holder)
   char first_file[], second file[];
   short holder[STACK_FILE_LENGTH][2];
{
   FILE  *first, *second;
   int   i;
   
   if((first = fopen(first_file, "r+b")) == NULL)
      printf("\n\nSFO> Cannot open file %s",
             first_file);
   
   if((second = fopen(second_file, "rb")) == NULL)
      printf("\n\nSFO> Cannot open file %s", second_file);
      
          /***************************************
          *  Seek to the end of the first file and
          *  to the beginning of the second file.
          *****************************************/
   
   fseek(first, OL, 2);
   fseek(second, OL, 0);
   
   while(fread(holder, sizeof(holder), 1, second) ){
      fwrite(holder, sizeof(holder), 1, first);
   }  /* ends while reading   */

   fclose(first);
   fclose(second);

}  /*  ends append_stack_files */

   /******************************************
   *   copy_stack_files(...
   *   Copy the first file to the second.
   ********************************************/

copy_stack_files(first_file, second_file, holder)
   char first_file[], second_file[];
   short holder[STACK_FILE_LENGTH][2];
{
   FILE  *first, *second;
   int   i;
   
   if( (first = fopen[first_file, "rb")) == NULL)
      printf("\n\nSFO> Cannot open file %s", first_file);
   
   if( (second = fopen(second_file, "wb")) == NULL)
      printf("\n\nSFO> Cannot open file %s", second_file);
      
          /****************************************
          *  Seek to the beginning of the first file.
          *****************************************/
   
   fseek(first, 0L, 0);
   
   while( fread(holder, sizeof(holder), 1, first) ){
      fwrite(holder, sizeof(holder), 1, second);
   }  /* ends while reading   */
   
   fclose(first);
   fclose(second);

}  /*  ends copy_stack_files */

/* End of File */