

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






