Main Page   Data Structures   File List   Data Fields   Globals  

label.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 segments an image into regions of similar graylevels       */
00009 /*   and creates a label map. Two regions with mean values mean1 and mean2,   */
00010 /*   and a combined standard deviation dev, are merged if                     */
00011 /*                                                                            */
00012 /*           abs(mean1 - mean2)  <=  thresh * (1 - dev/sigma)                 */
00013 /*                                                                            */
00014 /*   where thresh and sigma are input parameters. Assuming the image is       */
00015 /*   segmented into N regions, the resulting label map consists of N          */
00016 /*   segments, numbered consecutively from 0 to N-1.                          */
00017 /*                                                                            */
00018 /*----------------------------------------------------------------------------*/
00019 /*-Background Information-----------------------------------------------------*/
00020 /*                                                                            */
00021 /*   Mehldau, G.:                                                             */
00022 /*   "An Image Segmentation Algorithm."                                       */
00023 /*   University of Arizona, DIAL, Technical Report No. 90-3                   */
00024 /*                                                                            */
00025 /*----------------------------------------------------------------------------*/
00026 /*-Interface Information------------------------------------------------------*/
00027 void
00028 LABEL (IMAGE * in,              /*  I   Pointer to the input image.                           */
00029        double sigma,            /*  I   Greylevel variance threshold.                         */
00030        PIXEL thresh,            /*  I   Graylevel difference threshold.                       */
00031        IMAGE ** out             /*  O   Address of a pointer to the output image.             */
00032 /*----------------------------------------------------------------------------*/
00033   )
00034 {
00035   register short t, l, i, j, k;
00036   register double p, q, r, s, topn, lftn, topsum, lftsum, pinc, psum;
00037   char msg[SLEN];
00038   long total, *cnt = 0, *eqv = 0, top, lft, newLabel, label = 0L;
00039   float *mean = 0, *dev = 0;
00040   double *topmean = 0, *topdev = 0, *lftmean = 0, *lftdev = 0;
00041 
00042   if (TIMES)
00043     TIMING (T_LABEL);
00044   if (NAMES)
00045     {
00046       MESSAGE ('I', "");
00047       MESSAGE ('I', "LABEL");
00048       MESSAGE ('I', "");
00049       sprintf (msg, " Input image:                      %s", in->text);
00050       MESSAGE ('I', msg);
00051       sprintf (msg, " Graylevel difference threshold: %12.4e", thresh);
00052       MESSAGE ('I', msg);
00053       sprintf (msg, " Graylevel variance threshold:   %12.4e", sigma);
00054       MESSAGE ('I', msg);
00055       MESSAGE ('I', " ...............");
00056     }
00057 
00058   /* check input */
00059   if (!CHECKIMG (in))
00060     {
00061       MESSAGE ('E', " Can't identify image.");
00062       goto the_end;
00063     }
00064   else if (sigma < 0.0)
00065     {
00066       MESSAGE ('E', " Threshold  must be greater than or equal to zero.");
00067       goto the_end;
00068     }
00069   else if (thresh < 0.0)
00070     {
00071       MESSAGE ('E', " Threshold  must be greater than or equal to zero.");
00072       goto the_end;
00073     }
00074 
00075   /* allocate space */
00076   total = (long) in->nlin * (long) in->npix;
00077   if (!(cnt = (long *) malloc (total * sizeof (long))))
00078     {
00079       MESSAGE ('E', " Memory request failed.");
00080       goto the_end;
00081     }
00082   if (!(eqv = (long *) malloc (total * sizeof (long))))
00083     {
00084       MESSAGE ('E', " Memory request failed.");
00085       goto the_end;
00086     }
00087   total *= (long) in->nbnd;
00088   if (!(mean = (float *) malloc (total * sizeof (float))))
00089     {
00090       MESSAGE ('E', " Memory request failed.");
00091       goto the_end;
00092     }
00093   if (!(dev = (float *) malloc (total * sizeof (float))))
00094     {
00095       MESSAGE ('E', " Memory request failed.");
00096       goto the_end;
00097     }
00098   if (!(topmean = (double *) malloc (in->nbnd * sizeof (double))))
00099     {
00100       MESSAGE ('E', " Memory request failed.");
00101       goto the_end;
00102     }
00103   if (!(topdev = (double *) malloc (in->nbnd * sizeof (double))))
00104     {
00105       MESSAGE ('E', " Memory request failed.");
00106       goto the_end;
00107     }
00108   if (!(lftmean = (double *) malloc (in->nbnd * sizeof (double))))
00109     {
00110       MESSAGE ('E', " Memory request failed.");
00111       goto the_end;
00112     }
00113   if (!(lftdev = (double *) malloc (in->nbnd * sizeof (double))))
00114     {
00115       MESSAGE ('E', " Memory request failed.");
00116       goto the_end;
00117     }
00118 
00119   /* create image of appropriate size */
00120   if (!CHECKIMG (*out))
00121     GETMEM (1, in->nlin, in->npix, out);
00122   if (!*out)
00123     goto the_end;
00124 
00125   /* initialize progress indicator */
00126   if (LINES && !PROGRESS (psum = 0.0))
00127     goto the_end;
00128   pinc = 1.0 / (double) in->nlin;
00129 
00130   for (j = 0; j < in->nlin; j++)
00131     {
00132       for (k = 0; k < in->npix; k++)
00133         {
00134 
00135           /* look at adjacent segments */
00136           if (t = j)
00137             {
00138               for (top = eqv[(long) (*out)->data[0][j - 1][k]];
00139                    top != eqv[top]; top = eqv[top]);
00140               eqv[(long) (*out)->data[0][j - 1][k]] = top;
00141               topn = (double) cnt[top];
00142               top *= in->nbnd;
00143               topsum = 0.0;
00144             }
00145           if (l = k)
00146             {
00147               for (lft = eqv[(long) (*out)->data[0][j][k - 1]];
00148                    lft != eqv[lft]; lft = eqv[lft]);
00149               eqv[(long) (*out)->data[0][j][k - 1]] = lft;
00150               lftn = (double) cnt[lft];
00151               lft *= in->nbnd;
00152               lftsum = 0.0;
00153             }
00154 
00155           /* merge pixel with adjacent segment? */
00156           for (i = 0; (t || l) && i < in->nbnd; i++)
00157             {
00158               p = in->data[i][j][k];
00159               if (t)
00160                 {
00161                   q = mean[top + i];
00162                   r = dev[top + i];
00163                   topmean[i] = (p + topn * q) / (topn + 1.0);
00164                   topdev[i] =
00165                     sqrt (topn * (r * r + (p - q) * (p - q) / (topn + 1.0)) /
00166                           (topn + 1.0));
00167                   t = fabs (p - q) <= thresh * (1.0 - topdev[i] / sigma);
00168                   topsum += (p - q) * (p - q);
00169                 }
00170               if (l)
00171                 {
00172                   q = mean[lft + i];
00173                   r = dev[lft + i];
00174                   lftmean[i] = (p + lftn * q) / (lftn + 1.0);
00175                   lftdev[i] =
00176                     sqrt (lftn * (r * r + (p - q) * (p - q) / (lftn + 1.0)) /
00177                           (lftn + 1.0));
00178                   l = fabs (p - q) <= thresh * (1.0 - lftdev[i] / sigma);
00179                   lftsum += (p - q) * (p - q);
00180                 }
00181             }
00182 
00183           /* assign pixel label */
00184           if (t && l)
00185             {
00186               l = !(t = topsum < lftsum);
00187             }
00188           if (t)
00189             {
00190               for (i = 0; i < in->nbnd; i++)
00191                 {
00192                   mean[top + i] = topmean[i];
00193                   dev[top + i] = topdev[i];
00194                 }
00195               cnt[top / in->nbnd] += 1L;
00196               (*out)->data[0][j][k] = (*out)->data[0][j - 1][k];
00197             }
00198           else if (l)
00199             {
00200               for (i = 0; i < in->nbnd; i++)
00201                 {
00202                   mean[lft + i] = lftmean[i];
00203                   dev[lft + i] = lftdev[i];
00204                 }
00205               cnt[lft / in->nbnd] += 1L;
00206               (*out)->data[0][j][k] = (*out)->data[0][j][k - 1];
00207             }
00208           else
00209             {
00210               newLabel = label * in->nbnd;
00211               for (i = 0; i < in->nbnd; i++)
00212                 {
00213                   mean[newLabel + i] = in->data[i][j][k];
00214                   dev[newLabel + i] = 0.0;
00215                 }
00216               cnt[label] = 1L;
00217               eqv[label] = label;
00218               (*out)->data[0][j][k] = (PIXEL) label++;
00219             }
00220 
00221           /* merge adjacent segments? */
00222           if ((t || l) && top != lft && j && k)
00223             {
00224               for (t = TRUE, i = 0; t && i < in->nbnd; i++)
00225                 {
00226                   p = mean[top + i];
00227                   q = mean[lft + i];
00228                   r = dev[top + i];
00229                   s = dev[lft + i];
00230                   topmean[i] = (topn * p + lftn * q) / (topn + lftn);
00231                   topdev[i] =
00232                     sqrt ((topn * (r * r + p * p) +
00233                            lftn * (q * q + s * s)) / (topn + lftn) -
00234                           topmean[i] * topmean[i]);
00235                   t = fabs (p - q) <= thresh * (1.0 - topdev[i] / sigma);
00236                 }
00237 
00238               /* merge adjacent segments */
00239               if (t)
00240                 {
00241                   if (top < lft)
00242                     {
00243                       for (i = 0; i < in->nbnd; i++)
00244                         {
00245                           mean[top + i] = topmean[i];
00246                           dev[top + i] = topdev[i];
00247                         }
00248                       top /= in->nbnd;
00249                       lft /= in->nbnd;
00250                       cnt[top] += cnt[lft];
00251                       eqv[lft] = top;
00252                     }
00253                   else
00254                     {
00255                       for (i = 0; i < in->nbnd; i++)
00256                         {
00257                           mean[lft + i] = topmean[i];
00258                           dev[lft + i] = topdev[i];
00259                         }
00260                       top /= in->nbnd;
00261                       lft /= in->nbnd;
00262                       cnt[lft] += cnt[top];
00263                       eqv[top] = lft;
00264                     }
00265                 }
00266             }
00267 
00268         }
00269       if (LINES && !PROGRESS (psum += pinc))
00270         goto the_end;
00271     }
00272 
00273   /* assign consecutive labels */
00274   for (top = 0L; top < label; top++)
00275     {
00276       if (eqv[top] != top)
00277         {
00278           for (newLabel = eqv[top]; newLabel != eqv[newLabel];
00279                newLabel = eqv[newLabel]);
00280           eqv[top] = newLabel;
00281         }
00282     }
00283   for (newLabel = top = 0L; top < label; top++)
00284     {
00285       eqv[top] = (eqv[top] == top ? newLabel++ : eqv[eqv[top]]);
00286     }
00287   for (j = 0; j < in->nlin; j++)
00288     {
00289       for (k = 0; k < in->npix; k++)
00290         {
00291           (*out)->data[0][j][k] = (PIXEL) eqv[(long) (*out)->data[0][j][k]];
00292         }
00293     }
00294   (*out)->gmin = (PIXEL) 0L;
00295   (*out)->gmax = (PIXEL) (newLabel - 1L);
00296   MESSAGE ('I', "");
00297   sprintf (msg, " Number of segments = %ld", newLabel);
00298   MESSAGE ('I', msg);
00299 
00300 the_end:
00301   if (cnt)
00302     free (cnt);
00303   if (eqv)
00304     free (eqv);
00305   if (mean)
00306     free (mean);
00307   if (dev)
00308     free (dev);
00309   if (topmean)
00310     free (topmean);
00311   if (topdev)
00312     free (topdev);
00313   if (lftmean)
00314     free (lftmean);
00315   if (lftdev)
00316     free (lftdev);
00317   if (TIMES)
00318     TIMING (T_EXIT);
00319 }

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