Main Page   Data Structures   File List   Data Fields   Globals  

median.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 median filtering of an image.                     */
00009 /*                                                                            */
00010 /*----------------------------------------------------------------------------*/
00011 /*-Interface Information------------------------------------------------------*/
00012 void
00013 MEDIAN (IMAGE * in,             /*  I   Pointer to the input image.                           */
00014         short jsize,            /*  I   Number of lines in the median window.                 */
00015         short ksize,            /*  I   Number of pixels/line in the median window.           */
00016         IMAGE ** out            /*  O   Address of a pointer to the output image.             */
00017 /*----------------------------------------------------------------------------*/
00018   )
00019 {
00020   register short i, j, k, l, m, count, index, jstart, jend, kstart, kend,
00021     jover = (jsize - 1) / 2, kover = (ksize - 1) / 2;
00022   char msg[SLEN];
00023   double pinc, psum;
00024   PIXEL med, *list = 0;
00025 
00026   if (TIMES)
00027     TIMING (T_MEDIAN);
00028   if (NAMES)
00029     {
00030       MESSAGE ('I', "");
00031       MESSAGE ('I', "MEDIAN");
00032       MESSAGE ('I', "");
00033       sprintf (msg, " Input image:           %s", in->text);
00034       MESSAGE ('I', msg);
00035       sprintf (msg, " Window size: lines:    %d", jsize);
00036       MESSAGE ('I', msg);
00037       sprintf (msg, "              pixels:   %d", ksize);
00038       MESSAGE ('I', msg);
00039       MESSAGE ('I', " ...............");
00040     }
00041 
00042   /* check input */
00043   if (!CHECKIMG (in))
00044     {
00045       MESSAGE ('E', " Can't identify image.");
00046       goto the_end;
00047     }
00048   else if (jsize <= 0 || jsize % 2 == 0)
00049     {
00050       MESSAGE ('E',
00051                " Number of lines in the median window must be an odd number greater than zero.");
00052       goto the_end;
00053     }
00054   else if (jsize > in->nlin)
00055     {
00056       MESSAGE ('E',
00057                " Image line size must be equal to or greater than window size.");
00058       goto the_end;
00059     }
00060   else if (ksize <= 0 || ksize % 2 == 0)
00061     {
00062       MESSAGE ('E',
00063                " Number of pixels/line in the median window must be an odd number greater than zero.");
00064       goto the_end;
00065     }
00066   else if (ksize > in->npix)
00067     {
00068       MESSAGE ('E',
00069                " Image pixel size must be equal to or greater than window size.");
00070       goto the_end;
00071     }
00072 
00073   /* create image of appropriate size */
00074   if (!CHECKIMG (*out))
00075     GETMEM (in->nbnd, in->nlin, in->npix, out);
00076   if (!*out)
00077     goto the_end;
00078 
00079   /* allocate space for 1-D array */
00080   if (!(list = (PIXEL *) malloc (jsize * ksize * sizeof (PIXEL))))
00081     {
00082       MESSAGE ('E', " Memory request failed.");
00083       goto the_end;
00084     }
00085 
00086   /* initialize progress indicator */
00087   if (LINES && !PROGRESS (psum = 0.0))
00088     goto the_end;
00089   pinc = 1.0 / (double) in->nbnd / (double) in->nlin;
00090 
00091   /* put pixels inside window into array */
00092   for (i = 0; i < in->nbnd; i++)
00093     {
00094       for (j = 0; j < in->nlin; j++)
00095         {
00096           jstart = max (0, j - jover);
00097           jend = min (j + jover, in->nlin - 1);
00098           for (k = 0; k < in->npix; k++)
00099             {
00100               kstart = max (0, k - kover);
00101               kend = min (k + kover, in->npix - 1);
00102               for (count = 0, l = jstart; l <= jend; l++)
00103                 {
00104                   for (m = kstart; m <= kend; m++)
00105                     {
00106                       list[count++] = in->data[i][l][m];
00107                     }
00108                 }
00109 
00110               /* compute median */
00111               for (l = 0; l < (count + 1) / 2; l++)
00112                 {
00113                   med = list[index = l];
00114                   for (m = l + 1; m < count; m++)
00115                     {
00116                       if (med > list[m])
00117                         med = list[index = m];
00118                     }
00119                   list[index] = list[l];
00120                 }
00121               (*out)->data[i][j][k] = med;
00122             }
00123           if (LINES && !PROGRESS (psum += pinc))
00124             goto the_end;
00125         }
00126     }
00127 
00128 the_end:
00129   if (list)
00130     free (list);
00131   if (TIMES)
00132     TIMING (T_EXIT);
00133 }

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