00001 #include <tcl.h>
00002 #include <tk.h>
00003 #include "sadie.h"
00004 #include "proto.h"
00005 #include "sadie_byte.h"
00006 #include "sadie_short.h"
00007 #include "trees.h"
00008 #include "mosaic.h"
00009 #include "chain.h"
00010 #include "histogram.h"
00011 #include <sys/time.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 extern short nlev;
00022 extern short csize;
00023 extern double weight;
00024 extern double *count;
00025 extern PIXEL gain;
00026 extern PIXEL bias;
00027 extern PIXEL gmin;
00028 extern PIXEL gmax;
00029 extern PIXEL thresh;
00030 extern PIXEL gbrk[2][4];
00031 extern PIXEL *table;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 int locx;
00042 int locy;
00043 int zoomx;
00044 int zoomy;
00045 int retain;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 extern int **x_array_buffer;
00056 extern int point;
00057 extern int count_point;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int Sadie_TREES_Ext_TrackRingsCmd(ClientData client_data, Tcl_Interp* interp, int argc, char *argv[])
00068 {
00069
00070 int addrstr;
00071 char msg[SLEN];
00072 char *mode = NULL;
00073 struct timeval start, end, t1, t2;
00074 HISTOGRAM globalhist;
00075 HISTOGRAM **localhist;
00076 IMAGE_BYTE *byteimg=NULL;
00077 IMAGE_BYTE *iMag=NULL;
00078 IMAGE_BYTE *iDir=NULL;
00079 MOSAIC_INDEX *index=NULL;
00080
00081
00082 register int i, j, k, l, m, n;
00083 int max, found_max, done, nmax;
00084 int startx, starty;
00085 IMAGE_BYTE *out = NULL;
00086
00087
00088 int discard, x, y, count;
00089 int numlinks, pixcount, maxx, maxy;
00090 int prevx, prevy, currx, curry, reset;
00091 unsigned char code;
00092 CHAIN *chainmap;
00093 LIST_NODE *tempLnode;
00094 LIST_NODE **prevLnode;
00095 LIST_NODE *traverseLnode;
00096 CHAIN_NODE **prevCnode;
00097 CHAIN_NODE *tempCnode;
00098
00099
00100
00101 if( argc <= 3 ) {
00102 sprintf(msg, "Usage: Sadie_TREES_TrackRings byteimg index mode");
00103 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00104 return TCL_ERROR;
00105 }
00106
00107 sscanf(argv[1], "%x", &addrstr);
00108 byteimg = (IMAGE_BYTE *) addrstr;
00109
00110 sscanf(argv[2], "%x", &addrstr);
00111 index = (MOSAIC_INDEX *) addrstr;
00112
00113 mode = argv[3];
00114
00115
00116 gettimeofday(&start, NULL);
00117
00118
00119 gettimeofday(&t1, NULL);
00120 MOSAIC_BYTE_TRACKRINGS(byteimg, index, &iMag, &iDir);
00121 gettimeofday(&t2, NULL);
00122 printf("Total time for gradient = %ld ms.\n\n", delay(t1, t2));
00123
00124
00125 printf("Post-gradient processing\n");
00126 gettimeofday(&t1, NULL);
00127 MOSAIC_BYTE_SUPPRESS(byteimg, index, iMag, iDir, &globalhist, &localhist);
00128 gettimeofday(&t2, NULL);
00129 printf("Total post-gradient time = %ld ms.\n\n", delay(t1, t2));
00130
00131
00132
00133 if (!CHECKIMG_BYTE(byteimg)) {
00134 sprintf(msg," Can't identify mosaic.");
00135 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00136 return TCL_ERROR;
00137 }
00138 if (!CHECKIMG_BYTE(iMag)) {
00139 sprintf(msg," Can't identify magnitude mosaic.");
00140 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00141 return TCL_ERROR;
00142 }
00143 if (!CHECKIMG_BYTE(iDir)) {
00144 sprintf(msg," Can't identify direction mosaic.");
00145 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00146 return TCL_ERROR;
00147 }
00148 if (!CHECKIMG_MOSAIC_INDEX(index)) {
00149 sprintf(msg," Can't identify mosaic index");
00150 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00151 return TCL_ERROR;
00152 }
00153 if ((iMag->nlin != iDir->nlin) || (iMag->npix != iDir->npix)) {
00154 sprintf(msg," Dimensions of Ring Mosaic and Link Mosaic don't match.");
00155 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00156 return TCL_ERROR;
00157 }
00158
00159
00160 gettimeofday(&t1, NULL);
00161
00162
00163 GETMEM_BYTE(iMag->nbnd, iMag->nlin, iMag->npix, &out);
00164
00165
00166 chainmap = (CHAIN *)malloc(sizeof(CHAIN));
00167
00168
00169 for(i = 0; i < out->nbnd; i++)
00170 for(j = 0; j < out->nlin; j++)
00171 for(k = 0; k < out->npix; k++)
00172 out->data[i][j][k] = (BYTE)0;
00173
00174
00175
00176 chainmap->nlin = index->nlin;
00177 chainmap->npix = index->npix;
00178 memcpy((char *)(chainmap->header), (char *)byteimg->text, TLEN - 1);
00179 chainmap->list = NULL;
00180 prevLnode = (LIST_NODE **)&(chainmap->list);
00181
00182
00183
00184 max = 5;
00185 found_max = 0;
00186 count = -1;
00187 for(k = index->hstart + 1; k <= index->hend; k++) {
00188 j = index->vstart[k] - index->voffset[k] + 5;
00189
00190
00191 if (iMag->data[0][j][k] > max) {
00192 max = iMag->data[0][j][k];
00193 startx = index->vstart[k] + 0;
00194 starty = k;
00195 found_max = 1;
00196 }
00197
00198
00199 if (found_max && iMag->data[0][j][k] <= 5) {
00200 found_max = 0;
00201 max = 5;
00202 done = 0;
00203 discard = numlinks = 0;
00204 pixcount = 1;
00205
00206 tempLnode = (LIST_NODE *)malloc(sizeof(LIST_NODE));
00207 tempLnode->startj = startx;
00208 tempLnode->startk = starty;
00209 tempLnode->ring_type = NORMAL;
00210 tempLnode->chain = NULL;
00211 tempLnode->next = NULL;
00212 prevCnode = (CHAIN_NODE **)&(tempLnode->chain);
00213
00214
00215 while (!done && !discard) {
00216
00217
00218 if (startx == index->vend[starty] - 5 ||
00219 starty == index->hstart + 5 || starty == index->hend - 5) {
00220 done = 1;
00221 break;
00222 }
00223
00224
00225 if (HIST_FIND_MAX_NEIGH(iMag, byteimg, index, startx, starty, &x, &y)) {
00226
00227
00228 if (out->data[0][x-index->voffset[y]][y] == 255) {
00229 discard = 1;
00230 break;
00231
00232 } else {
00233
00234 out->data[0][x - index->voffset[y]][y] = 255;
00235 CHAIN_COMPUTE_CODE(startx, starty, x, y, &code);
00236
00237 startx = x;
00238 starty = y;
00239 tempCnode = (CHAIN_NODE *)malloc(sizeof(CHAIN_NODE));
00240 tempCnode->code = code;
00241 tempCnode->valid = 1;
00242 tempCnode->next = NULL;
00243 (*prevCnode) = tempCnode;
00244 prevCnode = (CHAIN_NODE **)&(tempCnode->next);
00245 pixcount++;
00246
00247 }
00248
00249
00250 } else {
00251
00252 if ( (float)numlinks/pixcount > 0.25 && pixcount > 15) {
00253
00254 discard = 1;
00255 break;
00256
00257 } else {
00258
00259 nmax = 0;
00260 for(m = starty - 5; m <= starty + 5; m++) {
00261 if (m < index->hstart || m > index->hend)
00262 continue;
00263 for(n = startx + 1; n <= startx + 10; n++) {
00264 if (n < index->vstart[m] || n > index->vend[m])
00265 continue;
00266 if (iMag->data[0][n - index->voffset[m]][m] > nmax) {
00267 nmax = iMag->data[0][n - index->voffset[m]][m];
00268 maxx = n;
00269 maxy = m;
00270 }
00271 }
00272 }
00273
00274 if (nmax == 0) {
00275
00276
00277 if (startx >= index->vend[starty] - 5 ||
00278 starty == index->hstart + 5 || starty == index->hend - 5) {
00279 done = 1;
00280 break;
00281 } else if (mode[0] == 'I' && pixcount > 50) {
00282
00283
00284 sprintf(msg, "interaction_zoom %d %d", starty, startx);
00285 if (Tcl_Eval(interp, msg) != TCL_OK)
00286 return TCL_ERROR;
00287
00288
00289 traverseLnode = tempLnode;
00290 prevx = traverseLnode->startk;
00291 prevy = traverseLnode->startj;
00292 tempCnode = (CHAIN_NODE *)traverseLnode->chain;
00293 while(tempCnode != NULL) {
00294
00295 CHAIN_COMPUTE_COORDINATES(prevx, prevy, tempCnode->code, &currx, &curry);
00296 sprintf(msg, "%s create line %d %d %d %d -width 1 -fill %s -tag %s", ".trees_main.zoompanel.zoomframe.canvas", prevx-zoomx, prevy-zoomy, currx-zoomx, curry-zoomy, "red", "interact");
00297
00298 if (Tcl_Eval(interp, msg) != TCL_OK)
00299 return TCL_ERROR;
00300
00301 prevx = currx;
00302 prevy = curry;
00303 tempCnode = (CHAIN_NODE *)tempCnode->next;
00304 }
00305
00306
00307 sprintf(msg, "update idletasks");
00308 if (Tcl_Eval(interp, msg) != TCL_OK)
00309 return TCL_ERROR;
00310
00311
00312 sprintf(msg, "trees_interaction_init");
00313 if (Tcl_Eval(interp, msg) != TCL_OK)
00314 return TCL_ERROR;
00315
00316
00317 sprintf(msg, "catch {.trees_main.zoompanel.zoomframe.canvas delete all}");
00318
00319 maxy = locx + zoomx;
00320 maxx = locy + zoomy;
00321
00322
00323 if (!retain) {
00324 discard = 1;
00325 break;
00326 }
00327
00328 } else {
00329 discard = 1;
00330 break;
00331 }
00332 }
00333
00334
00335 count_point = TRUE;
00336 point = 0;
00337 brshnm(starty, startx, maxy, maxx);
00338
00339
00340 x_array_buffer = (int **) malloc((long)point*sizeof(int *));
00341 for (l = 0; l < point; l++)
00342 x_array_buffer[l] = (int *) calloc(2, sizeof(int));
00343
00344
00345 count_point = FALSE;
00346 point = 0;
00347 brshnm(starty, startx, maxy, maxx);
00348
00349
00350 for (l = 0; l < point; l++) {
00351
00352 x = x_array_buffer[l][1];
00353 y = x_array_buffer[l][0];
00354 out->data[0][x - index->voffset[y]][y] = 255;
00355 CHAIN_COMPUTE_CODE(startx, starty, x, y, &code);
00356
00357 startx = x;
00358 starty = y;
00359 tempCnode = (CHAIN_NODE *)malloc(sizeof(CHAIN_NODE));
00360 tempCnode->code = code;
00361 tempCnode->valid = 0;
00362 tempCnode->next = NULL;
00363 (*prevCnode) = tempCnode;
00364 prevCnode = (CHAIN_NODE **)&(tempCnode->next);
00365 pixcount++;
00366 numlinks++;
00367
00368 }
00369
00370 }
00371
00372 }
00373
00374
00375 }
00376
00377 if (!discard && pixcount > 15) {
00378 (*prevLnode) = tempLnode;
00379 prevLnode = (LIST_NODE **)&(tempLnode->next);
00380 tempLnode->ring_id = count++;
00381 } else {
00382
00383 do {
00384 reset = 0;
00385 out->data[0][startx - index->voffset[starty]][starty] = 0;
00386 for(l = starty + 1; l > starty - 2; l--) {
00387 if (l < index->hstart || l > index->hend)
00388 continue;
00389 for(m = startx - 1; m < startx + 1; m++) {
00390 if (m < index->vstart[l] || m > index->vend[l])
00391 continue;
00392 if (out->data[0][m - index->voffset[l]][l] == 255) {
00393 out->data[0][m - index->voffset[l]][l] = 0;
00394 startx = m;
00395 starty = l;
00396 reset = 1;
00397 break;
00398 }
00399 }
00400 if (reset) break;
00401 }
00402 if (!reset) break;
00403 } while (startx != index->vstart[starty] + 1);
00404
00405 }
00406
00407 }
00408
00409 }
00410
00411 gettimeofday(&t2, NULL);
00412 printf("Tracking and coding rings = %ld ms.\n\n", delay(t1, t2));
00413
00414 gettimeofday(&end, NULL);
00415 printf("Total time for finding rings = %ld ms.\n\n", delay(start, end));
00416
00417 printf("Encoded %d rings\n", count+1);
00418
00419
00420 sprintf(msg, "%x", (int)chainmap);
00421 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00422
00423
00424 return TCL_OK;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 int Sadie_TREES_Ext_SetUserInputCmd(ClientData client_data, Tcl_Interp* interp, int argc, char *argv[])
00436 {
00437 double row, col;
00438 char msg[SLEN];
00439
00440 if( argc <= 5 ) {
00441 sprintf(msg, "Usage: Sadie_TREES_SetUserInput retain locx locy zoomx zoomy");
00442 Tcl_SetResult(interp, msg, TCL_VOLATILE);
00443 return TCL_ERROR;
00444 }
00445
00446 if( Tcl_GetInt (interp, argv[1], &retain) != TCL_OK ) {
00447 return TCL_ERROR;
00448 }
00449 if( Tcl_GetDouble (interp, argv[2], &col) != TCL_OK ) {
00450 return TCL_ERROR;
00451 }
00452 if( Tcl_GetDouble (interp, argv[3], &row) != TCL_OK ) {
00453 return TCL_ERROR;
00454 }
00455 if( Tcl_GetInt (interp, argv[4], &zoomx) != TCL_OK ) {
00456 return TCL_ERROR;
00457 }
00458 if( Tcl_GetInt (interp, argv[5], &zoomy) != TCL_OK ) {
00459 return TCL_ERROR;
00460 }
00461
00462
00463
00464 locx = (int)col;
00465 locy = (int)row;
00466
00467 return TCL_OK;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 int Sadie_TREES_Ext_Init(Tcl_Interp *interp) {
00479
00480 Tcl_CreateCommand(interp, "Sadie_TREES_Ext_TrackRings", Sadie_TREES_Ext_TrackRingsCmd,
00481 (ClientData) NULL, NULL);
00482 Tcl_CreateCommand(interp, "Sadie_TREES_Ext_SetUserInput", Sadie_TREES_Ext_SetUserInputCmd,
00483 (ClientData) NULL, NULL);
00484
00485 return TCL_OK;
00486 }
00487