Main Page   Data Structures   File List   Data Fields   Globals  

destripe.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1992 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   There are three methods to use in destriping an image.                   */
00009 /*   All use either a single detector or the average of all detectors as      */
00010 /*   a reference.  The first method adjusts the means of all the detectors    */
00011 /*   to match that of the reference.  The second method adjusts the means and */
00012 /*   standard deviations to match those of the reference.  The third method   */
00013 /*   computes cumulative distribution functions using a specified number of   */
00014 /*   levels for the reference and each of the detectors.  These are then used */
00015 /*   in matching the contrast of the detectors to that of the reference.      */
00016 /*                                                                            */
00017 /*----------------------------------------------------------------------------*/
00018 /*-Interface Information------------------------------------------------------*/
00019 void
00020 DESTRIPE (IMAGE * in,           /*  I  Pointer to the image.                                 */
00021           short option,         /*  I  Switch, indicating type of line matching              */
00022           /*     DESMNE - Destripe using mean only levels              */
00023           /*     DESSTD - Destripe using mean and standard dev.        */
00024           /*     DESCDF - Destripe using cumulative dist. function     */
00025           short roption,        /*  I  Switch, indicating type of reference used             */
00026           /*     DESSNG - Use a single line (detector) as reference    */
00027           /*     DESAVG - Average all detectors for reference          */
00028           short lines,          /*  I  Number of lines to destripe - ie, number of           */
00029           /*     detectors.  Must be a factor of total image line num  */
00030           short refline,        /*  I  The line (detector) to be used for destriping.        */
00031           /*     This value does not matter if DESAVG is selected.     */
00032           short nlev,           /*  I  The number of levels used in the cumulative           */
00033           /*     distribution function for the reference and           */
00034           /*     transformation lines.                                 */
00035           IMAGE ** out          /*  O  Address of a pointer to the output image.             */
00036           /*     The input image may be overwritten (out = &in1).      */
00037 /*----------------------------------------------------------------------------*/
00038   )
00039 {
00040   register short i, j, k, l;
00041   short skip, index, index2;
00042   double mean, stddev, oldmean, oldstddev, factor, *rcdf = 0, *tcdf = 0;
00043   PIXEL *table = 0;
00044 
00045   if (TIMES)
00046     TIMING (T_DESTRIPE);
00047   if (NAMES)
00048     {
00049       MESSAGE ('I', "");
00050       MESSAGE ('I', "DESTRIPE");
00051     }
00052 
00053   /* check input */
00054   if (!CHECKIMG (in))
00055     {
00056       MESSAGE ('E', " Can't identify image.");
00057       goto the_end;
00058     }
00059   else if (option != DESMNE && option != DESSTD && option != DESCDF)
00060     {
00061       MESSAGE ('E', " Option must be DESMNE, DESSTD, or DESCDF.");
00062       goto the_end;
00063     }
00064   else if (roption != DESSNG && roption != DESAVG)
00065     {
00066       MESSAGE ('E', " Reference option must be either DESSNG or DESAVG.");
00067       goto the_end;
00068     }
00069 
00070   /* create image of appropriate size */
00071   if (!CHECKIMG (*out))
00072     GETMEM (in->nbnd, in->nlin, in->npix, out);
00073   if (!*out)
00074     goto the_end;
00075 
00076   /* Set up image hopping parameters */
00077   if (roption == DESAVG)
00078     {
00079       refline = 1;
00080       skip = 1;
00081     }
00082   else
00083     {
00084       skip = lines;
00085     }
00086 
00087   if (option == DESMNE || option == DESSTD)
00088     {
00089 
00090       for (i = 0; i < in->nbnd; i++)
00091         {
00092 
00093           /* compute reference mean */
00094           mean = 0.0;
00095           for (j = refline - 1; j < in->nlin; j += skip)
00096             {
00097               for (k = 0; k < in->npix; k++)
00098                 {
00099                   mean += (double) in->data[i][j][k];
00100                 }
00101             }
00102           if (roption == DESSNG)
00103             {
00104               mean /= (double) in->npix * (double) (j - refline +
00105                                                     1) / (double) lines;
00106             }
00107           else
00108             {
00109               mean /= (double) in->npix * (double) in->nlin;
00110             }
00111 
00112           /* compute reference standard deviation */
00113           if (option == DESSTD)
00114             {
00115               stddev = 0.0;
00116               for (j = refline - 1; j < in->nlin; j += skip)
00117                 {
00118                   for (k = 0; k < in->npix; k++)
00119                     {
00120                       stddev +=
00121                         ((double) in->data[i][j][k] -
00122                          mean) * ((double) in->data[i][j][k] - mean);
00123                     }
00124                 }
00125               if (roption == DESSNG)
00126                 {
00127                   stddev /= (double) in->npix * (double) (j - refline +
00128                                                           1) / (double) lines;
00129                 }
00130               else
00131                 {
00132                   stddev /= (double) in->npix * (double) in->nlin;
00133                 }
00134               stddev = sqrt (stddev);
00135             }
00136 
00137           /* Calculate mean and/or standard deviation of each line to be transformed. Copy reference line to output. */
00138           for (j = 0; j < lines; j++)
00139             {
00140 
00141               if (roption == DESSNG && j == refline - 1)
00142                 {
00143                   /* copy reference lines (detector) directly to output image */
00144                   for (k = j; k < in->nlin; k += lines)
00145                     {
00146                       for (l = 0; l < in->npix; l++)
00147                         {
00148                           (*out)->data[i][k][l] = in->data[i][k][l];
00149                         }
00150                     }
00151                 }
00152               else
00153                 {
00154                   /* compute mean of one set of lines (one detector) */
00155                   oldmean = 0.0;
00156                   for (k = j; k < in->nlin; k += lines)
00157                     {
00158                       for (l = 0; l < in->npix; l++)
00159                         {
00160                           oldmean += (double) in->data[i][k][l];
00161                         }
00162                     }
00163                   oldmean /= (double) in->npix * (double) (k -
00164                                                            j) /
00165                     (double) lines;
00166 
00167                   /* compute standard deviation of one set of lines (one detector) */
00168                   if (option == DESSTD)
00169                     {
00170                       oldstddev = 0.0;
00171                       for (k = j; k < in->nlin; k += lines)
00172                         {
00173                           for (l = 0; l < in->npix; l++)
00174                             {
00175                               oldstddev +=
00176                                 ((double) in->data[i][k][l] -
00177                                  oldmean) * ((double) in->data[i][k][l] -
00178                                              oldmean);
00179                             }
00180                         }
00181                       oldstddev /= (double) in->npix * (double) (k -
00182                                                                  j) /
00183                         (double) lines;
00184                       oldstddev = sqrt (oldstddev);
00185                     }
00186 
00187                   /* copy transformed line to output, adjusting gray levels to achieve mean and/or standard deviation of reference */
00188                   for (k = j; k < in->nlin; k += lines)
00189                     {
00190                       for (l = 0; l < in->npix; l++)
00191                         {
00192                           if (option == DESMNE)
00193                             {
00194                               (*out)->data[i][k][l] =
00195                                 (PIXEL) ((double) in->data[i][k][l] -
00196                                          oldmean + mean);
00197                             }
00198                           else
00199                             {
00200                               (*out)->data[i][k][l] =
00201                                 (PIXEL) (((double) in->data[i][k][l] -
00202                                           oldmean) * stddev / oldstddev +
00203                                          mean);
00204                             }
00205                         }
00206                     }
00207                 }
00208             }
00209         }
00210 
00211     }
00212   else
00213     {
00214 
00215       if (!(rcdf = (double *) malloc (nlev * sizeof (double))))
00216         {
00217           MESSAGE ('E', " Memory request failed.");
00218           goto the_end;
00219         }
00220       if (!(tcdf = (double *) malloc (nlev * sizeof (double))))
00221         {
00222           MESSAGE ('E', " Memory request falied.");
00223           goto the_end;
00224         }
00225       if (!(table = (PIXEL *) malloc (nlev * sizeof (PIXEL))))
00226         {
00227           MESSAGE ('E', " Memory request failed.");
00228           goto the_end;
00229         }
00230 
00231       RANGE (in);
00232       factor = (double) (nlev - 1) / (double) (in->gmax - in->gmin);
00233 
00234       for (i = 0; i < in->nbnd; i++)
00235         {
00236 
00237           /* compute histogram of reference */
00238           for (j = 0; j < nlev; j++)
00239             {
00240               rcdf[j] = 0.0;
00241             }
00242           for (j = refline - 1; j < in->nlin; j += skip)
00243             {
00244               for (k = 0; k < in->npix; k++)
00245                 {
00246                   rcdf[(short)
00247                        ((double) (in->data[i][j][k] - in->gmin) * factor +
00248                         0.5)] += 1.0;
00249                 }
00250             }
00251 
00252           /* convert histogram to cumulative distribution function and scale to [0,1] */
00253           for (j = 1; j < nlev; j++)
00254             {
00255               rcdf[j] += rcdf[j - 1];
00256             }
00257           for (j = 0; j < nlev; j++)
00258             {
00259               rcdf[j] /= rcdf[nlev - 1];
00260             }
00261 
00262           /* loop through each line, calculate cdf, and use it to transform the line */
00263           for (j = 0; j < lines; j++)
00264             {
00265 
00266               /* copy reference lines (detector) directly to output image */
00267               if (roption == DESSNG && j == refline - 1)
00268                 {
00269                   for (k = j; k < in->nlin; k += lines)
00270                     {
00271                       for (l = 0; l < in->npix; l++)
00272                         {
00273                           (*out)->data[i][k][l] = in->data[i][k][l];
00274                         }
00275                     }
00276                 }
00277               else
00278                 {
00279 
00280                   /* compute histogram of one set of lines (one detector) */
00281                   for (k = 0; k < nlev; k++)
00282                     {
00283                       tcdf[k] = 0.0;
00284                     }
00285                   for (k = j; k < in->nlin; k += lines)
00286                     {
00287                       for (l = 0; l < in->npix; l++)
00288                         {
00289                           tcdf[(short)
00290                                ((double) (in->data[i][k][l] - in->gmin) *
00291                                 factor + 0.5)] += 1;
00292                         }
00293                     }
00294 
00295                   /* convert histogram to cumulative distribution function amd scale to [0,1] */
00296                   for (k = 1; k < nlev; k++)
00297                     {
00298                       tcdf[k] += tcdf[k - 1];
00299                     }
00300                   for (k = 0; k < nlev; k++)
00301                     {
00302                       tcdf[k] /= tcdf[nlev - 1];
00303                     }
00304 
00305                   /* loop through histograms making lookup table entries */
00306                   for (index = 0; index < nlev; index++)
00307                     {
00308                       for (index2 = 0; index2 < nlev; index2++)
00309                         {
00310                           if (rcdf[index2] == tcdf[index])
00311                             {
00312                               table[index] =
00313                                 (PIXEL) index2 / (PIXEL) factor + in->gmin;
00314                               break;
00315                             }
00316                           else if (rcdf[index2] > tcdf[index])
00317                             {
00318                               if (index2 == 0)
00319                                 {
00320                                   table[index] = in->gmin;
00321                                 }
00322                               else
00323                                 {
00324                                   if (rcdf[index2] - tcdf[index] <=
00325                                       tcdf[index] - rcdf[index2 - 1])
00326                                     {
00327                                       table[index] =
00328                                         (PIXEL) index2 / (PIXEL) factor +
00329                                         in->gmin;
00330                                     }
00331                                   else
00332                                     {
00333                                       table[index] =
00334                                         (PIXEL) (index2 -
00335                                                  1) / (PIXEL) factor +
00336                                         in->gmin;
00337                                     }
00338                                 }
00339                               break;
00340                             }
00341                         }
00342                     }
00343 
00344                   /* create new set of lines (detector) for output image */
00345                   for (k = j; k < in->nlin; k += lines)
00346                     {
00347                       for (l = 0; l < in->npix; l++)
00348                         {
00349                           index =
00350                             (short) ((double) (in->data[i][k][l] - in->gmin) *
00351                                      factor + 0.5);
00352                           (*out)->data[i][k][l] = table[index];
00353                         }
00354                     }
00355                 }
00356             }
00357         }
00358     }
00359 
00360 the_end:
00361   if (rcdf)
00362     free (rcdf);
00363   if (tcdf)
00364     free (tcdf);
00365   if (table)
00366     free (table);
00367   if (TIMES)
00368     TIMING (T_EXIT);
00369 }

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