00001 #include "sadie.h"
00002
00003 extern short csize;
00004 extern PIXEL thresh;
00005 extern double weight;
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 void
00018 WINDOW (IMAGE * in,
00019 PIXEL (*wtf) (PIXEL *, short, short),
00020
00021 short jsize,
00022 short ksize,
00023 IMAGE ** out
00024
00025 )
00026 {
00027 register short i, j, k, l, m, n, jmarg = (jsize - 1) / 2, kmarg =
00028 (ksize - 1) / 2;
00029 char msg[SLEN];
00030 PIXEL *wnd = 0;
00031 double pinc, psum;
00032
00033 if (TIMES)
00034 TIMING (T_WINDOW);
00035 if (NAMES)
00036 {
00037 MESSAGE ('I', "");
00038 MESSAGE ('I', "WINDOW");
00039 MESSAGE ('I', "");
00040 sprintf (msg, " Input image: %s", in->text);
00041 MESSAGE ('I', msg);
00042 sprintf (msg, " Window size: lines: %d", jsize);
00043 MESSAGE ('I', msg);
00044 sprintf (msg, " pixels: %d", ksize);
00045 MESSAGE ('I', msg);
00046 if (wtf == WTFCAVG)
00047 {
00048 MESSAGE ('I', " Conditional average filter");
00049 sprintf (msg, " Set size threshold: %d", csize);
00050 MESSAGE ('I', msg);
00051 sprintf (msg, " Graylevel difference threshold: %12.4e", thresh);
00052 MESSAGE ('I', msg);
00053 }
00054 else if (wtf == WTFDIVER)
00055 {
00056 MESSAGE ('I', " Diversity map");
00057 }
00058 else if (wtf == WTFMAJ)
00059 {
00060 MESSAGE ('I', " Majority filter");
00061 sprintf (msg, " Center pixel weight: %12.4e", weight);
00062 MESSAGE ('I', msg);
00063 }
00064 else if (wtf == WTFMAX)
00065 {
00066 MESSAGE ('I', " Maximum filter");
00067 }
00068 else if (wtf == WTFMIN)
00069 {
00070 MESSAGE ('I', " Minimum filter");
00071 }
00072 else if (wtf == WTFVAR)
00073 {
00074 MESSAGE ('I', " Variance map");
00075 }
00076 MESSAGE ('I', " ...............");
00077 }
00078
00079
00080 if (!CHECKIMG (in))
00081 {
00082 MESSAGE ('E', " Can't identify image.");
00083 goto the_end;
00084 }
00085 else if (!wtf)
00086 {
00087 MESSAGE ('E', " Can't identify window function.");
00088 goto the_end;
00089 }
00090 else if (jsize <= 0 || jsize % 2 == 0)
00091 {
00092 MESSAGE ('E',
00093 " Window line size must be an odd number greater than zero.");
00094 goto the_end;
00095 }
00096 else if (jsize > in->nlin)
00097 {
00098 MESSAGE ('E',
00099 " Image line size must be equal to or greater than window line size.");
00100 goto the_end;
00101 }
00102 else if (ksize <= 0 || ksize % 2 == 0)
00103 {
00104 MESSAGE ('E',
00105 " Window pixel size must be an odd number greater than zero.");
00106 goto the_end;
00107 }
00108 else if (ksize > in->npix)
00109 {
00110 MESSAGE ('E',
00111 " Image pixel size must be equal to or greater than window pixel size.");
00112 goto the_end;
00113 }
00114
00115
00116 if (!CHECKIMG (*out))
00117 GETMEM (in->nbnd, in->nlin, in->npix, out);
00118 if (!*out)
00119 goto the_end;
00120
00121
00122 if (!(wnd = (PIXEL *) malloc (jsize * ksize * sizeof (PIXEL))))
00123 {
00124 MESSAGE ('E', " Memory request failed.");
00125 goto the_end;
00126 }
00127
00128
00129 if (LINES && !PROGRESS (psum = 0.0))
00130 goto the_end;
00131 pinc = 1.0 / (double) in->nbnd / (double) (in->nlin - 2 * jmarg);
00132
00133
00134 for (i = 0; i < in->nbnd; i++)
00135 {
00136 for (j = jmarg; j < in->nlin - jmarg; j++)
00137 {
00138 for (k = kmarg; k < in->npix - kmarg; k++)
00139 {
00140 for (n = 0, l = j - jmarg; l <= j + jmarg; l++)
00141 {
00142 for (m = k - kmarg; m <= k + kmarg; m++)
00143 {
00144 wnd[n++] = in->data[i][l][m];
00145 }
00146 }
00147 (*out)->data[i][j][k] = (*wtf) (wnd, jsize, ksize);
00148 }
00149 if (LINES && !PROGRESS (psum += pinc))
00150 goto the_end;
00151 }
00152
00153
00154 for (j = 0; j < jmarg; j++)
00155 {
00156 for (k = kmarg; k < in->npix - kmarg; k++)
00157 {
00158 (*out)->data[i][j][k] = (*out)->data[i][jmarg][k];
00159 (*out)->data[i][in->nlin - j - 1][k] =
00160 (*out)->data[i][in->nlin - jmarg - 1][k];
00161 }
00162 }
00163
00164
00165 for (j = 0; j < in->nlin; j++)
00166 {
00167 for (k = 0; k < kmarg; k++)
00168 {
00169 (*out)->data[i][j][k] = (*out)->data[i][j][kmarg];
00170 (*out)->data[i][j][in->npix - k - 1] =
00171 (*out)->data[i][j][in->npix - kmarg - 1];
00172 }
00173 }
00174 }
00175
00176 the_end:
00177 if (wnd)
00178 free (wnd);
00179 if (TIMES)
00180 TIMING (T_EXIT);
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 extern short csize;
00200 extern PIXEL thresh;
00201 PIXEL
00202 WTFCAVG (PIXEL * wnd,
00203 short jsize,
00204 short ksize
00205
00206 )
00207 {
00208 register short i, count = 0;
00209 PIXEL center = wnd[jsize / 2 * ksize + ksize / 2], sum1 = (PIXEL) 0, sum2 =
00210 (PIXEL) 0, minval = wnd[0], maxval = wnd[0];
00211
00212 if (TIMES)
00213 TIMING (T_WTFCAVG);
00214
00215
00216 for (i = 0; i < jsize * ksize; i++)
00217 {
00218 if ((PIXEL) fabs ((double) (wnd[i] - center)) <= thresh)
00219 {
00220 sum1 += wnd[i];
00221 count += 1;
00222 }
00223 else if (csize != 0)
00224 {
00225 sum2 += wnd[i];
00226 minval = min (minval, wnd[i]);
00227 maxval = max (maxval, wnd[i]);
00228 }
00229 }
00230 if (csize == 0 || count > csize)
00231 {
00232 center = (PIXEL) ((double) sum1 / (double) count);
00233 }
00234 else if (csize != 0 && (PIXEL) fabs ((double) (maxval - minval)) <= thresh)
00235 {
00236 center = (PIXEL) ((double) sum2 / (double) (jsize * ksize - count));
00237 }
00238
00239 the_end:
00240 if (TIMES)
00241 TIMING (T_EXIT);
00242 return (center);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 PIXEL
00255 WTFDIVER (PIXEL * wnd,
00256 short jsize,
00257 short ksize
00258
00259 )
00260 {
00261 register short i, j, diversity = 0;
00262
00263 if (TIMES)
00264 TIMING (T_WTFDIVER);
00265
00266 for (i = 0; i < jsize * ksize; i++)
00267 {
00268 for (++diversity, j = 0; j < i; j++)
00269 {
00270 if (wnd[i] == wnd[j])
00271 {
00272 diversity -= 1;
00273 break;
00274 }
00275 }
00276 }
00277
00278 the_end:
00279 if (TIMES)
00280 TIMING (T_EXIT);
00281 return ((PIXEL) diversity);
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 extern short nlev;
00301 extern PIXEL gmin;
00302 extern double weight;
00303 extern double *count;
00304
00305 PIXEL
00306 WTFMAJ (PIXEL * wnd,
00307 short jsize,
00308 short ksize
00309
00310 )
00311 {
00312 register short i, pclass, center =
00313 (short) (wnd[jsize / 2 * ksize + ksize / 2] - gmin);
00314 double plurality;
00315
00316 if (TIMES)
00317 TIMING (T_WTFMAJ);
00318
00319
00320 for (i = 0; i < nlev; count[i++] = 0.0);
00321
00322
00323 for (i = 0; i < jsize * ksize; i++)
00324 {
00325 count[(short) (wnd[i] - gmin)] += 1.0;
00326 }
00327
00328
00329 count[center] *= weight;
00330
00331
00332 for (plurality = count[pclass = 0], i = 1; i < nlev; i++)
00333 {
00334 if (count[i] > plurality && i != center)
00335 plurality = count[pclass = i];
00336 }
00337 if (plurality <= (double) (jsize * ksize) / 2.0
00338 || plurality <= count[center])
00339 pclass = center;
00340
00341 the_end:
00342 if (TIMES)
00343 TIMING (T_EXIT);
00344 return ((PIXEL) pclass + gmin);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 PIXEL
00357 WTFMAX (PIXEL * wnd,
00358 short jsize,
00359 short ksize
00360
00361 )
00362 {
00363 register short i;
00364 PIXEL maxval = wnd[0];
00365
00366 if (TIMES)
00367 TIMING (T_WTFMAX);
00368
00369
00370 for (i = 1; i < jsize * ksize; i++)
00371 {
00372 maxval = max (maxval, wnd[i]);
00373 }
00374
00375 the_end:
00376 if (TIMES)
00377 TIMING (T_EXIT);
00378 return (maxval);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 PIXEL
00391 WTFMIN (PIXEL * wnd,
00392 short jsize,
00393 short ksize
00394
00395 )
00396 {
00397 register short i;
00398 PIXEL minval = wnd[0];
00399
00400 if (TIMES)
00401 TIMING (T_WTFMIN);
00402
00403
00404 for (i = 1; i < jsize * ksize; i++)
00405 {
00406 minval = min (minval, wnd[i]);
00407 }
00408
00409 the_end:
00410 if (TIMES)
00411 TIMING (T_EXIT);
00412 return (minval);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 PIXEL
00425 WTFVAR (PIXEL * wnd,
00426 short jsize,
00427 short ksize
00428
00429 )
00430 {
00431 register short i;
00432 double area = jsize * ksize;
00433 PIXEL sum = (PIXEL) 0, sumsq = (PIXEL) 0;
00434
00435 if (TIMES)
00436 TIMING (T_WTFVAR);
00437
00438 for (i = 0; i < jsize * ksize; i++)
00439 {
00440 sum += wnd[i];
00441 sumsq += wnd[i] * wnd[i];
00442 }
00443
00444 the_end:
00445 if (TIMES)
00446 TIMING (T_EXIT);
00447 return ((PIXEL)
00448 ((double) sumsq / area -
00449 ((double) sum / area) * ((double) sum / area)));
00450 }