Main Page   Data Structures   File List   Data Fields   Globals  

stats.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   This function computes the mean, standard deviation, minimum, maximum,   */
00009 /*   and range of graylevels in an image, as well as the number of pixels     */
00010 /*   with a zero graylevel, and outputs a histogram.                          */
00011 /*                                                                            */
00012 /*----------------------------------------------------------------------------*/
00013 /*-Interface Information------------------------------------------------------*/
00014 short
00015 STATS (IMAGE * in,              /*  I   Pointer to the input image.                           */
00016        short inc,               /*  I   Pixels/line and line increment.                       */
00017        short nlev,              /*  I   > 0:   Number of bins in the histogram.               */
00018        /*      = 0:   Histogram is suppressed.                       */
00019        short option,            /*  I   Switch, indicating how to use input pixel range:      */
00020        /*      INCLUDE - Use only this input range for computing     */
00021        /*                statistics.                                 */
00022        /*      EXCLUDE - Exclude this pixel range.                   */
00023        /*      IGNORE  - Do not use the pixel range.                 */
00024        PIXEL rangemin,          /*  I   Minimum pixel value in range of interest.             */
00025        PIXEL rangemax,          /*  I   Maximum pixel value in range of interest.             */
00026        double *mean,            /*  O   Pointer to an array[nbnd], containing the             */
00027        /*      mean graylevel for each band.                         */
00028        double *dev,             /*  O   Pointer to an array[nbnd], containing the             */
00029        /*      graylevel standard deviation for each band.           */
00030        PIXEL * gmin,            /*  O   Pointer to an array[nbnd], containing the             */
00031        /*      minimum graylevel for each band.                      */
00032        PIXEL * gmax,            /*  O   Pointer to an array[nbnd], containing the             */
00033        /*      maximum graylevel for each band.                      */
00034        PIXEL * grng,            /*  O   Pointer to an array[nbnd], containing the             */
00035        /*      graylevel range for each band.                        */
00036        long *zero               /*  O   Pointer to an array[nbnd], containing the             */
00037        /*      number of pixels with a zero graylevel for each band. */
00038 /*----------------------------------------------------------------------------*/
00039   )
00040 {
00041   register int i, j, k;
00042   char msg[SLEN];
00043   long *hist = 0, maxval, npts;
00044   double sum, sumsq;
00045   PIXEL **arrays = NULL;
00046   char minlbl[20], maxlbl[20];
00047   int plotoption = NORM;
00048   long *include, *exclude;
00049 
00050   if (TIMES)
00051     TIMING (T_STATS);
00052   if (NAMES)
00053     {
00054       MESSAGE ('I', "");
00055       MESSAGE ('I', "STATS");
00056       MESSAGE ('I', "");
00057       sprintf (msg, " Input image:                         %s", in->text);
00058       MESSAGE ('I', msg);
00059       sprintf (msg, " Line and pixel subsample increment:  %d", inc);
00060       MESSAGE ('I', msg);
00061       if (nlev > 0)
00062         {
00063           sprintf (msg, " Histogram resolution:                %d", nlev);
00064           MESSAGE ('I', msg);
00065         }
00066       if (option == INCLUDE)
00067         {
00068           sprintf (msg,
00069                    " Include only pixels in the graylevel range: %.2f to %.2f",
00070                    rangemin, rangemax);
00071           MESSAGE ('I', msg);
00072         }
00073       else if (option == EXCLUDE)
00074         {
00075           sprintf (msg,
00076                    " Exclude pixels in the graylevel range: %.2f to %.2f",
00077                    rangemin, rangemax);
00078           MESSAGE ('I', msg);
00079         }
00080       MESSAGE ('I', " ...............");
00081     }
00082 
00083   /* check input */
00084   if (!CHECKIMG (in))
00085     {
00086       MESSAGE ('E', " Can't identify image.");
00087       goto the_end;
00088     }
00089   else if (inc <= 0)
00090     {
00091       MESSAGE ('E', " Increment must be greater than zero.");
00092       goto the_end;
00093     }
00094   else if (nlev < 0)
00095     {
00096       MESSAGE ('E',
00097                " Number of histogram bins must be greater than or equal to zero.");
00098       goto the_end;
00099     }
00100 
00101   /* compute and output statistics for each band */
00102   MESSAGE ('I', "");
00103   if (option != IGNORE)
00104     {
00105       MESSAGE ('I',
00106                " Band   Minimum     Maximum       Mean     Deviation       Zero/Non-Zero   Included/Excluded");
00107     }
00108   else
00109     {
00110       MESSAGE ('I',
00111                " Band   Minimum     Maximum       Mean     Deviation       Zero/Non-Zero");
00112     }
00113   MESSAGE ('I', "");
00114 
00115   RANGE (in);
00116   include = (long *) malloc ((in->nbnd) * sizeof (long));
00117   exclude = (long *) malloc ((in->nbnd) * sizeof (long));
00118   for (i = 0; i < in->nbnd; i++)
00119     {
00120       gmin[i] = in->gmax;
00121       gmax[i] = in->gmin;
00122       zero[i] = 0L;
00123 
00124       if (option != IGNORE)
00125         {
00126           include[i] = exclude[i] = 0L;
00127         }
00128 
00129       for (sum = sumsq = 0.0, j = 0; j < in->nlin; j += inc)
00130         {
00131           for (k = 0; k < in->npix; k += inc)
00132             {
00133               switch (option)
00134                 {
00135 
00136                 case INCLUDE:
00137                   if (in->data[i][j][k] >= rangemin
00138                       && in->data[i][j][k] <= rangemax)
00139                     {
00140                       sum += (double) in->data[i][j][k];
00141                       sumsq +=
00142                         (double) (in->data[i][j][k] * in->data[i][j][k]);
00143                       gmin[i] = min (gmin[i], in->data[i][j][k]);
00144                       gmax[i] = max (gmax[i], in->data[i][j][k]);
00145                       if (in->data[i][j][k] == (PIXEL) 0)
00146                         {
00147                           zero[i] += 1L;
00148                         }
00149                       include[i] += 1L;
00150                     }
00151                   else
00152                     {
00153                       exclude[i] += 1L;
00154                     }
00155                   break;
00156 
00157                 case EXCLUDE:
00158                   if (in->data[i][j][k] < rangemin
00159                       || in->data[i][j][k] > rangemax)
00160                     {
00161                       sum += (double) in->data[i][j][k];
00162                       sumsq +=
00163                         (double) (in->data[i][j][k] * in->data[i][j][k]);
00164                       gmin[i] = min (gmin[i], in->data[i][j][k]);
00165                       gmax[i] = max (gmax[i], in->data[i][j][k]);
00166                       if (in->data[i][j][k] == (PIXEL) 0)
00167                         {
00168                           zero[i] += 1L;
00169                         }
00170                       include[i] += 1L;
00171                     }
00172                   else
00173                     {
00174                       exclude[i] += 1L;
00175                     }
00176                   break;
00177 
00178                 default:
00179                   sum += (double) in->data[i][j][k];
00180                   sumsq += (double) (in->data[i][j][k] * in->data[i][j][k]);
00181                   gmin[i] = min (gmin[i], in->data[i][j][k]);
00182                   gmax[i] = max (gmax[i], in->data[i][j][k]);
00183                   if (in->data[i][j][k] == (PIXEL) 0)
00184                     {
00185                       zero[i] += 1L;
00186                     }
00187                   break;
00188 
00189                 }
00190 
00191             }
00192         }
00193       if (option != IGNORE)
00194         {
00195           if (include[i] > 0L)
00196             {
00197               mean[i] = sum / ((double) include[i]);
00198               dev[i] =
00199                 sqrt (sumsq / ((double) include[i]) - mean[i] * mean[i]);
00200               grng[i] = gmax[i] - gmin[i];
00201             }
00202           else
00203             {
00204               mean[i] = 0.0;
00205               dev[i] = 0.0;
00206               gmin[i] = gmax[i] = 0.0;
00207               grng[i] = 0.0;
00208             }
00209           sprintf (msg, "%5d%12.4e%12.4e%12.4e%12.4e%10ld/%ld%15ld/%ld",
00210                    i + 1, (double) gmin[i], (double) gmax[i], mean[i], dev[i],
00211                    zero[i], include[i] - zero[i], include[i], exclude[i]);
00212         }
00213       else
00214         {
00215           mean[i] =
00216             sum / ((double) (in->nlin / inc + (in->nlin % inc ? 1 : 0)) *
00217                    (double) (in->npix / inc + (in->npix % inc ? 1 : 0)));
00218           dev[i] =
00219             sqrt (sumsq /
00220                   ((double) (in->nlin / inc + (in->nlin % inc ? 1 : 0)) *
00221                    (double) (in->npix / inc + (in->npix % inc ? 1 : 0))) -
00222                   mean[i] * mean[i]);
00223           grng[i] = gmax[i] - gmin[i];
00224           sprintf (msg, "%5d%12.4e%12.4e%12.4e%12.4e%10ld/%ld", i + 1,
00225                    (double) gmin[i], (double) gmax[i], mean[i], dev[i],
00226                    zero[i], (long) in->nlin * (long) in->npix - zero[i]);
00227         }
00228 
00229       MESSAGE ('I', msg);
00230     }
00231 
00232   /* allocate space and compute histograms */
00233   if (nlev > 0)
00234     {
00235 
00236       /* Allocate memory for plotting */
00237       arrays = (PIXEL **) malloc (in->nbnd * sizeof (PIXEL *));
00238       if (!arrays)
00239         {
00240           MESSAGE ('E', " Error allocating memory for plotting!");
00241           goto the_end;
00242         }
00243       for (i = 0; i < in->nbnd; i++)
00244         {
00245           arrays[i] = NULL;
00246           arrays[i] = (PIXEL *) malloc (nlev * sizeof (PIXEL));
00247           if (!arrays[i])
00248             {
00249               MESSAGE ('E', " Error allocating memory for plotting!");
00250               goto the_end;
00251             }
00252         }
00253 
00254       RANGE (in);
00255       if (!(hist = (long *) malloc (in->nbnd * nlev * sizeof (long))))
00256         {
00257           MESSAGE ('E', " Memory request failed.");
00258           goto the_end;
00259         }
00260       MESSAGE ('I', "");
00261 
00262       if (option == INCLUDE)
00263         {
00264           sprintf (msg, " Histogram has %d levels between %.4e and %.4e",
00265                    nlev, (double) rangemin, (double) rangemax);
00266           MESSAGE ('I', msg);
00267           STRICTHISTOGRM (in, inc, option, rangemin, rangemax, nlev, hist);
00268         }
00269       else if (option == EXCLUDE)
00270         {
00271           sprintf (msg, " Histogram has %d levels between %.4e and %.4e",
00272                    nlev, (double) in->gmin, (double) in->gmax);
00273           MESSAGE ('I', msg);
00274           STRICTHISTOGRM (in, inc, option, rangemin, rangemax, nlev, hist);
00275         }
00276       else
00277         {
00278           sprintf (msg, " Histogram has %d levels between %.4e and %.4e",
00279                    nlev, (double) in->gmin, (double) in->gmax);
00280           MESSAGE ('I', msg);
00281           HISTOGRM (in, inc, in->gmin, in->gmax, nlev, hist);
00282         }
00283 
00284       /* Create data arrays for plotting */
00285       for (i = 0; i < in->nbnd; i++)
00286         {
00287           for (j = 0; j < nlev; j++)
00288             {
00289               arrays[i][j] = (PIXEL) hist[i * nlev + j];
00290             }
00291         }
00292 
00293       if (option == INCLUDE)
00294         {
00295           sprintf (minlbl, "%.2f", rangemin);
00296           sprintf (maxlbl, "%.2f", rangemax);
00297         }
00298       else
00299         {
00300           sprintf (minlbl, "%.2f", in->gmin);
00301           sprintf (maxlbl, "%.2f", in->gmax);
00302         }
00303 
00304       PLOT (arrays, in->nbnd, nlev, minlbl, maxlbl, plotoption);
00305     }
00306 
00307 the_end:
00308 
00309   /* Free Array */
00310   if (arrays)
00311     {
00312       for (i = 0; i < in->nbnd; i++)
00313         {
00314           if (arrays[i])
00315             free (arrays[i]);
00316           arrays[i] = NULL;
00317         }
00318       free (arrays);
00319       arrays = NULL;
00320     }
00321 
00322   if (hist)
00323     free (hist);
00324   if (TIMES)
00325     TIMING (T_EXIT);
00326 }

Generated on Sun May 18 15:36:18 2003 for tclSadie by doxygen1.3