Main Page   Data Structures   File List   Data Fields   Globals  

vstretch.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   This function performs a spatially-variable graylevel transformation     */
00009 /*   on a single-band image.                                                  */
00010 /*                                                                            */
00011 /*----------------------------------------------------------------------------*/
00012 /*-Background Information-----------------------------------------------------*/
00013 /*                                                                            */
00014 /*   Fahnestock, J.D. and Schowengerdt, R.A.:                                 */
00015 /*   "Spatially variant contrast enhancement using local range modification." */
00016 /*   Optical Engineering, Vol. 22, No. 3, May/June 1983                       */
00017 /*                                                                            */
00018 /*----------------------------------------------------------------------------*/
00019 /*-Interface Information------------------------------------------------------*/
00020 void
00021 VSTRETCH (IMAGE * in,           /*  I   Pointer to the input image.                           */
00022           short size,           /*  I   Number of lines and pixels in image blocks.           */
00023           IMAGE ** out          /*  O   Address of a pointer to the output image.             */
00024 /*----------------------------------------------------------------------------*/
00025   )
00026 {
00027   register short j, k, u, v;
00028   char msg[SLEN];
00029   long total, x, y, idx1, idx2, blkx, blky;
00030   double rat1, rat2, rat3, rat4, pinc, psum;
00031   PIXEL *hi = 0, *lo = 0, *mp = 0, *np = 0, m, n;
00032 
00033   if (TIMES)
00034     TIMING (T_VSTRETCH);
00035   if (NAMES)
00036     {
00037       MESSAGE ('I', "");
00038       MESSAGE ('I', "VSTRETCH");
00039       MESSAGE ('I', "");
00040       sprintf (msg, " Input image:                    %s", in->text);
00041       MESSAGE ('I', msg);
00042       sprintf (msg, " Block size: lines and pixels:   %d", size);
00043       MESSAGE ('I', msg);
00044       MESSAGE ('I', " ...............");
00045     }
00046 
00047   /* check input */
00048   if (!CHECKIMG (in))
00049     {
00050       MESSAGE ('E', " Can't identify image.");
00051       goto the_end;
00052     }
00053   else if (in->nbnd > 1)
00054     {
00055       MESSAGE ('E', " Image must be single-band.");
00056       goto the_end;
00057     }
00058   else if (size < 1)
00059     {
00060       MESSAGE ('E',
00061                " Size of subblock must be equal to or greater than one.");
00062       goto the_end;
00063     }
00064   else if (size > in->nlin || size > in->npix)
00065     {
00066       MESSAGE ('E',
00067                " Image size must be equal to or greater than subblock size.");
00068       goto the_end;
00069     }
00070 
00071   /* create image of appropriate size */
00072   if (!CHECKIMG (*out))
00073     GETMEM (1, in->nlin, in->npix, out);
00074   if (!*out)
00075     goto the_end;
00076   blkx = (in->npix - 1) / size + 1L;
00077   blky = (in->nlin - 1) / size + 1L;
00078 
00079   /* allocate space for arrays */
00080   total = blkx * blky;
00081   if (!(hi = (PIXEL *) malloc (total * sizeof (PIXEL))))
00082     {
00083       MESSAGE ('E', " Memory request failed.");
00084       goto the_end;
00085     }
00086   if (!(lo = (PIXEL *) malloc (total * sizeof (PIXEL))))
00087     {
00088       MESSAGE ('E', " Memory request failed.");
00089       goto the_end;
00090     }
00091   total = (blkx + 1L) * (blky + 1L);
00092   if (!(mp = (PIXEL *) malloc (total * sizeof (PIXEL))))
00093     {
00094       MESSAGE ('E', " Memory request failed.");
00095       goto the_end;
00096     }
00097   if (!(np = (PIXEL *) malloc (total * sizeof (PIXEL))))
00098     {
00099       MESSAGE ('E', " Memory request failed.");
00100       goto the_end;
00101     }
00102 
00103   /* initialize progress indicator */
00104   if (LINES && !PROGRESS (psum = 0.0))
00105     goto the_end;
00106   pinc = 0.5 / (double) blkx / (double) blky;
00107 
00108   /* first pass: obtain transformation parameters from subblocks */
00109   /* search for maximum and minimum */
00110   for (y = 0L; y < blky; y++)
00111     {
00112       for (x = 0L; x < blkx; x++)
00113         {
00114           for (m = n = in->data[0][y * size][x * size], j = y * size;
00115                j < (y + 1L) * size && j < in->nlin; j++)
00116             {
00117               for (k = x * size; k < (x + 1L) * size && k < in->npix; k++)
00118                 {
00119                   if (in->data[0][j][k] > m)
00120                     m = in->data[0][j][k];
00121                   if (in->data[0][j][k] < n)
00122                     n = in->data[0][j][k];
00123                 }
00124             }
00125           hi[y * blkx + x] = m;
00126           lo[y * blkx + x] = n;
00127           if (LINES && !PROGRESS (psum += pinc))
00128             goto the_end;
00129         }
00130     }
00131 
00132   /* obtain values for parameter arrays */
00133   /* four corners */
00134   mp[0] = hi[0];
00135   np[0] = lo[0];
00136   mp[blkx] = hi[blkx - 1L];
00137   np[blkx] = lo[blkx - 1L];
00138   mp[blky * (blkx + 1L)] = hi[(blky - 1L) * blkx];
00139   np[blky * (blkx + 1L)] = lo[(blky - 1L) * blkx];
00140   mp[(blkx + 1L) * (blky + 1L) - 1L] = hi[blkx * blky - 1L];
00141   np[(blkx + 1L) * (blky + 1L) - 1L] = lo[blkx * blky - 1L];
00142 
00143   /* four sides */
00144   for (y = 1L; y < blky; y++)
00145     {
00146       idx1 = (y - 1L) * blkx;
00147       idx2 = y * blkx;
00148       mp[y * (blkx + 1L)] = max (hi[idx1], hi[idx2]);
00149       np[y * (blkx + 1L)] = min (lo[idx1], lo[idx2]);
00150       idx1 = (y + 1L) * blkx - 1L;
00151       mp[(y + 1L) * (blkx + 1L) - 1L] = max (hi[idx2 - 1L], hi[idx1]);
00152       np[(y + 1L) * (blkx + 1L) - 1L] = min (lo[idx2 - 1L], lo[idx1]);
00153     }
00154   for (x = 1L; x < blkx; x++)
00155     {
00156       mp[x] = max (hi[x - 1L], hi[x]);
00157       np[x] = min (lo[x - 1L], lo[x]);
00158       idx1 = blky * (blkx + 1L) + x;
00159       idx2 = (blky - 1L) * blkx + x;
00160       mp[idx1] = max (hi[idx2 - 1L], hi[idx2]);
00161       np[idx1] = min (lo[idx2 - 1L], lo[idx2]);
00162     }
00163 
00164   /* inside */
00165   for (y = 1L; y < blky; y++)
00166     {
00167       for (x = 1L; x < blkx; x++)
00168         {
00169           idx1 = (y - 1L) * blkx + x;
00170           idx2 = y * blkx + x;
00171           mp[y * (blkx + 1L) + x] =
00172             max (max (hi[idx1], hi[idx1 - 1L]),
00173                  max (hi[idx2], hi[idx2 - 1L]));
00174           np[y * (blkx + 1L) + x] =
00175             min (min (lo[idx1], lo[idx1 - 1L]),
00176                  min (lo[idx2], lo[idx2 - 1L]));
00177         }
00178     }
00179 
00180   /* second pass: perform transformation */
00181   for (x = 0L; x < blkx; x++)
00182     {
00183       for (y = 0L; y < blky; y++)
00184         {
00185           for (u = 0, j = y * size; j < (y + 1L) * size && j < in->nlin;
00186                u++, j++)
00187             {
00188               for (v = 0, k = x * size; k < (x + 1L) * size && k < in->npix;
00189                    v++, k++)
00190                 {
00191                   idx1 = (y + 1L) * (blkx + 1L) + x;
00192                   idx2 = y * (blkx + 1L) + x;
00193                   rat1 = (double) u / (double) size;
00194                   rat2 = (double) (size - u) / (double) size;
00195                   rat3 = (double) (size - v) / (double) size;
00196                   rat4 = (double) v / (double) size;
00197                   m =
00198                     (rat1 * (double) mp[idx1] +
00199                      rat2 * (double) mp[idx2]) * rat3 +
00200                     (rat1 * (double) mp[idx1 + 1L] +
00201                      rat2 * (double) mp[idx2 + 1L]) * rat4;
00202                   n =
00203                     (rat1 * (double) np[idx1] +
00204                      rat2 * (double) np[idx2]) * rat3 +
00205                     (rat1 * (double) np[idx1 + 1L] +
00206                      rat2 * (double) np[idx2 + 1L]) * rat4;
00207                   (*out)->data[0][j][k] =
00208                     m ==
00209                     n ? in->
00210                     data[0][j][k] : (PIXEL) ((double) (in->gmax - in->gmin) /
00211                                              (double) (m -
00212                                                        n) *
00213                                              ((double) in->data[0][j][k] -
00214                                               n)) + in->gmin;
00215                 }
00216             }
00217           if (LINES && !PROGRESS (psum += pinc))
00218             goto the_end;
00219         }
00220     }
00221 
00222 the_end:
00223   if (hi)
00224     free (hi);
00225   if (lo)
00226     free (lo);
00227   if (mp)
00228     free (mp);
00229   if (np)
00230     free (np);
00231   if (TIMES)
00232     TIMING (T_EXIT);
00233 }

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