Listing 5 Code implementing the histogram peaks technique

   /*********************************************
   *   peak_threshold_segmentation(...
   *   This function segments an image using
   *   thresholding. It uses the histogram peaks
   *   to find the hi and low values of the
   *   threshold.
   *   If the segment parameter is 0, you only
   *   threshold the array - you do not segment.
   ***********************************************/

peak_threshold_segmentation(in_name, out_name
                            the_image, out_image,
                            il, ie, ll, le,
                            value, segment)
   char   in name[], out_name[];
   int    il, ie, ll, le, segment;
   short  the_image[ROWS][COLS],
          out_image[ROWS] [COLS], value;
{
   int      length, peak1, peak2, width;
   short    hi, low;
   struct   tiff_header_struct image_header;
   unsigned long histogram[GRAY_LEVELS+1];
   
   if(does_not_exist(out_name)){
      printf("\n\nPTS> output file does not exist %s", out_name);
      read_tiff_header(in_name, &image_header);
      round_off_image_size(&image_header, &length, &width);
      image_header.image_length = length*ROWS;
      image_header.image_width = width*COLS;
      create_allocate_tiff_file(out_name, &image_header, out_image);
   }  /* ends if does not exist */
   
   read_tiff_image(in_name, the_image, il, ie, ll, le);
   zero_histogram(histogram);
   calculate_histogram(the_image, histogram);
   smooth_histogram(histogram);
   find_peaks(histogram, &peak1, &peak2);
   peaks_high_low(histogram, peak1, peak2, &hi, &low);
   threshold_image_array(the_image, out_image, hi, low, value);
   if(segment == 1)
      grow(out_image, value);
   write_array_into_tiff_image(out_name, out_image, il, ie, ll, le);

}  /* ends peak_threshold_segmentation */

   /*******************************************
   *   find_peaks(...
   *   This function looks through the histogram
   *   array and finds the two highest peaks.
   *   The peaks must be separated, cannot be
   *   next to each other, by a spacing defined
   *   in cips.h.
   *   The peaks array holds the peak value
   *   in the first place and its location in
   *   the second place.
   *******************************************/

find_peaks(histogram, peak1, peak2)
   unsigned long histogram[];
   int *peak1, *peak2;
{
   int distance[PEAKS], peaks[PEAKS][2];
   int i, j=0, max:0, max_place:0;
   
   for(i=0; i<PEAKS; i++){
      distance[i] = 0;
      peaks[i][0] = -1;
      peaks[i] [1] = -1;
   }
   
   for(i=0; i<=GRAY_LEVELS; i++){
      max        = histogram[i];
      max_place = i;
      insert_into_peaks(peaks, max, max_place);
   }  /* ends loop over i */
   
   for(i=1; i<PEAKS; i++){
      distance[i] = peaks[0][1] - peaks[i][1];
      if(distance[i] < 0)
         distance[i] = distance[i]*(-1);
   }
   
   *peak1 = peaks[0] [1];
   for(i=PEAKS-1; i>0; 1--)
      if(distance[i] > PEAK_SPACE) *peak2 = peaks[i][1];

}  /* ends find_peaks */

   /*******************************************
   *   insert_into_peaks(...
   *   This function takes a value and its
   *   place in the histogram and inserts them
   *   into a peaks array. This helps us rank
   *   the the peaks in the histogram.
   *   The objective is to build a list of
   *   histogram peaks and thier locations.
   *   The peaks array holds the peak value
   *   in the first place and its location in
   *   the second place.
   *******************************************/

insert_into_peaks(peaks, max, max_place)
   int max, max_place, peaks[PEAKS][2];
}
   int i, j;
   
      /* first case */
   if(max > peaks[0][0]){
      for(i=PEAKS-1; i>0; i--){
         peaks[i][0] = peaks[i-1][0];
         peaks[il[1] = peaks[i-1[1];
      }
      peaks[0] [0] = max;
      peaks[0][1] = max_place;
   }  /* ends if */
   
      /* middle cases */
   for(j=0; j<PEAKS-3; j++){
      if(max < peaks[j][0] && max > peaks[j+1][0]){
         for(i:PEAKS-1; i>j+1; i--){
            peaks[i][0] = peaks[i-1][0];
            peaks[i][1] = peaks[i-1][1];
         }
         peaks[j+1][0] = max;
         peaks[j+1][1] = max_place;
      }  /* ends if */
   }  /* ends loop over j */
      /* last case */
   if(max < peaks[PEAKS-2][0] && max > peaks[PEAKS-1] [0]){
      peaks[PEAKS-1][0] = max;
      peaks[PEAKS-1][0] = max_place;
   }  /* ends if */

}  /* ends insert into_peaks */

   /***********************************************
   *   peaks_high_low(...
   *   This function uses the histogram array
   *   and the peaks to find the best high and
   *   low threshold values for the threshold
   *   function. You want the hi and low values
   *   so that you will threshold the image around
   *   the smaller of the two "humps" in the
   *   histogram. This is because the smaller
   *   hump represents the objects while the
   *   larger hump represents the background.
   ***********************************************/

peaks_high_low(histogram, peak1, peak2, hi, low)
   int peak1, peak2;
   short *hi, *low;
   unsigned long histogram[];
{
   int i, mid_point;
   unsigned long sum1 = 0, sum2 = 0;

   if(peak1 > peak2)
      mid_point = ((peak1 - peak2)/2) + peak2;
   if(peak1 < peak2)
      mid_point = ((peak2 - peak1)/2) + peak1;
   
   for(i=0; i<mid_point; i++)
      sum1 = sum1 + histogram[i];
   
   for(i=mid_point; i<=GRAY_LEVELS; i++)
      sum2 = sum2 + histogram[i];
   if(sum1 >= sum2){
      *low = midpoint;
      *hi = GRAY_LEVELS;
   }
   else{
      *low = 0;
      *hi = mid_point;
   }

}  /* ends peaks_high_low */
/* End of File */