home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_3.9 / THRESHE / THRESHE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  4.3 KB  |  177 lines

  1. /* 
  2.  * threshe.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* THRESHE:     program performs binarization by maximum entropy method
  10.  *                    usage: threshe inimg outimg [-i] [-L]
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <images.h>
  18. #include <tiffimage.h>
  19. #include <math.h>
  20. extern void print_sos_lic ();
  21.  
  22. #define NHIST 256               /* no. bins in histogram */
  23.  
  24. long input (int, char **, short *);
  25. long usage (short);
  26.  
  27. main (
  28.        int argc,
  29.        char *argv[])
  30. {
  31.   Image *imgI, *imgO;           /* I/O image structures */
  32.   unsigned char **imgIn, **imgOut;  /* input and output images */
  33.   long width, height;           /* image size */
  34.   long iHist[NHIST];            /* hist. of intensities */
  35.   double prob[NHIST];
  36.   double Hn, Ps, Hs;
  37.   double psi, psiMax;
  38.   long thresh;
  39.   short invertFlag;             /* if =0, dark -> ON; if =1, dark -> OFF */
  40.   long x, y;                    /* image coordinates */
  41.   long i, j, n;
  42.  
  43.   if (input (argc, argv, &invertFlag) < 0)
  44.     return (-1);
  45.  
  46. /* allocate input and output image memory */
  47.   imgI = ImageIn (argv[1]);
  48.   imgIn = ImageGetPtr (imgI);
  49.   height = ImageGetHeight (imgI);
  50.   width = ImageGetWidth (imgI);
  51.   imgO = ImageAlloc (height, width, 8);
  52.   imgOut = ImageGetPtr (imgO);
  53.  
  54. /* compile histogram */
  55.   printf ("MAIN: Compile histogram...\n");
  56.   for (i = 0; i < NHIST; i++)
  57.     iHist[i] = 0;
  58.   for (y = 0, n = 0; y < height; y++) {
  59.     for (x = 0; x < width; x++) {
  60.       iHist[imgIn[y][x]]++;
  61.       n++;
  62.     }
  63.   }
  64.  
  65. /* compute probabilities */
  66.   for (i = 0; i < NHIST; i++)
  67.     prob[i] = (double) iHist[i] / (double) n;
  68.  
  69. /* find threshold */
  70.   for (i = 0, Hn = 0.0; i < NHIST; i++)
  71.     if (prob[i] != 0.0)
  72.       Hn -= prob[i] * log (prob[i]);
  73.  
  74.   for (i = 1, psiMax = 0.0; i < NHIST; i++) {
  75.     for (j = 0, Ps = Hs = 0.0; j < i; j++) {
  76.       Ps += prob[j];
  77.       if (prob[j] > 0.0)
  78.         Hs -= prob[j] * log (prob[j]);
  79.     }
  80.     if (Ps > 0.0 && Ps < 1.0)
  81.       psi = log (Ps - Ps * Ps) + Hs / Ps + (Hn - Hs) / (1.0 - Ps);
  82.     if (psi > psiMax) {
  83.       psiMax = psi;
  84.       thresh = i;
  85.     }
  86.   }
  87.  
  88.   printf ("Calculated threshold value (by Entropy method) = %d.\n", thresh);
  89.  
  90. /* output thresholded image */
  91.   if (invertFlag == 0) {
  92.     for (y = 0, n = 0; y < height; y++)
  93.       for (x = 0; x < width; x++)
  94.         imgOut[y][x] = (imgIn[y][x] > thresh) ? 255 : 0;
  95.   }
  96.   else {
  97.     for (y = 0, n = 0; y < height; y++)
  98.       for (x = 0; x < width; x++)
  99.         imgOut[y][x] = (imgIn[y][x] < thresh) ? 255 : 0;
  100.   }
  101.  
  102.   ImageOut (argv[2], imgO);
  103.  
  104.   return (0);
  105. }
  106.  
  107.  
  108.  
  109. /* USAGE:       function gives instructions on usage of program
  110.  *                    usage: usage (flag)
  111.  *              When flag is 1, the long message is given, 0 gives short.
  112.  */
  113.  
  114. long
  115. usage (flag)
  116.      short flag;                /* flag =1 for long message; =0 for short message */
  117. {
  118.  
  119. /* print short usage message or long */
  120.   printf ("USAGE: threshe inimg outimg [-i] [-L]\n");
  121.   if (flag == 0)
  122.     return (-1);
  123.  
  124.   printf ("\nthreshe performs binarization with respect to\n");
  125.   printf ("automatically determined intensity threshold;\n");
  126.   printf ("the input gray-level image is converted to a binary image;\n");
  127.   printf ("threshold determination is made by the maximum entropy\n");
  128.   printf ("method.\n\n");
  129.   printf ("ARGUMENTS:\n");
  130.   printf ("    inimg: input image filename (TIF)\n");
  131.   printf ("   outimg: output image filename (TIF)\n\n");
  132.   printf ("OPTIONS:\n");
  133.   printf ("       -i: INVERT: intensities ABOVE (lighter) threshold set to 0\n");
  134.   printf ("           and those BELOW (darker) threshold set to 255\n");
  135.   printf ("       -L: print Software License for this module\n");
  136.  
  137.   return (-1);
  138. }
  139.  
  140.  
  141. /* INPUT:       function reads input parameters
  142.  *                  usage: input (argc, argv)
  143.  */
  144.  
  145. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  146.  
  147. long
  148. input (argc, argv, invertFlag)
  149.      int argc;
  150.      char *argv[];
  151.      short *invertFlag;         /* if =0, dark -> ON; if =1, dark -> OFF */
  152.  
  153. {
  154.   long n;
  155.  
  156.   *invertFlag = 0;
  157.  
  158.   if (argc == 1)
  159.     USAGE_EXIT (1);
  160.   if (argc == 2)
  161.     USAGE_EXIT (0);
  162.  
  163.   for (n = 3; n < argc; n++) {
  164.     if (strcmp (argv[n], "-i") == 0) {
  165.       *invertFlag = 1;
  166.     }
  167.     else if (strcmp (argv[n], "-L") == 0) {
  168.       print_sos_lic ();
  169.       exit (0);
  170.     }
  171.     else
  172.       USAGE_EXIT (0);
  173.   }
  174.  
  175.   return (0);
  176. }
  177.