Listing 1 (hist.c) Histogram Operations

     /*********************************************************
      *      file d:\cips\hist.c
      *
      *      Functions: This file contains
      *          calculate_histogram
      *          calculate_histogram
      *          zero_histogram
      *          perform_histogram_equalization
      *          show_histogram
      *          print_histogram
      *          smooth_histogram
      *
      *
      *      Purpose: These functions calculate and display the
      *         histogram of an input image array.
      *
      *      Modifications:
      *          July 86 - ported to IBM-PC
      *          August 1990 - modified for use in the
      *              C Image Processing System
      *
      ******************************************************/

#include "d:\cips\cips.h"

#define PRINT_WIDTH 80
#define FORMFEED '\014'

      /*****************************************
      *
      *    zero_histogram(...
      *
      ******************************************/

zero_histogram(histogram)
  unsigned long histogram[];
{
  int i;
  for(i=0; i<256; i++)
     histogram[i] = 0;
} /* ends zero_histogram */

      /*****************************************
      *
      *    calcualte_histogram(...
      *
      ******************************************/

calculate_histogram(image, histogram)
  short  image[ROWS] [COLS];
  unsigned long histogram[];
{
  int i,j,k;
  for(i:0; i<ROWS; i++){
     for(j=0; j<COLS; j++){
        k = image[i] [j];
        histogram[k] = histogram[k] + 1;
     }
  }
} /* ends calculate_histogram */


      /*****************************************
      *
      *    perform_histogram_equalization(...
      *
      ******************************************/

perform_histogram_equalization(image, histogram, new_grays, area)
  float new_grays, area;
  short image[ROWS][COLS];
  unsigned long histogram[];
{
  int i,
     j,
     k;
  unsigned long sum,
          sum_of_h[256];

  double constant;


  sum = 0;
  for(i=0; i<256; i++){
     sum         = sum + histogram[i];
     sum_of_h[i] = sum;
  }

     /* constant = new # of gray levels div by area */
  constant = new_grays/area;
  for(i=0; i<ROWS; i++){
     for(j=0; j<COLS; j++){
        k           = image[i] [j];
        image[i][j] = sum_of_h[k] * constant;
     }
  }
} /* ends perform_histogram_equalization */

      /**********************************************
      *
      *       show_histogram(histogram)
      *
      *        This function shows the histogram
      *        on the screen as numbers and stars.
      *
      ***********************************************/


show_histogram(histogram)
      unsigned long histogram[];
{
      int     count,
             i,
             j;
      unsigned long max, scale;


      max   = 0;
      count = 0;

      for(i=0; i<GRAY_LEVELS; i++)
         if(histogram[i] > max)
           max = histogram[i];

      if(max > (70 - 12))
         scale = max/(70 - 12);
      else
         scale = 1

      printf("\n max=%ld scale=%ld",max, scale);

      printf("\n\ngray count");
      printf("\nlevel");

      for(i=0; i<256; i++){
         if(histogram[i] == 0)
           ++count;
         else
           count = 0;

         if(count < 2){
           printf("\n %4d: %7ld",i,histogram[i]);
           for(j=0; j<((int)(histogram[i]/scale)); j++){
              printf("*");
           }         /* ends loop over j             */
         }           /* ends if count < 5            */
      }              /*  ends loop over i GRAY_LEVELS */
}      /* ends show_histogram */

       /**********************************************
       *
       *        print_histogram(histogram)
       *
       *        This function prints the histogram
       *       input to the function.
       *
       **********************************************/


print_histogram(histogram, name)
       char name[];
       unsigned long histogram[];
{
       char    string [300],
              output[300];

       int     count,
              i,
              j,
              line_counter,
              print_counter;
       unsigned long scale, max;

       FILE *printer;

       if( (printer = fopen("prn", "w")) == NULL)
          printf("\nPH> Could not open printer");
       else
          printf("\nPH> The print file is opened");

       max            = 0;
       count          = 0;
       print_counter  = 0;

       for(i=0; i<256; i++)
          if(histogram[i] > max)
             max = histogram[i];

       if(max = (PRINT_WIDTH - 12))
          scale = max/(PRINT_WIDTH - 12);
       else
          scale = 1;

       printf("\n max=%ld scale=%ld",max, scale);

       printf("\nPI> Print header");
       line_counter = 0;
       long_clear_buffer(string);
       sprintf(string,"          This image is -- %s --", name);
       my_fwriteln(printer, string);
       ++line_counter;

       long_clear_buffer(string);
       sprintf(string, " ");
       my_fwriteln(printer, string);
       ++line_counter;

       long_clear_buffer(string);
       sprintf(string,"           gray     count");
       my_fwriteln(printer, string);
       ++line_counter;
       long_clear_buffer(string);
       sprintf(string,"          level");
       my_fwriteln(printer, string);
       ++line_counter;

       for(i=0; i<256; i++){
          if(histogram[i] == 0)
             ++count;
          else
             count = 0;
          if(count < 2){
             printf(" %4d: %7ld",i,histogram[i]);
             print_counter++;
             if(print_counter >= 6){
                printf("\n");
                print_counter = 0;
             }  /* ends if print_counter >= 6 */

             long_clear buffer(string);
             sprintf(string,
               "           %3d: %7ld ->",i,histogram[i]);
             my_fwrite(printer, string);
             long_clear_buffer(string);
             sprintf(output, " ");
             for(j=0; j<((int)(histogram[i]/scale)); j++){
                sprintf(string, "*");
                append_string(string, output);
             }          /* ends loop over j                */
             my_fwriteln(printer, output);
             ++line_counter;
             if(line_counter >= 55){
                line_counter = 0;
                putc(FORMFEED, printer);
             } /* ends if line_counter >= 55 */
          }                    /* ends if count < 2 */
       }                 /* ends loop over i */
       putc(FORMFEED, printer);
       fclose(printer);

}        /* ends print_histogram */



       /**********************************************
       *
       *       display_histogram(histogram)
       *
       *       This function shows the histogram
       *       input to the function.
       *
       **********************************************/


display_histogram(histogram, x, y,
              line_color,data_color)
       int data_color, line_color, x, y;
       unsigned long histogram[];
{
       int     count,
              i,
              j,
              length;
       unsigned long scale, max;

       max   = 0;
       count = 0;

       for(i=0; i<256; i++)
          if(histogram[i] > max)
             max = histogram[i];

       if(max > (300 - 12))
          scale = max/(100 - 12);
       else
          scale = 1;

   /****************************
   *
   *   clear out an area for
   *   this histogram display
   *
   *****************************/

       _setcolor(0);
       for(i=0; i<258; i++){
          for(j=0; j<100; j++){
             _setpixel(x-1+i, y-j);
          }
       }

        /****************************
        *
        *  loop thru the histogram
        *  and plot the scaled data
        *
        ****************************/


       _setlinestyle(0xFFFF);
       _setcolor(data_color);

       for(i=0; i<256; i++){
          if(histogram[i] != 0){
             length = histogram[i]/scale;
             _moveto(x+i, y);
             _lineto(x+i, y-length);
          }
       }  /* ends loop over i GRAY_LEVELS */


        /***************************
        *
        *  draw the histogram
        *  axes
        *
        ****************************/


       _setcolor(line_color);

       _moveto(x, y);
       _lineto(x+255, y);
       _moveto(x, y);
       _lineto(x, y-5);
       _moveto(x+50, y);
       _lineto(x+50, y-5);
       _moveto(x+100, y);
       _lineto(x+100, y-5);
       _moveto(x+150, y);
       _lineto(x+150, y-5);
       _moveto(x+200, y);
       _lineto(x+200, y-5);
       _moveto(x+255, y);
       _lineto(x+255, y-5);

}       /* ends display_histogram */




display_menu_for_histogram(print, vertical, horizontal)
   int       *print, *vertical, *horizontal;
{
   char response[80];
   int  int_response, not_finished, r;

   not_finished = 1;
   while(not_finished){
      printf("\n\nHISTOGRAM> Enter choice (0 for no change) ");
      printf("\nHISTOGRAM> 1. print is %d (1=print 0=display)",
             *print);
      printf("\nHISTOGRAM> 2. # of vertical 100x100 areas %d",
             *vertical);
      printf("\nHISTOGRAM> 3. # of horizontal 100x100 areas %d",
            *horizontal);
      printf("\nHISTOGRAM> _\b");
      get_integer(&r);

      if(r == 0)
         not_finished = 0;

      if(r == 1){
         printf(
            "\nHISTOGRAM> Enter 1 for print or 0 for display");
         printf("\nHISTOGRAM>___ ");
         get_integer(&int_response);
         *print = int_response;
      } /* ends if r == 1 */

      if(r == 2){
         printf(
            "\nHISTOGRAM> Enter # of vertical 100x100 areas ");
         printf("\nHISTOGRAM> _\b");
         get_integer(&int_response);
         *vertical = int_response;
      }  /* ends if r == 2 */

      if(r == 3){
         printf(
            "\nHISTOGRAM> Enter # of horizontal 100x100 areas ");
         printf("\nHISTOGRAM>___ ");
         get_integer(&int_response);
         *horizontal = int_response;
      }  /* ends if r == 3 */


   }  /* ends while not_finished */

}  /* ends display_menu */




calculate_area_histogram(histogram, vertical, horizontal,
                the_image, name, il, ie, ll, le)
   char     name[];
   int      horizontal, il, ie, ll, le, vertical;
   short    the_image[ROWS] [COLS];
   unsigned long histogram[];
{
   int count, i, j;

   printf("\nCalculating histograms");
   zero_histogram(histogram);
   count = 1;

   for(i=0; i<vertical; i++){
      for(j=0; j<horizontal; j++){
         printf("\n\tcalculating %d of %d",
              count, horizontal*vertical);
         read_tiff_image(name, the_image,
              il+i*ROWS, ie+j*COLS, ll+i*ROWS, le+j*COLS);
         calculate_histogram(the_image, histogram);
         count++;
      }  /* ends loop over j */
   }  /* ends loop over i */

}  /* calcualte_area_histogram */




/* End of File */