Main Page   Data Structures   File List   Data Fields   Globals  

match.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 /*   This function transforms the graylevels of one image to match those      */
00009 /*   of a second image.  The first option uses a least-squares match, and     */
00010 /*   the second option uses the cumulative distribution functions of both     */
00011 /*   images.                                                                  */
00012 /*                                                                            */
00013 /*----------------------------------------------------------------------------*/
00014 /*-Background Information-----------------------------------------------------*/
00015 /*                                                                            */
00016 /*   Dallas, W.J. and Mauser, W.:                                             */
00017 /*   "Preparing Pictures for Visual Comparison."                              */
00018 /*   Applied Optics, Vol. 19, No. 21, November 1980                           */
00019 /*                                                                            */
00020 /*----------------------------------------------------------------------------*/
00021 /*-Interface Information------------------------------------------------------*/
00022 void
00023 MATCH (IMAGE * in1,             /*  I  Pointer to the transformation image.                  */
00024        IMAGE * in2,             /*  I  Pointer to the reference image.                       */
00025        short nlev,              /*  I  Number of graylevels to be used in the transformation. */
00026        short option,            /*  I  Switch, indicating type of image matching             */
00027        /*     LSQ   -   Images matched using gray levels            */
00028        /*     CDF   -   Images matched using cumulative dist fncns  */
00029        IMAGE ** out             /*  O  Address of a pointer to the output image.             */
00030        /*     The input image may be overwritten (out = &in1).      */
00031 /*----------------------------------------------------------------------------*/
00032   )
00033 {
00034   register short i, j, k, index, index2;
00035   char msg[SLEN];
00036   long *count = 0, *hist1 = 0, *hist2 = 0;
00037   double offset, offset2, factor, factor2, pinc, psum, *cdf1 = 0, *cdf2 = 0;
00038   PIXEL *table = 0;
00039   char minlbl[10], maxlbl[10];
00040 
00041   if (TIMES)
00042     TIMING (T_MATCH);
00043   if (NAMES)
00044     {
00045       MESSAGE ('I', "");
00046       MESSAGE ('I', "MATCH");
00047       MESSAGE ('I', "");
00048       sprintf (msg, " Transformation input image:   %s", in1->text);
00049       MESSAGE ('I', msg);
00050       sprintf (msg, " Reference input image:        %s", in2->text);
00051       MESSAGE ('I', msg);
00052       sprintf (msg, " Lookup table entries:         %d", nlev);
00053       MESSAGE ('I', msg);
00054       if (option == LSQ)
00055         {
00056           MESSAGE ('I', " Least squares transformation");
00057         }
00058       else
00059         {
00060           MESSAGE ('I', " CDF transformation");
00061         }
00062       MESSAGE ('I', " ...............");
00063     }
00064 
00065   /* check input */
00066   if (!CHECKIMG (in1))
00067     {
00068       MESSAGE ('E', " Can't identify transformation image.");
00069       goto the_end;
00070     }
00071   else if (!CHECKIMG (in2))
00072     {
00073       MESSAGE ('E', " Can't identify reference image.");
00074       goto the_end;
00075     }
00076   else if (in1->nbnd != in2->nbnd)
00077     {
00078       MESSAGE ('E', " Number of bands must be identical in both images.");
00079       goto the_end;
00080     }
00081   else if (in1->nlin != in2->nlin)
00082     {
00083       MESSAGE ('E', " Number of lines must be identical in both images.");
00084       goto the_end;
00085     }
00086   else if (in1->npix != in2->npix)
00087     {
00088       MESSAGE ('E',
00089                " Number of pixels/line must be identical in both images.");
00090       goto the_end;
00091     }
00092   else if (nlev <= 0)
00093     {
00094       MESSAGE ('E', " Number of graylevel bins must be greater than zero.");
00095       goto the_end;
00096     }
00097   else if (option != LSQ && option != CDF)
00098     {
00099       MESSAGE ('E', " Option must be either LSQ or CDF.");
00100       goto the_end;
00101     }
00102 
00103   /* create image of appropriate size */
00104   if (!CHECKIMG (*out))
00105     GETMEM (in1->nbnd, in1->nlin, in1->npix, out);
00106   if (!*out)
00107     goto the_end;
00108 
00109   /* initialize progress indicator */
00110   if (LINES && !PROGRESS (psum = 0.0))
00111     goto the_end;
00112   pinc =
00113     (option == LSQ ? 0.5 : 1.0) / (double) in1->nbnd / (double) in1->nlin;
00114 
00115   /* allocate space for array */
00116   if (!(table = (PIXEL *) malloc (nlev * sizeof (PIXEL))))
00117     {
00118       MESSAGE ('E', " Memory request failed.");
00119       goto the_end;
00120     }
00121 
00122   /* initialize */
00123   RANGE (in1);
00124   offset = (double) in1->gmin;
00125   factor = (double) (nlev - 1) / (double) (in1->gmax - in1->gmin);
00126 
00127   if (option == LSQ)
00128     {
00129 
00130       /* allocate space for array */
00131       if (!(count = (long *) malloc (nlev * sizeof (long))))
00132         {
00133           MESSAGE ('E', " Memory request failed.");
00134           goto the_end;
00135         }
00136 
00137       for (i = 0; i < in1->nbnd; i++)
00138         {
00139 
00140           /* build look-up table */
00141           for (index = 0; index < nlev; index++)
00142             {
00143               table[index] = (PIXEL) 0;
00144               count[index] = 0L;
00145             }
00146           for (j = 0; j < in1->nlin; j++)
00147             {
00148               for (k = 0; k < in1->npix; k++)
00149                 {
00150                   index =
00151                     (short) (((double) in1->data[i][j][k] - offset) * factor);
00152                   table[index] += in2->data[i][j][k];
00153                   count[index] += 1L;
00154                 }
00155               if (LINES && !PROGRESS (psum += pinc))
00156                 goto the_end;
00157             }
00158 
00159           /* average the table with the count array */
00160           for (index = 0; index < nlev; index++)
00161             {
00162               if (count[index] != 0)
00163                 {
00164                   table[index] /= (double) count[index];
00165                 }
00166             }
00167 
00168           /* create output image */
00169           for (j = 0; j < in1->nlin; j++)
00170             {
00171               for (k = 0; k < in1->npix; k++)
00172                 {
00173                   index =
00174                     (short) (((double) in1->data[i][j][k] - offset) * factor);
00175                   (*out)->data[i][j][k] = table[index];
00176                 }
00177               if (LINES && !PROGRESS (psum += pinc))
00178                 goto the_end;
00179             }
00180 
00181           /* output look-up table */
00182           sprintf (minlbl, "0");
00183           sprintf (maxlbl, "%d", nlev);
00184           PLOT (&table, 1, nlev, minlbl, maxlbl, NORM);
00185         }
00186 
00187     }
00188   else
00189     {
00190 
00191       /* allocate space for histograms of reference and transform images and cdf's */
00192       if (!(hist1 = (long *) malloc (in1->nbnd * nlev * sizeof (long))))
00193         {
00194           MESSAGE ('E', " Memory request failed.");
00195           goto the_end;
00196         }
00197       if (!(hist2 = (long *) malloc (in2->nbnd * nlev * sizeof (long))))
00198         {
00199           MESSAGE ('E', " Memory request failed.");
00200           goto the_end;
00201         }
00202       if (!(cdf1 = (double *) malloc (in1->nbnd * nlev * sizeof (double))))
00203         {
00204           MESSAGE ('E', " Memory request failed.");
00205           goto the_end;
00206         }
00207       if (!(cdf2 = (double *) malloc (in2->nbnd * nlev * sizeof (double))))
00208         {
00209           MESSAGE ('E', " Memory request failed.");
00210           goto the_end;
00211         }
00212 
00213       /* compute cumulative distribution function for transformation image */
00214       RANGE (in1);
00215       HISTOGRM (in1, 1, in1->gmin, in1->gmax, nlev, hist1);
00216       for (i = 0; i < in1->nbnd; i++)
00217         {
00218           for (j = 1; j < nlev; j++)
00219             {
00220               hist1[i * nlev + j] += hist1[i * nlev + j - 1];
00221             }
00222         }
00223 
00224       /* scale cumulative distribution function to [0,1] */
00225       for (i = 0; i < in1->nbnd; i++)
00226         {
00227           for (j = 0; j < nlev; j++)
00228             {
00229               cdf1[i * nlev + j] =
00230                 (double) (hist1[i * nlev + j]) / (double) (hist1[nlev - 1]);
00231             }
00232         }
00233 
00234       /* compute cumulative distribution function for reference image */
00235       RANGE (in2);
00236       HISTOGRM (in2, 1, in2->gmin, in2->gmax, nlev, hist2);
00237       for (i = 0; i < in2->nbnd; i++)
00238         {
00239           for (j = 1; j < nlev; j++)
00240             {
00241               hist2[i * nlev + j] += hist2[i * nlev + j - 1];
00242             }
00243         }
00244 
00245       /* scale cumulative distribution function to [0,1] */
00246       for (i = 0; i < in1->nbnd; i++)
00247         {
00248           for (j = 0; j < nlev; j++)
00249             {
00250               cdf2[i * nlev + j] =
00251                 (double) (hist2[i * nlev + j]) / (double) (hist2[nlev - 1]);
00252             }
00253         }
00254 
00255       offset2 = (double) in2->gmin;
00256       factor2 = (double) (nlev - 1) / (double) (in2->gmax - in2->gmin);
00257 
00258       /* loop through histograms making the lookup table entries table[index] = cdf2 <inverse> [cdf1[index]] */
00259       for (i = 0; i < in1->nbnd; i++)
00260         {
00261           for (index = 0; index < nlev; index++)
00262             {
00263               for (index2 = 0; index2 < nlev; index2++)
00264                 {
00265                   if (cdf2[i * nlev + index2] == cdf1[i * nlev + index])
00266                     {
00267                       table[index] =
00268                         (PIXEL) index2 / (PIXEL) factor2 + offset2;
00269                       break;
00270                     }
00271                   else if (cdf2[i * nlev + index2] > cdf1[i * nlev + index])
00272                     {
00273                       if (index2 == 0)
00274                         {
00275                           table[index] = offset2;
00276                         }
00277                       else
00278                         {
00279                           if ((cdf2[i * nlev + index2] -
00280                                cdf1[i * nlev + index]) <=
00281                               (cdf1[i * nlev + index] -
00282                                cdf2[i * nlev + index2 - 1]))
00283                             {
00284                               table[index] =
00285                                 (PIXEL) index2 / (PIXEL) factor2 + offset2;
00286                             }
00287                           else
00288                             {
00289                               table[index] =
00290                                 (PIXEL) (index2 - 1) / (PIXEL) factor2 +
00291                                 offset2;
00292                             }
00293                         }
00294                       break;
00295                     }
00296                 }
00297             }
00298 
00299           /* create output image */
00300           for (j = 0; j < in1->nlin; j++)
00301             {
00302               for (k = 0; k < in1->npix; k++)
00303                 {
00304                   index =
00305                     (short) (((double) (in1->data[i][j][k] - offset) *
00306                               factor) + 0.5);
00307                   (*out)->data[i][j][k] = table[index];
00308                 }
00309               if (LINES && !PROGRESS (psum += pinc))
00310                 goto the_end;
00311             }
00312 
00313           /* output the lookup table */
00314           sprintf (minlbl, "0");
00315           sprintf (maxlbl, "%d", nlev);
00316           PLOT (&table, 1, nlev, minlbl, maxlbl, NORM);
00317         }
00318     }
00319 
00320 the_end:
00321   if (table)
00322     free (table);
00323   if (count)
00324     free (count);
00325   if (hist1)
00326     free (hist1);
00327   if (hist2)
00328     free (hist2);
00329   if (cdf1)
00330     free (cdf1);
00331   if (cdf2)
00332     free (cdf2);
00333   if (TIMES)
00334     TIMING (T_EXIT);
00335 }

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