home *** CD-ROM | disk | FTP | other *** search
- /*
- * histramp.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* HISTRAMP: program performs histogram modification upon a b/w image
- * - yielding an image whose probability density fct is
- * ramp shaped
- * usage: histramp inimg outimg [-s SLOPE_SIGN] [-L]
- *
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <tiffimage.h> /* tiff info on images */
- #include <images.h> /* contains image format information */
- extern void print_sos_lic ();
-
- #define NBINS 256 /* no. of histogram bins */
- #define MAX 255 /* maximum value of histogram */
- #define MAXP1 256 /* no. histogram values */
- #define DFLT_SLOPE 0 /* default slope of intensity histogram */
-
- int histdistr (long *, long, long *);
- int usage (short);
- int input (int, char **, long *);
-
- main (argc, argv)
- int argc;
- char *argv[];
-
- {
- register int i, j;
- register double constant; /* a constant value */
- Image *imgI; /* I/O image structures */
- unsigned char **image, /* input/output data array */
- transform[MAXP1]; /* transform array */
- long ntotal, /* total of summation of cumulative distr. */
- distr[NBINS]; /* cumulative distribution array */
- long hist[NBINS], /* image histogram array */
- nCol, /* image dimensions */
- nRow, slopeSign; /* sign of slope (-1, 0, +1 for -, 0, +) */
- double intercept, /* histogram 0-intercept */
- slope; /* histogram slope */
- double z;
-
- /* read user parameter values */
- if ((input (argc, argv, &slopeSign)) < 0)
- return (-1);
-
- /* invert slopeSign for white high, black low (added 13-Jul-99) */
- if (slopeSign == -1)
- slopeSign = 1;
- else if (slopeSign == 1)
- slopeSign = -1;
-
- /* open input file */
- 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);
- }
- image = imgI->img;
- nRow = ImageGetHeight (imgI);
- nCol = ImageGetWidth (imgI);
- printf ("image size is %dx%d\n", nCol, nRow);
-
- /* construct histogram */
- for (i = 0; i < NBINS; i++)
- hist[i] = 0;
- for (i = 0; i < nRow; i++)
- for (j = 0; j < nCol; j++)
- hist[image[i][j]]++;
-
- /* construct cumumlative distribution */
- histdistr (hist, NBINS, distr);
-
- /* total summation under cumulative distribution omits 1/2 of lowest
- * and highest occupied bins (See history note, 1 April 85) */
- ntotal = distr[NBINS - 1];
-
- /* calculate slope */
-
- switch (slopeSign) {
- case -1:
- slope = -2.0 * ntotal / (double) (MAX * MAX);
- break;
- case 0:
- slope = 0.0;
- break;
- case 1:
- slope = 2.0 * ntotal / (double) (MAX * MAX);
- break;
- }
-
- /* compute transform table for histogram equalization or histogram ramp */
-
- switch (slopeSign) {
-
- case -1: /* negative ramp */
- intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
- constant = intercept / slope;
- for (i = 0; i <= MAX; i++) {
- z = constant * constant + 2.0 / slope * distr[i];
- if (z < 0.0)
- z = 0.0; /* due to quantization error */
- transform[i] = (unsigned char) (-constant + 0.5 - sqrt (z));
- }
- break;
-
- case 0: /* histogram equalization */
- constant = ((double) MAX) / ntotal;
- for (i = 0; i <= MAX; i++)
- transform[i] = (unsigned char) (constant * distr[i] + 0.5);
- break;
-
- case 1: /* positive ramp */
- intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
- constant = intercept / slope;
- for (i = 0; i <= MAX; i++) {
- z = constant * constant + 2.0 / slope * distr[i];
- if (z < 0.0)
- z = 0.0; /* due to quantization error */
- transform[i] = (unsigned char) (-constant + 0.5 + sqrt (z));
- }
- }
-
- /* transform each pixel value */
-
- for (i = 0; i < nRow; i++)
- for (j = 0; j < nCol; j++)
- image[i][j] = transform[image[i][j]];
-
- ImageOut (argv[2], imgI);
- return (0);
- }
-
- /* 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: histramp inimg outimg [-s SLOPE_SIGN] [-L]\n");
- if (flag == 0)
- return (-1);
-
- printf ("\nhistramp transforms image intensity distribution\n");
- printf ("to enhance contrast in dark, medium, or light intensities.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -s SLOPE_SIGN: is a value of -1, 0, or 1, connoting the sign\n");
- printf (" of the intensity histogram shape. This increases contrast\n");
- printf (" in intensity ranges high (-1), medium (0), or low (1)\n");
- printf (" intensity ranges;\n");
- printf (" the default SLOPE is 0, which yields uniform contrast\n");
- printf (" distribution across all intensities (known as histogram\n");
- printf (" equalization)\n");
- printf (" -L: print Software License for this module\n");
-
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, &slopeSign)
- */
-
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- input (argc, argv, slopeSign)
- int argc;
- char *argv[];
- long *slopeSign; /* sign of slope of histogram */
- {
- long n;
-
- if (argc == 1)
- USAGE_EXIT (1);
- if (argc == 2)
- USAGE_EXIT (0);
-
- *slopeSign = DFLT_SLOPE;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-s") == 0) {
- if (++n == argc)
- USAGE_EXIT (0);
- *slopeSign = (long) atol (argv[n]);
- }
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (0);
- }
-
- return (0);
- }
-