00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 void
00028 LABEL (IMAGE * in,
00029 double sigma,
00030 PIXEL thresh,
00031 IMAGE ** out
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
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
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
00120 if (!CHECKIMG (*out))
00121 GETMEM (1, in->nlin, in->npix, out);
00122 if (!*out)
00123 goto the_end;
00124
00125
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
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
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
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
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
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
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 }