Main Page   Data Structures   File List   Data Fields   Globals  

sconvl.c

Go to the documentation of this file.
00001 #include "trees.h"
00002 
00003 
00004 /*-Copyright Information------------------------------------------------------*/
00005 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00006 /*----------------------------------------------------------------------------*/
00007 /*-General Information--------------------------------------------------------*/
00008 /*                                                                            */
00009 /*   This function computes a two-dimensional spatial convolution between     */
00010 /*   a user-supplied spatial kernel and a single-band image.                  */
00011 /*                                                                            */
00012 /*----------------------------------------------------------------------------*/
00013 /*-Interface Information------------------------------------------------------*/
00014 void TREES_SCONVL (
00015 IMAGE *in,      /*  I   Pointer to the input image.                           */
00016 LOCAL_INDEX *localindex,                 
00017 PIXEL *psf,     /*  I   Pointer to the convolution mask matrix[jsize][ksize]. */
00018 short jsize,    /*  I   Number of lines in the convolution mask.              */
00019 short ksize,    /*  I   Number of pixels/line in the convolution mask.        */
00020 IMAGE **out     /*  O   Address of a pointer to the output image.             */
00021 /*----------------------------------------------------------------------------*/
00022 ) { register int j, k, l, m, n, jmarg=jsize/2, kmarg=ksize/2, box;
00023     char   msg[SLEN];
00024     double sum, r1, rn, pinc, psum;
00025 
00026     int progmeter;
00027     double progress;
00028     int progcount, progtotal, progincr;
00029     int cancel=0;
00030 
00031     progmeter = ProgMeter_Create("Convolution");
00032     progress = 0.0;
00033 
00034 
00035     if (TIMES) TIMING(T_SCONVL);
00036     if (NAMES) {
00037         MESSAGE('I',"");
00038         MESSAGE('I',"SCONVL");
00039         MESSAGE('I',"");
00040         sprintf(msg," Input image:           %s",in->text);
00041         MESSAGE('I',msg);
00042         sprintf(msg," Kernel size: lines:    %d",jsize);
00043         MESSAGE('I',msg);
00044         sprintf(msg,"              pixels:   %d",ksize);
00045         MESSAGE('I',msg);
00046         if (jsize <= SLEN/16  &&  ksize <= SLEN/16) {
00047             MESSAGE('I'," Spatial kernel:");
00048             for (n=j=0; j<jsize; j++) {
00049                 for (m=k=0,msg[m++]=' '; k<ksize; k++,m=strlen(msg)) {
00050                     sprintf(msg+m,"%12.4e",(double)psf[n++]);
00051                 }
00052                 MESSAGE('I',msg);
00053             }
00054         } else {
00055             MESSAGE('I'," Kernel too large to list.");
00056         }
00057         MESSAGE('I'," ...............");
00058     }
00059 
00060     /* check input */
00061     if (!CHECKIMG(in)) {
00062         MESSAGE('E'," Can't identify image.");
00063         goto the_end;
00064     } else if (in->nbnd > 1) {
00065         MESSAGE('E'," Image must be single-band.");
00066         goto the_end;
00067     } else if (jsize < 0  ||  jsize%2 == 0) {
00068         MESSAGE('E'," Number of lines in the convolution mask must be an odd number greater than zero.");
00069         goto the_end;
00070     } else if (jsize > in->nlin) {
00071         MESSAGE('E'," Image size must be equal to or greater than convolution mask size in the line dimension.");
00072         goto the_end;
00073     } else if (ksize < 0  ||  ksize%2 == 0) {
00074         MESSAGE('E'," Number of pixels/line in the convolution mask must be an odd number greater than zero.");
00075         goto the_end;
00076     } else if (ksize > in->npix) {
00077         MESSAGE('E'," Image size must be equal to or greater than convolution mask size in the pixel dimension.");
00078         goto the_end;
00079     }
00080 
00081     /* create image of appropriate size */
00082     if (!CHECKIMG(*out)) GETMEM(1,in->nlin,in->npix,out);
00083     if (!*out) goto the_end;
00084 
00085     /* Initialize output image */
00086     for(j = 0; j < in->nlin; j++) {
00087         for(k = 0; k < in->npix; k++) {
00088             (*out)->data[0][j][k] = (PIXEL)0;
00089         }
00090     }
00091 
00092     /* initialize progress indicator */
00093     if (LINES  &&  !PROGRESS(psum=0.0)) goto the_end;
00094     pinc = 1.0/(double)(in->nlin-2*jmarg);
00095     progtotal = in->nlin-2*jmarg;
00096     progcount = 0;
00097     progincr = rint((double)progtotal/20.0);
00098 
00099     /* see if it's a box-filter PSF */
00100     for (box=TRUE,k=1; box && k<jsize*ksize; k++) {
00101         box = psf[k] == psf[0];
00102     }
00103     
00104     if (box) { /* Box filter implementation is yet to be tested */
00105         for (k = localindex->hstart + kmarg; k <= localindex->hend - kmarg; k++) {
00106 
00107             /* initialize box */
00108             for (r1 = sum  = 0.0, l = k -kmarg; l <= k + kmarg; l++) {
00109                 r1 += (double)in->data[0][localindex->vstart[k] - jmarg][l];
00110                 for (j = localindex->vstart[k] - jmarg + 1; j <= localindex->vstart[k] + jmarg; j++) {
00111                     sum += (double)in->data[0][j][l];
00112                 }
00113             }
00114             (*out)->data[0][localindex->vstart[k]][k] = (PIXEL)((sum += r1)*(double)psf[0]);
00115 
00116             /* box-filter algorithm */
00117             for (j = localindex->vstart[k] + 1; j <= localindex->vend[k]; j++) {
00118                 for (sum -= r1, r1 = rn = 0.0, l = k - kmarg; l <= k + kmarg; l++) {
00119                     r1 += (double)in->data[0][j - jmarg][l];
00120                     rn += (double)in->data[0][j + jmarg][l];
00121                 }
00122                 (*out)->data[0][j][k] = (PIXEL)((sum += rn)*(double)psf[0]);
00123             }
00124             if (LINES  &&  !PROGRESS(psum+=pinc)) goto the_end;
00125             if (progmeter) {
00126                     progcount++;
00127                     if ((progcount%progincr) == 0) {
00128                         progress = ((double)progcount/(double)progtotal)*100.0;
00129                         cancel = ProgMeter_Update(progmeter,progress);
00130                         if (cancel != 0) goto the_end;
00131                     }
00132             }
00133         }
00134 
00135     } else /* compute normal convolution */ {
00136         for (k = localindex->hstart; k <= localindex->hend; k++) {
00137             for (j = localindex->vstart[k]; j <= localindex->vend[k]; j++) {
00138                 for (sum = 0.0,n = jsize*ksize, l = 0; l < jsize; l++) {
00139                     for (m = 0; m < ksize; m++) {
00140                         sum += (double)in->data[0][j-jmarg+l][k-kmarg+m]*(double)psf[--n];
00141                     }
00142                 }
00143                 (*out)->data[0][j][k] = (PIXEL)sum;
00144             }
00145             if (LINES  &&  !PROGRESS(psum+=pinc)) goto the_end;
00146             if (progmeter) {
00147                     progcount++;
00148                     if ((progcount%progincr) == 0) {
00149                         progress = ((double)progcount/(double)progtotal)*100.0;
00150                         cancel = ProgMeter_Update(progmeter,progress);
00151                         if (cancel != 0) goto the_end;
00152                     }
00153             }
00154         }
00155     }
00156 
00157     
00158     the_end:
00159     if (TIMES) TIMING(T_EXIT);
00160 
00161     if (progmeter) {
00162         ProgMeter_Destroy(progmeter);
00163     }
00164 
00165     if (cancel != 0) {
00166         if (*out) RELMEM(*out);
00167         *out = NULL;
00168     }
00169 }

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