Changeset 29543 for trunk/psModules/src/imcombine/pmStack.c
- Timestamp:
- Oct 25, 2010, 2:45:41 PM (16 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/imcombine/pmStack.c (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmStack.c
r27427 r29543 19 19 20 20 #include <stdio.h> 21 #include <string.h> // for memset 21 22 #include <pslib.h> 22 23 … … 34 35 35 36 36 //#define TESTING // Enable test output 37 //#define TEST_X 843-1 // x coordinate to examine 38 //#define TEST_Y 813-1 // y coordinate to examine 39 //#define TEST_RADIUS 0 // Radius to examine 40 37 # if (0) 38 #define TESTING // Enable test output 39 #define TEST_X 4963 // x coordinate to examine 40 #define TEST_Y 5353 // y coordinate to examine 41 #define TEST_X 40 // x coordinate to examine 42 #define TEST_Y 40 // y coordinate to examine 43 #define TEST_RADIUS 0.5 // Radius to examine 44 # endif 45 46 # ifdef TESTING 47 # define CHECKPIX(XPIX,YPIX,MSG,...) { if (PS_SQR(XPIX - TEST_X) + PS_SQR(YPIX - TEST_Y) <= PS_SQR(TEST_RADIUS)) { fprintf(stderr,MSG,__VA_ARGS__); } } 48 # else 49 # define CHECKPIX(XPIX,YPIX,MSG,...) { } 50 # endif 41 51 42 52 // Data structure for use as a buffer when combining pixels … … 250 260 ) 251 261 { 252 #ifdef TESTING 253 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 254 fprintf(stderr, "Marking image %d, pixel %d,%d for inspection\n", source, x, y); 255 } 256 #endif 262 CHECKPIX(x, y, "Marking image %d, pixel %d,%d for inspection\n", source, x, y); 257 263 pmStackData *data = inputs->data[source]; // Stack data of interest 258 264 if (!data) { … … 272 278 ) 273 279 { 274 #ifdef TESTING 275 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 276 fprintf(stderr, "Marking pixel image %d, pixel %d,%d for rejection\n", source, x, y); 277 } 278 #endif 280 CHECKPIX(x, y, "Marking pixel image %d, pixel %d,%d for rejection\n", source, x, y); 279 281 pmStackData *data = inputs->data[source]; // Stack data of interest 280 282 if (!data) { … … 290 292 static void combineExtract(int *num, // Number of good pixels 291 293 bool *suspect, // Any suspect pixels? 294 psImageMaskType *badMask, // OR of all bad (masked) pixels 295 psImageMaskType *goodMask, // OR of all good (unmasked) pixels 292 296 combineBuffer *buffer, // Buffer with vectors 293 297 psImage *image, // Combined image, for output … … 300 304 const psVector *reject, // Indices of pixels to reject, or NULL 301 305 int x, int y, // Coordinates of interest; frame of output image 302 psImageMaskType maskVal, // Value to mask303 psImageMaskType maskSuspect // Value to suspect306 psImageMaskType badMaskBits, // Value to mask as 'bad' 307 psImageMaskType suspectMaskBits // Value to mask as 'suspect' 304 308 ) 305 309 { … … 322 326 } 323 327 328 // mask values to store possible mask combinations 329 *badMask = 0; 330 *goodMask = 0xffff; 331 332 int nGoodBits[16]; // accumulate the good pixel bits here for fuzzy logic 333 psAssert (sizeof(psImageMaskType) == 2, "psImageMaskType is not the expected size"); 334 memset (nGoodBits, 0, 16*sizeof(int)); 335 324 336 // Extract the pixel and mask data 325 337 int numGood = 0; // Number of good pixels … … 328 340 // should be because of how pixelMapGenerate works 329 341 if (reject && reject->data.U16[j] == i) { 342 // pixels can be rejected because: 343 // 1) only 1 input pixel (and 'safe' is true) 344 // 2) only 2 input pixels were available and they were mutually inconsistent (or variance info was missing) 345 // 3) NOTE : ifdef'ed out code for 3 inputs case 346 // 4) outlier from sample of N pixels 347 // 5) some of these may have been suspect. 348 // XXX raise a specific mask bit for these (currently results in BLANK) 330 349 j++; 350 351 pmStackData *data = inputs->data[i]; // Stack data of interest 352 if (data) { 353 int xIn = x - data->readout->col0, yIn = y - data->readout->row0; // Coordinates on input readout 354 psImage *mask = data->readout->mask; // Mask of interest 355 *badMask |= mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn]; // save the bad bits used 356 CHECKPIX(x, y, "reject: adding bit to mask: %d : %x (badMask = %x)\n", i, mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn], *badMask); 357 } else { 358 CHECKPIX(x, y, "reject: no item in data (badMask = %x)\n", *badMask); 359 } 331 360 continue; 332 361 } … … 334 363 pmStackData *data = inputs->data[i]; // Stack data of interest 335 364 if (!data) { 365 CHECKPIX(x, y, "skip: no item in data (badMask = %x)\n", *badMask); 336 366 continue; 337 367 } … … 339 369 int xIn = x - data->readout->col0, yIn = y - data->readout->row0; // Coordinates on input readout 340 370 psImage *mask = data->readout->mask; // Mask of interest 341 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & maskVal) { 371 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & badMaskBits) { 372 *badMask |= (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & badMaskBits); // save the bad bits used 373 CHECKPIX(x, y, "skip: adding bit to mask: %d : %x (badMask = %x)\n", i, mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn], *badMask); 342 374 continue; 343 375 } 344 376 345 pixelSuspects->data.U8[numGood] = mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & maskSuspect ? 346 true : false; 377 pixelSuspects->data.U8[numGood] = mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & suspectMaskBits ? true : false; 378 379 // *goodMask &= mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn]; // save the mask bits still used 380 // check for set bits and increment counter as appropriate 381 { 382 psImageMaskType value = 0x0001; 383 for (int nbit = 0; nbit < 16; nbit ++) { 384 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn] & value) { 385 nGoodBits[nbit] ++; 386 } 387 value <<= 1; 388 } 389 } 347 390 348 391 psImage *image = data->readout->image; // Image of interest … … 356 399 pixelSources->data.U16[numGood] = i; 357 400 numGood++; 401 402 CHECKPIX(x, y, "keep: %d : %x (badMask = %x)\n", i, mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn], *badMask); 358 403 } 359 404 pixelData->n = numGood; … … 367 412 *num = numGood; 368 413 414 // set the mask bits if nGoodBits[i] > f*numGood 415 { 416 # define SUSPECT_FRACTION 0.65 417 *goodMask = 0x0000; 418 psImageMaskType value = 0x0001; 419 for (int nbit = 0; nbit < 16; nbit ++) { 420 if (nGoodBits[nbit] > SUSPECT_FRACTION*numGood) { 421 *goodMask |= value; 422 } 423 value <<= 1; 424 } 425 } 426 369 427 #ifdef TESTING 370 428 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 371 429 for (int i = 0; i < numGood; i++) { 372 fprintf(stderr, "Input %d, pixel %d,%d (%" PRIu16 "): %f %f (%f) %f %f %d \n",430 fprintf(stderr, "Input %d, pixel %d,%d (%" PRIu16 "): %f %f (%f) %f %f %d %x %x -> %x %x\n", 373 431 i, x, y, pixelSources->data.U16[i], pixelData->data.F32[i], pixelVariances->data.F32[i], 374 432 addVariance->data.F32[i], pixelWeights->data.F32[i], pixelExps->data.F32[i], 375 pixelSuspects->data.U8[i] );433 pixelSuspects->data.U8[i], badMaskBits, suspectMaskBits, *badMask, *goodMask); 376 434 } 377 435 } … … 380 438 return; 381 439 } 382 383 440 384 441 // Combine pixels … … 392 449 combineBuffer *buffer, // Buffer with vectors 393 450 int x, int y, // Coordinates of interest; frame of output image 394 psImageMaskType bad, // Value for bad pixels 451 psImageMaskType blankMask, // Value for empty pixels 452 psImageMaskType badMask, // Value for bad pixels 453 psImageMaskType goodMask, // Value for good pixels 395 454 bool safe, // Safe combination? 396 455 float invTotalWeight // Inverse of total weight for all inputs … … 404 463 // Default option is that the pixel is bad 405 464 float imageValue = NAN, varianceValue = NAN; // Value for combined image and variance map 406 psImageMaskType maskValue = bad; // Value for combined mask407 465 float expValue = 0.0, expWeightValue = NAN; // Exposure value (straight, and weighted) 466 467 // default output mask value. badMask is the OR of all unused input pixels. 468 // if there are no input pixels, this value will be 0, in which case we want to set the output pixel to BLANK. 469 // if there are only good input pixels, and they do not result in a valid pixel, we still want to set this to BLANK. 470 psImageMaskType maskValue = badMask ? badMask : blankMask; // Value for combined mask 471 472 CHECKPIX(x, y, "bad vs good : %x %x %x\n", maskValue, badMask, blankMask); 408 473 409 474 switch (num) { 410 475 case 0: { 411 476 // Nothing to combine: it's bad 412 #ifdef TESTING 413 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 414 fprintf(stderr, "No inputs to combine, pixel %d,%d is bad.\n", x, y); 415 } 416 #endif 477 CHECKPIX(x, y, "No inputs to combine, pixel %d,%d is bad.\n", x, y); 417 478 break; 418 479 } … … 428 489 expWeightValue = pixelExps->data.F32[0]; 429 490 } 430 maskValue = 0; 431 #ifdef TESTING 432 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 433 fprintf(stderr, "Single input to combine, safety off, pixel %d,%d --> %f\n", 434 x, y, imageValue); 435 } 436 #endif 437 } 438 #ifdef TESTING 439 else if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 440 fprintf(stderr, "Single input to combine, safety on, pixel %d,%d is bad.\n", x, y); 441 } 442 #endif 491 maskValue = goodMask; 492 CHECKPIX(x, y, "Single input to combine, safety off, pixel %d,%d --> %f\n", x, y, imageValue); 493 } else { 494 CHECKPIX(x, y, "Single input to combine, safety on, pixel %d,%d is bad.\n", x, y); 495 } 443 496 break; 444 497 } … … 446 499 // Automatically accept the mean of the pixels only if we're not playing safe 447 500 if (!safe) { 448 if (combinationMeanVariance(&imageValue, &varianceValue, &expValue, &expWeightValue, 449 pixelData, pixelVariances, pixelExps, pixelWeights)) { 450 maskValue = 0; 451 #ifdef TESTING 452 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 453 fprintf(stderr, "Two inputs to combine using unsafe, pixel %d,%d --> %f %f\n", 454 x, y, imageValue, varianceValue); 455 } 456 #endif 501 if (combinationMeanVariance(&imageValue, &varianceValue, &expValue, &expWeightValue, pixelData, pixelVariances, pixelExps, pixelWeights)) { 502 maskValue = goodMask; 503 CHECKPIX(x, y, "Two inputs to combine using unsafe, pixel %d,%d --> %f %f\n", x, y, imageValue, varianceValue); 457 504 } 505 } else { 506 CHECKPIX(x, y, "Two inputs to combine, safety on, pixel %d,%d is bad\n", x, y); 458 507 } 459 #ifdef TESTING460 else {461 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) {462 fprintf(stderr, "Two inputs to combine, safety on, pixel %d,%d is bad\n", x, y);463 }464 }465 #endif466 508 break; 467 509 } … … 472 514 break; 473 515 } 474 maskValue = 0; 475 #ifdef TESTING 476 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 477 fprintf(stderr, "Combined inputs, pixel %d,%d --> %f %f\n", x, y, imageValue, varianceValue); 478 } 479 #endif 516 maskValue = goodMask; 517 CHECKPIX(x, y, "Combined inputs, pixel %d,%d --> %f %f\n", x, y, imageValue, varianceValue); 480 518 break; 481 519 } … … 522 560 int numIter = PS_MAX(iter * num, 1); // Number of iterations 523 561 524 #ifdef TESTING 525 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 526 fprintf(stderr, "Testing pixel %d,%d: %d %f %f %f %d %d\n", 527 x, y, numIter, rej, sys, olympic, useVariance, safe); 528 } 529 #endif 562 CHECKPIX(x, y, "Testing pixel %d,%d: %d %f %f %f %d %d\n", x, y, numIter, rej, sys, olympic, useVariance, safe); 530 563 531 564 psVector *pixelData = buffer->pixels; // Values for the pixel of interest … … 548 581 // Systematic error contributes to the rejection level 549 582 float sysVar = PS_SQR(sys * pixelData->data.F32[i]); 550 #ifdef TESTING 551 // Correct variance for comparison against weighted mean including itself 552 float compare = 1.0 - pixelWeights->data.F32[i] / sumWeights; 553 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 554 fprintf(stderr, "Variance %d (%d), pixel %d,%d: %f %f %f\n", i, pixelSources->data.U16[i], 555 x, y, pixelVariances->data.F32[i], sysVar, compare); 556 } 557 #endif 583 CHECKPIX(x, y, "Variance %d (%d), pixel %d,%d: %f %f %f\n", 584 i, pixelSources->data.U16[i], x, y, 585 pixelVariances->data.F32[i], sysVar, 1.0 - pixelWeights->data.F32[i] / sumWeights); 558 586 pixelLimits->data.F32[i] = rej2 * (pixelVariances->data.F32[i] + sysVar); 559 587 } … … 593 621 combineMarkInspect(inputs, x, y, pixelSources->data.U16[1]); 594 622 } 595 #ifdef TESTING 596 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 597 fprintf(stderr, "Flagged both inputs for pixel %d,%d (%f > %f x %f\n)", 598 x, y, diff, rej, sqrtf(sigma2)); 599 } 600 #endif 623 CHECKPIX(x, y, "Flagged both inputs for pixel %d,%d (%f > %f x %f\n)", x, y, diff, rej, sqrtf(sigma2)); 601 624 } 602 625 } else if (i == 0 && safe) { … … 708 731 float median = combinationWeightedOlympic(pixelData, pixelWeights, 709 732 olympic, buffer->sort); // Median for stack 710 #ifdef TESTING 711 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 712 fprintf(stderr, "Flag with variance pixel %d,%d: median = %f\n", x, y, median); 713 } 714 #endif 733 CHECKPIX(x, y, "Flag with variance pixel %d,%d: median = %f\n", x, y, median); 715 734 float worst = -INFINITY; // Largest deviation 716 735 for (int j = 0; j < num; j++) { 717 736 float diff = pixelData->data.F32[j] - median; // Difference from expected 718 #ifdef TESTING 719 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 720 fprintf(stderr, "Testing input %d for pixel %d,%d: %f\n", j, x, y, diff); 721 } 722 #endif 737 CHECKPIX(x, y, "Testing input %d for pixel %d,%d: %f\n", j, x, y, diff); 723 738 724 739 // Comparing squares --- cheaper than lots of sqrts … … 737 752 combinationMedianStdev(&median, &stdev, pixelData, buffer->sort); 738 753 float limit = rej * stdev; // Rejection limit 739 #ifdef TESTING 740 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 741 fprintf(stderr, 742 "Flag without variance pixel %d,%d; median = %f, stdev = %f, limit = %f\n", 743 x, y, median, stdev, limit); 744 } 745 #endif 754 CHECKPIX(x, y, "Flag without variance pixel %d,%d; median = %f, stdev = %f, limit = %f\n", x, y, median, stdev, limit); 746 755 float worst = -INFINITY; // Largest deviation 747 756 for (int j = 0; j < num; j++) { … … 763 772 if (maskIndex >= 0) { 764 773 if (suspect) { 765 #ifdef TESTING 766 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 767 fprintf(stderr, "Throwing out all suspect pixels for %d,%d\n", x, y); 768 } 769 #endif 774 CHECKPIX(x, y, "Throwing out all suspect pixels for %d,%d\n", x, y); 770 775 // Throw out all suspect pixels 771 776 int numGood = 0; // Number of good pixels … … 796 801 } else { 797 802 // Throw out masked pixel 798 #ifdef TESTING 799 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 800 fprintf(stderr, "Throwing out input %d for pixel %d,%d\n", maskIndex, x, y); 801 } 802 #endif 803 CHECKPIX(x, y, "Throwing out input %d for pixel %d,%d\n", maskIndex, x, y); 803 804 combineMarkInspect(inputs, x, y, pixelSources->data.U16[maskIndex]); 804 805 int numGood = 0; // Number of good pixels … … 999 1000 1000 1001 /// Stack input images 1001 bool pmStackCombine(pmReadout *combined, pmReadout *expmaps, psArray *input, 1002 psImageMaskType maskVal, psImageMaskType maskSuspect, 1003 psImageMaskType bad, int kernelSize, 1004 float iter, float rej, float sys, float olympic, 1005 bool useVariance, bool safe, bool rejection) 1002 bool pmStackCombine( 1003 pmReadout *combined, // output stacked readout 1004 pmReadout *expmaps, // output exposure map information 1005 psArray *input, // input exposures 1006 psImageMaskType badMaskBits, // treat these bits as 'bad' 1007 psImageMaskType suspectMaskBits, // treat these bits as 'suspect' 1008 psImageMaskType blankMaskBits, // use this mask value for pixels missing input data (distinguish between Ninput = 0 and Ngood = 0?) 1009 int kernelSize, 1010 float iter, 1011 float rej, 1012 float sys, 1013 float olympic, 1014 bool useVariance, 1015 bool safe, 1016 bool rejection) 1006 1017 { 1007 1018 bool haveVariances; // Do we have the variance maps? … … 1012 1023 } 1013 1024 PS_ASSERT_INT_NONNEGATIVE(kernelSize, false); 1014 PS_ASSERT_INT_POSITIVE(b ad, false);1025 PS_ASSERT_INT_POSITIVE(blankMaskBits, false); 1015 1026 if (isnan(rej)) { 1016 1027 PS_ASSERT_FLOAT_EQUAL(iter, 0, false); … … 1070 1081 } 1071 1082 psFree(stack); 1072 pmReadoutUpdateSize(combined, minInputCols, minInputRows, xSize, ySize, true, true, b ad);1083 pmReadoutUpdateSize(combined, minInputCols, minInputRows, xSize, ySize, true, true, blankMaskBits); 1073 1084 psTrace("psModules.imcombine", 1, "Have for combination [%d:%d,%d:%d] (%dx%d)\n", 1074 1085 minInputCols, maxInputCols, minInputRows, maxInputRows, xSize, ySize); … … 1131 1142 for (int y = minInputRows; y < maxInputRows; y++) { 1132 1143 for (int x = minInputCols; x < maxInputCols; x++) { 1144 CHECKPIX(x, y, "Combining pixel %d,%d: %x %x %f %f %f %f %d %d %d\n", x, y, badMaskBits, blankMaskBits, iter, rej, sys, olympic, useVariance, safe, rejection); 1145 1133 1146 #ifdef TESTING 1134 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) {1135 fprintf(stderr, "Combining pixel %d,%d: %x %x %f %f %f %f %d %d %d\n", 1136 x, y, maskVal, bad, iter, rej, sys, olympic, useVariance, safe, rejection); 1137 } 1138 #endif 1147 if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) { 1148 fprintf (stderr, "combine\n"); 1149 } 1150 # endif 1151 1139 1152 psVector *reject = NULL; // Images to reject for this pixel 1140 1153 if (rejection) { … … 1154 1167 #endif 1155 1168 } 1156 1157 int num; // Number of good pixels1158 bool suspect; // Suspect pixels in stack?1159 combineExtract(&num, &suspect, buffer, combinedImage, combinedMask, combinedVariance, 1160 input, weights, exps, addVariance, reject, x, y, maskVal, maskSuspect); 1161 combine Pixels(combinedImage, combinedMask, combinedVariance, exp, expnum, expweight,1162 num, buffer, x, y, bad, safe, totalExpWeight);1169 1170 int num; // Number of good pixels 1171 bool suspect; // Suspect pixels in stack? 1172 psImageMaskType badMask = 0; // OR of mask bits in all bad input pixels 1173 psImageMaskType goodMask = 0; // OR of mask bits in all good input pixels 1174 combineExtract(&num, &suspect, &badMask, &goodMask, buffer, combinedImage, combinedMask, combinedVariance, input, weights, exps, addVariance, reject, x, y, badMaskBits, suspectMaskBits); 1175 combinePixels(combinedImage, combinedMask, combinedVariance, exp, expnum, expweight, num, buffer, x, y, blankMaskBits, badMask, goodMask, safe, totalExpWeight); 1163 1176 1164 1177 if (iter > 0) {
Note:
See TracChangeset
for help on using the changeset viewer.
