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 FCONVL (
00014 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 ) { register short  i, j, k;
00022     char   msg[SLEN];
00023     short  jbgn, kbgn;
00024     double pinc, psum;
00025     IMAGE  *scratch1=0, *scratch2=0, *scratch3=0, *scratch4=0, *flt;
00026 
00027     if (TIMES) TIMING(T_FCONVL);
00028     if (NAMES) {
00029         MESSAGE('I',"");
00030         MESSAGE('I',"FCONVL");
00031         MESSAGE('I',"");
00032         sprintf(msg," Input image:    %s",in->text);
00033         MESSAGE('I',msg);
00034         sprintf(msg," Filter image:   %s",filter->text);
00035         MESSAGE('I',msg);
00036         if (option == PSF) {
00037             MESSAGE('I'," Filter image is spatial kernel");
00038         } else if (option == OTF) {
00039             MESSAGE('I'," Filter image is frequency transfer function");
00040         }
00041         MESSAGE('I'," ...............");
00042     }
00043 
00044     /* check input */
00045     if (!CHECKIMG(in)) {
00046         MESSAGE('E'," Can't identify image.");
00047         goto the_end;
00048     } else if (in->nlin != 1L<<rnd(log10((double)in->nlin)/log10(2.0))) {
00049         MESSAGE('E'," Number of lines must be a power of two.");
00050         goto the_end;
00051     } else if (in->npix != 1L<<rnd(log10((double)in->npix)/log10(2.0))) {
00052         MESSAGE('E'," Number of pixels/line must be a power of two.");
00053         goto the_end;
00054     } else if (!CHECKIMG(filter)) {
00055         MESSAGE('E'," Can't identify filter image.");
00056         goto the_end;
00057     } else if (in->nbnd != filter->nbnd) {
00058         MESSAGE('E'," Number of bands must be identical in both images.");
00059         goto the_end;
00060     }
00061     if (option == PSF) {
00062         if (in->nlin < filter->nlin) {
00063             MESSAGE('E'," Image size in lines must be equal to or greater than that of filter image.");
00064             goto the_end;
00065         } else if (in->npix < filter->npix) {
00066             MESSAGE('E'," Image size in pixels/line must be equal to or greater than that of filter image.");
00067             goto the_end;
00068         }
00069     } else /* (option == OTF) */ {
00070         if (in->nlin != filter->nlin) {
00071             MESSAGE('E'," Image size in lines in the frequency domain must be equal to that of filter image.");
00072             goto the_end;
00073         } else if (in->npix != filter->npix/2) {
00074             MESSAGE('E'," Image size in pixels/line in the frequency domain must be equal to that of filter image.");
00075             goto the_end;
00076         }
00077     }
00078     
00079     /* Fourier transform input image */
00080     FFT2D(in,FORWARD,&scratch1);
00081     if (ABORT  ||  !scratch1) goto the_end;
00082     sprintf(scratch1->text,"Scratch");
00083 
00084     if (option == PSF) {
00085         /* Zero-pad (if necessary) and Fourier transform point-spread function */
00086         if (in->nlin > filter->nlin  ||  in->npix > filter->npix) {
00087             jbgn = (in->nlin-filter->nlin)/2;
00088             kbgn = (in->npix-filter->npix)/2;
00089             MOSAIC(&filter,1,in->nlin,in->npix,&jbgn,&kbgn,(PIXEL)0,&scratch2);
00090             if (ABORT  ||  !scratch2) goto the_end;
00091             sprintf(scratch2->text,"Scratch");
00092             FFT2D(scratch2,FORWARD,&scratch3);
00093             if (ABORT  ||  !scratch3) goto the_end;
00094             sprintf(scratch3->text,"Scratch");
00095             flt = scratch3;
00096         } else {
00097             FFT2D(filter,FORWARD,&scratch2);
00098             if (ABORT  ||  !scratch2) goto the_end;
00099             sprintf(scratch2->text,"Scratch");
00100             flt = scratch2;
00101         }
00102     } else /* (option == OTF) */ {
00103         flt = filter;
00104     }  
00105 
00106     /* create image of appropriate size */
00107     GETMEM(scratch1->nbnd,scratch1->nlin,scratch1->npix,&scratch4);
00108     if (!scratch4) goto the_end;
00109     sprintf(scratch4->text,"Scratch");
00110 
00111     /* initialize progress indicator */
00112     if (LINES  &&  !PROGRESS(psum=0.0)) goto the_end;
00113     pinc = 1.0/(double)scratch1->nbnd/(double)scratch1->nlin;
00114 
00115     /* multiply two complex images */
00116     for (i=0; i<scratch1->nbnd; i+=1) {
00117         for (j=0; j<scratch1->nlin; j+=1) {
00118             for (k=0; k<scratch1->npix; k+=2) {
00119                 scratch4->data[i][j][k  ] = (PIXEL)((double)scratch1->data[i][j][k]*(double)flt->data[i][j][k] - (double)scratch1->data[i][j][k+1]*(double)flt->data[i][j][k+1]);
00120                 scratch4->data[i][j][k+1] = (PIXEL)((double)scratch1->data[i][j][k+1]*(double)flt->data[i][j][k] + (double)scratch1->data[i][j][k]*(double)flt->data[i][j][k+1]);
00121             }
00122             if (LINES  &&  !PROGRESS(psum+=pinc)) goto the_end;
00123         }
00124     }
00125     
00126     /* Fourier transform filtered image */
00127     FFT2D(scratch4,INVERSE,out);
00128 
00129     the_end:
00130     if (scratch1) RELMEM(scratch1);
00131     if (scratch2) RELMEM(scratch2);
00132     if (scratch3) RELMEM(scratch3);
00133     if (scratch4) RELMEM(scratch4);
00134     if (TIMES)    TIMING(T_EXIT);
00135 }

Generated on Wed Apr 9 08:56:05 2003 for TREES by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002