home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_2.1 / histstats / histstats.c next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  6.1 KB  |  218 lines

  1. /* 
  2.  * histstats.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* HISTSTATS:   program compiles histogram and some histogram statistics
  10.  *            for an image
  11.  *              usage: histstats inimg outimg [-f HIST_FILE] [-L]
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <string.h>
  19. #include <tiffimage.h>          /* tiff info on images */
  20. #include <images.h>
  21. extern void print_sos_lic ();
  22.  
  23. #define NBINS 256               /* no. of histogram bins */
  24. #define WID_HIST 256            /* size of histogram image */
  25. #define HT_HIST 256
  26. #define LN2INV 1.442695041      /* 1 over natural log of 2 :
  27.                                  * * log2(x) = (1/log(2)) * log(x) */
  28.  
  29. int histogram (char *, int, int *);
  30. int input (int, char **, short *);
  31. int usage (short);
  32.  
  33. main (argc, argv)
  34.      int argc;
  35.      char *argv[];
  36. {
  37.   Image *imgI, *imgO;           /* input and output image structures */
  38.   unsigned char **imgIn, **imgOut;  /* input/output image */
  39.   FILE *fpOut;                  /* output text file for histogram */
  40.   short fileFlag;               /* flag = 1 to write hist. text file; or 0 */
  41.   int hist[NBINS];              /* image histogram array */
  42.   long maxHist, iMaxHist;       /* maximum histogram value and bin number */
  43.   long total;                   /* total pixels in image */
  44.   long lowHist, highHist;       /* highest and lowest intensity values */
  45.   long sum;                     /* sum of bins in histogram */
  46.   double sumSqr;                /* sum of squares of bins in histogram */
  47.   double avgHist;               /* average bin location */
  48.   double stdDev;                /* standard deviation of intensities */
  49.   double entropy, prob;         /* entropy and probability of bin intensity */
  50.   long nOccupied;               /* number of occupied bins */
  51.   long x, y, i, j;
  52.   long height;                  /* height of histogram bin */
  53.   struct point imgSize;         /* image dimensions */
  54.  
  55. /* read user parameter values */
  56.   if ((input (argc, argv, &fileFlag)) < 0)
  57.     return (-1);
  58.  
  59. /* open input and output images */
  60.   imgI = ImageIn (argv[1]);
  61.   if (imgI->bps == 8 && imgI->spp == 3) {
  62.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  63.     exit (1);
  64.   }
  65.   imgIn = imgI->img;
  66.   imgSize.y = ImageGetHeight (imgI);
  67.   imgSize.x = ImageGetWidth (imgI);
  68.   printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
  69.  
  70.   imgO = ImageAlloc (WID_HIST, HT_HIST, 1);
  71.   imgOut = ImageGetPtr (imgO);
  72.  
  73. /* zero histogram array */
  74.   for (i = 0; i < NBINS; i++)
  75.     hist[i] = 0;
  76.  
  77. /* construct histogram */
  78.   for (j = 0; j < imgSize.y; j++)
  79.     histogram (imgIn[j], imgSize.x, hist);
  80.  
  81. /* compile statistics and normalize histogram values */
  82.   iMaxHist = 0;
  83.   maxHist = 0;
  84.   total = 0;
  85.   sum = 0;
  86.   sumSqr = 0.0;
  87.   lowHist = highHist = -1;
  88.   for (i = 0; i < NBINS; i++) {
  89.     sum += i * hist[i];
  90.     sumSqr += (double) i *(double) i *(double) hist[i];
  91.     total += hist[i];
  92.     if (hist[i] > maxHist) {
  93.       maxHist = hist[i];
  94.       iMaxHist = i;
  95.     }
  96.     if (lowHist == -1 && hist[i] > 0)
  97.       lowHist = i;
  98.     if (hist[i] > 0)
  99.       highHist = i;
  100.   }
  101.   avgHist = (double) sum / (double) total;
  102.   stdDev = sqrt (sumSqr / (double) total - avgHist * avgHist);
  103.  
  104.   nOccupied = 0;
  105.   entropy = 0.0;
  106.   for (i = 0; i < NBINS; i++) {
  107.     if (hist[i] != 0)
  108.       nOccupied++;
  109.     prob = hist[i] / (double) total;
  110.     if (hist[i] != 0)
  111.       entropy -= prob * log (prob);
  112.   }
  113.   entropy *= LN2INV;
  114.  
  115.   for (i = 0; i < NBINS; i++)
  116.     hist[i] = (long) ((double) hist[i] * (HT_HIST - 1.0)
  117.                       / (double) maxHist + 0.5);
  118.  
  119.  
  120.  
  121. /* write histogram statistics */
  122.   printf ("HISTOGRAM STATS:\n");
  123.   printf ("\trange of occupied bins: %d to %d\n", lowHist, highHist);
  124.   printf ("\tmaximum bin height = %d at bin = %d\n", maxHist, iMaxHist);
  125.   printf ("\taverage bin location = %5.2f\n", avgHist);
  126.   printf ("\tstandard deviation = %5.2f\n", stdDev);
  127.   printf ("\tno. occupied bins = %d, entropy = %5.2f [bits]\n",
  128.           nOccupied, entropy);
  129.  
  130. /* make histogram image */
  131.   for (y = 0; y < HT_HIST; y++)
  132.     for (x = 0; x < WID_HIST; x++)
  133.       imgOut[y][x] = 255;
  134.   for (i = 0, j = 0; i < NBINS; i++) {
  135.     height = HT_HIST - 1 - hist[i];
  136.     for (y = height; y < HT_HIST; y++)
  137.       imgOut[y][j] = 0;
  138.     j++;
  139.   }
  140.  
  141. /* print out text file of histogram values if flag set */
  142.   if (fileFlag) {
  143.     fpOut = fopen (argv[4], "w");
  144.     for (i = 0; i < NBINS; i++)
  145.       fprintf (fpOut, "%d ", hist[i]);
  146.   }
  147.  
  148. /* write output histogram image */
  149.   ImageOut (argv[2], imgO);
  150. }
  151.  
  152. /* USAGE:       function gives instructions on usage of program
  153.  *                    usage: usage (flag)
  154.  *              When flag is 1, the long message is given, 0 gives short.
  155.  */
  156.  
  157. int
  158. usage (flag)
  159.      short flag;                /* flag =1 for long message; =0 for short message */
  160. {
  161.  
  162. /* print short usage message or long */
  163.   printf ("USAGE: histstats inimg outimg [-f HIST_FILE] [-L]\n");
  164.   if (flag == 0)
  165.     return (-1);
  166.  
  167.   printf ("\nhiststats determines image intensity histogram, and\n");
  168.   printf ("yields some global image histogram statistics.\n\n");
  169.   printf ("ARGUMENTS:\n");
  170.   printf ("    inimg: input image filename (TIF)\n");
  171.   printf ("   outimg: output image filename (TIF)\n\n");
  172.   printf ("OPTIONS:\n");
  173.   printf ("  -f file: write output data file holding histogram values\n");
  174.   printf ("       -L: print Software License for this module\n");
  175.  
  176.   return (-1);
  177. }
  178.  
  179.  
  180. /* INPUT:       function reads input parameters
  181.  *                  usage: input (argc, argv, fileFlag)
  182.  */
  183.  
  184. /* print usage and return */
  185. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  186.  
  187. int
  188. input (argc, argv, fileFlag)
  189.      int argc;
  190.      char *argv[];
  191.      short *fileFlag;           /* flag = 1 to write hist. text file; or 0 */
  192. {
  193.   long n;
  194.  
  195.   if (argc == 1)
  196.     USAGE_EXIT (1);
  197.   if (argc == 2)
  198.     USAGE_EXIT (0);
  199.  
  200.   *fileFlag = 0;
  201.  
  202.   for (n = 3; n < argc; n++) {
  203.     if (strcmp (argv[n], "-f") == 0) {
  204.       if (++n == argc || argv[n][0] == '-')
  205.         USAGE_EXIT (0);
  206.       *fileFlag = 1;
  207.     }
  208.     else if (strcmp (argv[n], "-L") == 0) {
  209.       print_sos_lic ();
  210.       exit (0);
  211.     }
  212.     else
  213.       USAGE_EXIT (0);
  214.   }
  215.  
  216.   return (1);
  217. }
  218.