Main Page   Data Structures   File List   Data Fields   Globals  

fconvl.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1990 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   This function convolves an image with a filter function, using the       */
00009 /*   Fast Fourier transform.                                                  */
00010 /*                                                                            */
00011 /*----------------------------------------------------------------------------*/
00012 /*-Interface Information------------------------------------------------------*/
00013 void
00014 FCONVL (IMAGE * in,             /*  I   Pointer to the input image.                           */
00015         IMAGE * filter,         /*  I   Pointer to the filter image.                          */
00016         short option,           /*  I   Switch, indicating the type of filter function:       */
00017         /*      PSF  -  spatial kernel.                               */
00018         /*      OTF  -  frequency transfer function.                  */
00019         IMAGE ** out            /*  O   Address of a pointer to the output image.             */
00020 /*----------------------------------------------------------------------------*/
00021   )
00022 {
00023   register short i, j, k;
00024   char msg[SLEN];
00025   short jbgn, kbgn;
00026   double pinc, psum;
00027   IMAGE *scratch1 = 0, *scratch2 = 0, *scratch3 = 0, *scratch4 = 0, *flt;
00028 
00029   if (TIMES)
00030     TIMING (T_FCONVL);
00031   if (NAMES)
00032     {
00033       MESSAGE ('I', "");
00034       MESSAGE ('I', "FCONVL");
00035       MESSAGE ('I', "");
00036       sprintf (msg, " Input image:    %s", in->text);
00037       MESSAGE ('I', msg);
00038       sprintf (msg, " Filter image:   %s", filter->text);
00039       MESSAGE ('I', msg);
00040       if (option == PSF)
00041         {
00042           MESSAGE ('I', " Filter image is spatial kernel");
00043         }
00044       else if (option == OTF)
00045         {
00046           MESSAGE ('I', " Filter image is frequency transfer function");
00047         }
00048       MESSAGE ('I', " ...............");
00049     }
00050 
00051   /* check input */
00052   if (!CHECKIMG (in))
00053     {
00054       MESSAGE ('E', " Can't identify image.");
00055       goto the_end;
00056     }
00057   else if (in->nlin != 1L << rnd (log10 ((double) in->nlin) / log10 (2.0)))
00058     {
00059       MESSAGE ('E', " Number of lines must be a power of two.");
00060       goto the_end;
00061     }
00062   else if (in->npix != 1L << rnd (log10 ((double) in->npix) / log10 (2.0)))
00063     {
00064       MESSAGE ('E', " Number of pixels/line must be a power of two.");
00065       goto the_end;
00066     }
00067   else if (!CHECKIMG (filter))
00068     {
00069       MESSAGE ('E', " Can't identify filter image.");
00070       goto the_end;
00071     }
00072   else if (in->nbnd != filter->nbnd)
00073     {
00074       MESSAGE ('E', " Number of bands must be identical in both images.");
00075       goto the_end;
00076     }
00077   if (option == PSF)
00078     {
00079       if (in->nlin < filter->nlin)
00080         {
00081           MESSAGE ('E',
00082                    " Image size in lines must be equal to or greater than that of filter image.");
00083           goto the_end;
00084         }
00085       else if (in->npix < filter->npix)
00086         {
00087           MESSAGE ('E',
00088                    " Image size in pixels/line must be equal to or greater than that of filter image.");
00089           goto the_end;
00090         }
00091     }
00092   else                          /* (option == OTF) */
00093     {
00094       if (in->nlin != filter->nlin)
00095         {
00096           MESSAGE ('E',
00097                    " Image size in lines in the frequency domain must be equal to that of filter image.");
00098           goto the_end;
00099         }
00100       else if (in->npix != filter->npix / 2)
00101         {
00102           MESSAGE ('E',
00103                    " Image size in pixels/line in the frequency domain must be equal to that of filter image.");
00104           goto the_end;
00105         }
00106     }
00107 
00108   /* Fourier transform input image */
00109   FFT2D (in, FORWARD, &scratch1);
00110   if (ABORT || !scratch1)
00111     goto the_end;
00112   sprintf (scratch1->text, "Scratch");
00113 
00114   if (option == PSF)
00115     {
00116       /* Zero-pad (if necessary) and Fourier transform point-spread function */
00117       if (in->nlin > filter->nlin || in->npix > filter->npix)
00118         {
00119           jbgn = (in->nlin - filter->nlin) / 2;
00120           kbgn = (in->npix - filter->npix) / 2;
00121           MOSAIC (&filter, 1, in->nlin, in->npix, &jbgn, &kbgn, (PIXEL) 0,
00122                   &scratch2);
00123           if (ABORT || !scratch2)
00124             goto the_end;
00125           sprintf (scratch2->text, "Scratch");
00126           FFT2D (scratch2, FORWARD, &scratch3);
00127           if (ABORT || !scratch3)
00128             goto the_end;
00129           sprintf (scratch3->text, "Scratch");
00130           flt = scratch3;
00131         }
00132       else
00133         {
00134           FFT2D (filter, FORWARD, &scratch2);
00135           if (ABORT || !scratch2)
00136             goto the_end;
00137           sprintf (scratch2->text, "Scratch");
00138           flt = scratch2;
00139         }
00140     }
00141   else                          /* (option == OTF) */
00142     {
00143       flt = filter;
00144     }
00145 
00146   /* create image of appropriate size */
00147   GETMEM (scratch1->nbnd, scratch1->nlin, scratch1->npix, &scratch4);
00148   if (!scratch4)
00149     goto the_end;
00150   sprintf (scratch4->text, "Scratch");
00151 
00152   /* initialize progress indicator */
00153   if (LINES && !PROGRESS (psum = 0.0))
00154     goto the_end;
00155   pinc = 1.0 / (double) scratch1->nbnd / (double) scratch1->nlin;
00156 
00157   /* multiply two complex images */
00158   for (i = 0; i < scratch1->nbnd; i += 1)
00159     {
00160       for (j = 0; j < scratch1->nlin; j += 1)
00161         {
00162           for (k = 0; k < scratch1->npix; k += 2)
00163             {
00164               scratch4->data[i][j][k] =
00165                 (PIXEL) ((double) scratch1->data[i][j][k] *
00166                          (double) flt->data[i][j][k] -
00167                          (double) scratch1->data[i][j][k +
00168                                                        1] *
00169                          (double) flt->data[i][j][k + 1]);
00170               scratch4->data[i][j][k + 1] =
00171                 (PIXEL) ((double) scratch1->data[i][j][k + 1] *
00172                          (double) flt->data[i][j][k] +
00173                          (double) scratch1->data[i][j][k] *
00174                          (double) flt->data[i][j][k + 1]);
00175             }
00176           if (LINES && !PROGRESS (psum += pinc))
00177             goto the_end;
00178         }
00179     }
00180 
00181   /* Fourier transform filtered image */
00182   FFT2D (scratch4, INVERSE, out);
00183 
00184 the_end:
00185   if (scratch1)
00186     RELMEM (scratch1);
00187   if (scratch2)
00188     RELMEM (scratch2);
00189   if (scratch3)
00190     RELMEM (scratch3);
00191   if (scratch4)
00192     RELMEM (scratch4);
00193   if (TIMES)
00194     TIMING (T_EXIT);
00195 }

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