home *** CD-ROM | disk | FTP | other *** search
- /*
- * histstats.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* HISTSTATS: program compiles histogram and some histogram statistics
- * for an image
- * usage: histstats inimg outimg [-f HIST_FILE] [-L]
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include <tiffimage.h> /* tiff info on images */
- #include <images.h>
- extern void print_sos_lic ();
-
- #define NBINS 256 /* no. of histogram bins */
- #define WID_HIST 256 /* size of histogram image */
- #define HT_HIST 256
- #define LN2INV 1.442695041 /* 1 over natural log of 2 :
- * * log2(x) = (1/log(2)) * log(x) */
-
- int histogram (char *, int, int *);
- int input (int, char **, short *);
- int usage (short);
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- Image *imgI, *imgO; /* input and output image structures */
- unsigned char **imgIn, **imgOut; /* input/output image */
- FILE *fpOut; /* output text file for histogram */
- short fileFlag; /* flag = 1 to write hist. text file; or 0 */
- int hist[NBINS]; /* image histogram array */
- long maxHist, iMaxHist; /* maximum histogram value and bin number */
- long total; /* total pixels in image */
- long lowHist, highHist; /* highest and lowest intensity values */
- long sum; /* sum of bins in histogram */
- double sumSqr; /* sum of squares of bins in histogram */
- double avgHist; /* average bin location */
- double stdDev; /* standard deviation of intensities */
- double entropy, prob; /* entropy and probability of bin intensity */
- long nOccupied; /* number of occupied bins */
- long x, y, i, j;
- long height; /* height of histogram bin */
- struct point imgSize; /* image dimensions */
-
- /* read user parameter values */
- if ((input (argc, argv, &fileFlag)) < 0)
- return (-1);
-
- /* open input and output images */
- imgI = ImageIn (argv[1]);
- if (imgI->bps == 8 && imgI->spp == 3) {
- printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
- exit (1);
- }
- imgIn = imgI->img;
- imgSize.y = ImageGetHeight (imgI);
- imgSize.x = ImageGetWidth (imgI);
- printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
-
- imgO = ImageAlloc (WID_HIST, HT_HIST, 1);
- imgOut = ImageGetPtr (imgO);
-
- /* zero histogram array */
- for (i = 0; i < NBINS; i++)
- hist[i] = 0;
-
- /* construct histogram */
- for (j = 0; j < imgSize.y; j++)
- histogram (imgIn[j], imgSize.x, hist);
-
- /* compile statistics and normalize histogram values */
- iMaxHist = 0;
- maxHist = 0;
- total = 0;
- sum = 0;
- sumSqr = 0.0;
- lowHist = highHist = -1;
- for (i = 0; i < NBINS; i++) {
- sum += i * hist[i];
- sumSqr += (double) i *(double) i *(double) hist[i];
- total += hist[i];
- if (hist[i] > maxHist) {
- maxHist = hist[i];
- iMaxHist = i;
- }
- if (lowHist == -1 && hist[i] > 0)
- lowHist = i;
- if (hist[i] > 0)
- highHist = i;
- }
- avgHist = (double) sum / (double) total;
- stdDev = sqrt (sumSqr / (double) total - avgHist * avgHist);
-
- nOccupied = 0;
- entropy = 0.0;
- for (i = 0; i < NBINS; i++) {
- if (hist[i] != 0)
- nOccupied++;
- prob = hist[i] / (double) total;
- if (hist[i] != 0)
- entropy -= prob * log (prob);
- }
- entropy *= LN2INV;
-
- for (i = 0; i < NBINS; i++)
- hist[i] = (long) ((double) hist[i] * (HT_HIST - 1.0)
- / (double) maxHist + 0.5);
-
-
-
- /* write histogram statistics */
- printf ("HISTOGRAM STATS:\n");
- printf ("\trange of occupied bins: %d to %d\n", lowHist, highHist);
- printf ("\tmaximum bin height = %d at bin = %d\n", maxHist, iMaxHist);
- printf ("\taverage bin location = %5.2f\n", avgHist);
- printf ("\tstandard deviation = %5.2f\n", stdDev);
- printf ("\tno. occupied bins = %d, entropy = %5.2f [bits]\n",
- nOccupied, entropy);
-
- /* make histogram image */
- for (y = 0; y < HT_HIST; y++)
- for (x = 0; x < WID_HIST; x++)
- imgOut[y][x] = 255;
- for (i = 0, j = 0; i < NBINS; i++) {
- height = HT_HIST - 1 - hist[i];
- for (y = height; y < HT_HIST; y++)
- imgOut[y][j] = 0;
- j++;
- }
-
- /* print out text file of histogram values if flag set */
- if (fileFlag) {
- fpOut = fopen (argv[4], "w");
- for (i = 0; i < NBINS; i++)
- fprintf (fpOut, "%d ", hist[i]);
- }
-
- /* write output histogram image */
- ImageOut (argv[2], imgO);
- }
-
- /* USAGE: function gives instructions on usage of program
- * usage: usage (flag)
- * When flag is 1, the long message is given, 0 gives short.
- */
-
- int
- usage (flag)
- short flag; /* flag =1 for long message; =0 for short message */
- {
-
- /* print short usage message or long */
- printf ("USAGE: histstats inimg outimg [-f HIST_FILE] [-L]\n");
- if (flag == 0)
- return (-1);
-
- printf ("\nhiststats determines image intensity histogram, and\n");
- printf ("yields some global image histogram statistics.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -f file: write output data file holding histogram values\n");
- printf (" -L: print Software License for this module\n");
-
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, fileFlag)
- */
-
- /* print usage and return */
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- int
- input (argc, argv, fileFlag)
- int argc;
- char *argv[];
- short *fileFlag; /* flag = 1 to write hist. text file; or 0 */
- {
- long n;
-
- if (argc == 1)
- USAGE_EXIT (1);
- if (argc == 2)
- USAGE_EXIT (0);
-
- *fileFlag = 0;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-f") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *fileFlag = 1;
- }
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (0);
- }
-
- return (1);
- }
-