Main Page   Data Structures   File List   Data Fields   Globals  

sconvl.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 #include        "math.h"
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
00015 SCONVL (IMAGE * in,             /*  I   Pointer to the input image.                           */
00016         PIXEL * psf,            /*  I   Pointer to the convolution mask matrix[jsize][ksize]. */
00017         short jsize,            /*  I   Number of lines in the convolution mask.              */
00018         short ksize,            /*  I   Number of pixels/line in the convolution mask.        */
00019         IMAGE ** out            /*  O   Address of a pointer to the output image.             */
00020 /*----------------------------------------------------------------------------*/
00021   )
00022 {
00023   register short j, k, l, m, n, jmarg = jsize / 2, kmarg = ksize / 2, box;
00024   char msg[SLEN];
00025   double sum, c1, cn, pinc, psum;
00026 
00027   int progmeter;
00028   double progress;
00029   int progcount, progtotal, progincr;
00030   int cancel = 0;
00031 
00032   progmeter = ProgMeter_Create ("Convolution");
00033   progress = 0.0;
00034 
00035   if (TIMES)
00036     TIMING (T_SCONVL);
00037   if (NAMES)
00038     {
00039       MESSAGE ('I', "");
00040       MESSAGE ('I', "SCONVL");
00041       MESSAGE ('I', "");
00042       sprintf (msg, " Input image:           %s", in->text);
00043       MESSAGE ('I', msg);
00044       sprintf (msg, " Kernel size: lines:    %d", jsize);
00045       MESSAGE ('I', msg);
00046       sprintf (msg, "              pixels:   %d", ksize);
00047       MESSAGE ('I', msg);
00048       if (jsize <= SLEN / 16 && ksize <= SLEN / 16)
00049         {
00050           MESSAGE ('I', " Spatial kernel:");
00051           for (n = j = 0; j < jsize; j++)
00052             {
00053               for (m = k = 0, msg[m++] = ' '; k < ksize;
00054                    k++, m = strlen (msg))
00055                 {
00056                   sprintf (msg + m, "%12.4e", (double) psf[n++]);
00057                 }
00058               MESSAGE ('I', msg);
00059             }
00060         }
00061       else
00062         {
00063           MESSAGE ('I', " Kernel too large to list.");
00064         }
00065       MESSAGE ('I', " ...............");
00066     }
00067 
00068   /* check input */
00069   if (!CHECKIMG (in))
00070     {
00071       MESSAGE ('E', " Can't identify image.");
00072       goto the_end;
00073     }
00074   else if (in->nbnd > 1)
00075     {
00076       MESSAGE ('E', " Image must be single-band.");
00077       goto the_end;
00078     }
00079   else if (jsize < 0 || jsize % 2 == 0)
00080     {
00081       MESSAGE ('E',
00082                " Number of lines in the convolution mask must be an odd number greater than zero.");
00083       goto the_end;
00084     }
00085   else if (jsize > in->nlin)
00086     {
00087       MESSAGE ('E',
00088                " Image size must be equal to or greater than convolution mask size in the line dimension.");
00089       goto the_end;
00090     }
00091   else if (ksize < 0 || ksize % 2 == 0)
00092     {
00093       MESSAGE ('E',
00094                " Number of pixels/line in the convolution mask must be an odd number greater than zero.");
00095       goto the_end;
00096     }
00097   else if (ksize > in->npix)
00098     {
00099       MESSAGE ('E',
00100                " Image size must be equal to or greater than convolution mask size in the pixel dimension.");
00101       goto the_end;
00102     }
00103 
00104   /* create image of appropriate size */
00105   if (!CHECKIMG (*out))
00106     GETMEM (1, in->nlin, in->npix, out);
00107   if (!*out)
00108     goto the_end;
00109 
00110   /* initialize progress indicator */
00111   if (LINES && !PROGRESS (psum = 0.0))
00112     goto the_end;
00113   pinc = 1.0 / (double) (in->nlin - 2 * jmarg);
00114   progtotal = in->nlin - 2 * jmarg;
00115   progcount = 0;
00116   progincr = rint ((double) progtotal / 20.0);
00117 
00118   /* see if it's a box-filter PSF */
00119   for (box = TRUE, k = 1; box && k < jsize * ksize; k++)
00120     {
00121       box = psf[k] == psf[0];
00122     }
00123 
00124   if (box)
00125     {
00126       for (j = jmarg; j < in->nlin - jmarg; j++)
00127         {
00128 
00129           /* initialize box */
00130           for (c1 = sum = 0.0, l = j - jmarg; l <= j + jmarg; l++)
00131             {
00132               c1 += (double) in->data[0][l][0];
00133               for (k = 1; k < ksize; k++)
00134                 {
00135                   sum += (double) in->data[0][l][k];
00136                 }
00137             }
00138           (*out)->data[0][j][kmarg] = (PIXEL) ((sum += c1) * (double) psf[0]);
00139 
00140           /* box-filter algorithm */
00141           for (k = kmarg + 1; k < in->npix - kmarg; k++)
00142             {
00143               for (sum -= c1, c1 = cn = 0.0, l = j - jmarg; l <= j + jmarg;
00144                    l++)
00145                 {
00146                   c1 += (double) in->data[0][l][k - kmarg];
00147                   cn += (double) in->data[0][l][k + kmarg];
00148                 }
00149               (*out)->data[0][j][k] = (PIXEL) ((sum += cn) * (double) psf[0]);
00150             }
00151           if (LINES && !PROGRESS (psum += pinc))
00152             goto the_end;
00153           if (progmeter)
00154             {
00155               progcount++;
00156               if ((progcount % progincr) == 0)
00157                 {
00158                   progress =
00159                     ((double) progcount / (double) progtotal) * 100.0;
00160                   cancel = ProgMeter_Update (progmeter, progress);
00161                   if (cancel != 0)
00162                     goto the_end;
00163                 }
00164             }
00165         }
00166 
00167     }
00168   else                          /* compute normal convolution */
00169     {
00170       for (j = jmarg; j < in->nlin - jmarg; j++)
00171         {
00172           for (k = kmarg; k < in->npix - kmarg; k++)
00173             {
00174               for (sum = 0.0, n = jsize * ksize, l = 0; l < jsize; l++)
00175                 {
00176                   for (m = 0; m < ksize; m++)
00177                     {
00178                       sum +=
00179                         (double) in->data[0][j - jmarg + l][k - kmarg +
00180                                                             m] *
00181                         (double) psf[--n];
00182                     }
00183                 }
00184               (*out)->data[0][j][k] = (PIXEL) sum;
00185             }
00186           if (LINES && !PROGRESS (psum += pinc))
00187             goto the_end;
00188           if (progmeter)
00189             {
00190               progcount++;
00191               if ((progcount % progincr) == 0)
00192                 {
00193                   progress =
00194                     ((double) progcount / (double) progtotal) * 100.0;
00195                   cancel = ProgMeter_Update (progmeter, progress);
00196                   if (cancel != 0)
00197                     goto the_end;
00198                 }
00199             }
00200         }
00201     }
00202 
00203   /* fill top and bottom margins */
00204   for (j = 0; j < jmarg; j++)
00205     {
00206       for (k = 0; k < in->npix - kmarg; k++)
00207         {
00208           (*out)->data[0][j][k] = (*out)->data[0][jmarg][k];
00209           (*out)->data[0][in->nlin - j - 1][k] =
00210             (*out)->data[0][in->nlin - jmarg - 1][k];
00211         }
00212     }
00213 
00214   /* fill left and right margins */
00215   for (j = 0; j < in->nlin; j++)
00216     {
00217       for (k = 0; k < kmarg; k++)
00218         {
00219           (*out)->data[0][j][k] = (*out)->data[0][j][kmarg];
00220           (*out)->data[0][j][in->npix - k - 1] =
00221             (*out)->data[0][j][in->npix - kmarg - 1];
00222         }
00223     }
00224 
00225 the_end:
00226   if (TIMES)
00227     TIMING (T_EXIT);
00228 
00229   if (progmeter)
00230     {
00231       ProgMeter_Destroy (progmeter);
00232     }
00233 
00234   if (cancel != 0)
00235     {
00236       if (*out)
00237         RELMEM (*out);
00238       *out = NULL;
00239     }
00240 }

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