Changeset 14106 for trunk/psModules/src/imcombine/pmSubtraction.c
- Timestamp:
- Jul 10, 2007, 1:54:26 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/imcombine/pmSubtraction.c (modified) (28 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtraction.c
r13736 r14106 4 4 * @author GLG, MHPCC 5 5 * 6 * @version $Revision: 1.1 4$ $Name: not supported by cvs2svn $7 * @date $Date: 2007-0 6-09 01:06:48$6 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $ 7 * @date $Date: 2007-07-10 23:54:26 $ 8 8 * 9 9 * Copyright 2004-2007 Institute for Astronomy, University of Hawaii … … 24 24 25 25 #include "pmSubtraction.h" 26 27 //#define CAN_PASS_STATIC_INLINE // Can I pass the address of a static inline function? 26 28 27 29 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 53 55 } 54 56 57 #ifndef CAN_PASS_STATIC_INLINE 55 58 // Generate an image of the solved kernel 56 59 // Meant to replace the following function declaration: … … 61 64 // double (*weightFunc)(double value) // Function for weighting 62 65 // ); 63 // because even if the weightFunc can't be "static inline", they still appearin the assembly.66 // because even though the weightFunc is "static inline", it still appears in the assembly. 64 67 // TARGET: Kernel, to return (psKernel*) 65 68 // SOLUTION: Solution to the least-squares problem (psVector*) … … 75 78 \ 76 79 /* Ensure the subIndex for POIS kernels is what is expected */ \ 77 assert((KERNELS)->type != PM_SUBTRACTION_KERNEL_POIS || \ 80 assert(((KERNELS)->type != PM_SUBTRACTION_KERNEL_POIS && \ 81 (KERNELS)->type != PM_SUBTRACTION_KERNEL_SPAM && \ 82 (KERNELS)->type != PM_SUBTRACTION_KERNEL_FRIES) || \ 78 83 ((KERNELS)->u->data.S32[(KERNELS)->subIndex] == 0 && \ 79 84 (KERNELS)->v->data.S32[(KERNELS)->subIndex] == 0 && \ … … 103 108 break; \ 104 109 } \ 110 /* SPAM and FRIES use the same method */ \ 111 case PM_SUBTRACTION_KERNEL_SPAM: \ 112 case PM_SUBTRACTION_KERNEL_FRIES: { \ 113 int uStart = (KERNELS)->u->data.S32[i]; \ 114 int uStop = (KERNELS)->uStop->data.S32[i]; \ 115 int vStart = (KERNELS)->v->data.S32[i]; \ 116 int vStop = (KERNELS)->vStop->data.S32[i]; \ 117 for (int v = vStart; v <= vStop; v++) { \ 118 for (int u = uStart; u <= uStop; u++) { \ 119 (TARGET)->kernel[v][u] += value; \ 120 } \ 121 } \ 122 if ((KERNELS)->spatialOrder > 0 && i != (KERNELS)->subIndex) { \ 123 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ \ 124 (TARGET)->kernel[0][0] += subValue; \ 125 } \ 126 break; \ 127 } \ 105 128 case PM_SUBTRACTION_KERNEL_ISIS: { \ 106 129 psKernel *preCalc = (KERNELS)->preCalc->data[i]; /* Precalculated values */ \ … … 122 145 } \ 123 146 } 124 125 #if 0 147 #else 126 148 // Generate an image of the solved kernel 127 149 static inline psKernel *solvedKernel(psKernel *kernel, // Kernel, to return … … 139 161 140 162 // Ensure the subIndex for POIS kernels is what is expected 141 assert(kernels->type != PM_SUBTRACTION_KERNEL_POIS || 163 assert((kernels->type != PM_SUBTRACTION_KERNEL_POIS && 164 kernels->type != PM_SUBTRACTION_KERNEL_SPAM && 165 kernels->type != PM_SUBTRACTION_KERNEL_FRIES) || 142 166 (kernels->u->data.S32[kernels->subIndex] == 0 && kernels->v->data.S32[kernels->subIndex] == 0 && 143 167 kernels->xOrder->data.S32[kernels->subIndex] == 0 && … … 167 191 break; 168 192 } 193 /* SPAM and FRIES use the same method */ 194 case PM_SUBTRACTION_KERNEL_SPAM: 195 case PM_SUBTRACTION_KERNEL_FRIES: 196 int uStart = kernels->u->data.S32[i]; 197 int uStop = kernels->uStop->data.S32[i]; 198 int vStart = kernels->v->data.S32[i]; 199 int vStop = kernels->vStop->data.S32[i]; 200 for (int v = vStart; v <= vStop; v++) { 201 for (int u = uStart; u <= uStop; u++) { 202 kernel->kernel[v][u] += value; 203 } 204 } 205 if (kernels->spatialOrder > 0 && i != kernels->subIndex) { 206 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ 207 kernel->kernel[0][0] += subValue; 208 } 209 break; 169 210 case PM_SUBTRACTION_KERNEL_ISIS: { 170 211 psKernel *preCalc = kernels->preCalc->data[i];// Precalculated values … … 190 231 #endif 191 232 233 #ifndef CAN_PASS_STATIC_INLINE 192 234 // Generate the convolved pixel value 193 235 // Meant to replace the following function declaration: … … 199 241 // double (*weightFunc)(double value) // Function for weighting 200 242 // ); 201 // because even if the weightFunc can't be "static inline", they still appearin the assembly.243 // because even though weightFunc is "static inline", it still appears in the assembly. 202 244 // 203 245 // TARGET: The value to 'return' (double) … … 225 267 break; \ 226 268 } \ 227 case PM_SUBTRACTION_KERNEL_ISIS: { \ 269 /* Method for SPAM and FRIES is the same */ \ 270 case PM_SUBTRACTION_KERNEL_SPAM: \ 271 case PM_SUBTRACTION_KERNEL_FRIES: { \ 272 int uStart = (KERNELS)->u->data.S32[(INDEX)]; \ 273 int uStop = (KERNELS)->uStop->data.S32[(INDEX)]; \ 274 int vStart = (KERNELS)->v->data.S32[(INDEX)]; \ 275 int vStop = (KERNELS)->vStop->data.S32[(INDEX)]; \ 276 for (int v = vStart; v <= vStop; v++) { \ 277 for (int u = uStart; u <= uStop; u++) { \ 278 (TARGET) += FUNC(polyValue) * (IMAGE)->data.F32[(Y) + v][(X) + u]; \ 279 } \ 280 } \ 281 if ((KERNELS)->spatialOrder > 0 && (INDEX) != (KERNELS)->subIndex) { \ 282 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ \ 283 (TARGET) += FUNC(-1.0) * (IMAGE)->data.F32[(Y)][(X)]; \ 284 } \ 285 break; \ 286 } \ 287 case PM_SUBTRACTION_KERNEL_ISIS: { \ 228 288 psKernel *kernel = (KERNELS)->preCalc->data[(INDEX)]; /* The convolution kernel */ \ 229 289 psKernel *subKernel = (KERNELS)->preCalc->data[(KERNELS)->subIndex]; /* Kernel to subtract */ \ … … 231 291 double sum = 0.0; /* Accumulated sum from convolution */ \ 232 292 double sub = 0.0; /* Accumulated sum to subtract */ \ 233 for (int v = -size ; v <= size; v++) { \234 for (int u = -size ; u <= size; u++) { \235 sum += FUNC(kernel->kernel[v][u]) * (IMAGE)->data.F32[ (Y) + v][(X) + u]; \293 for (int v = -size, y = (Y) - size; v <= size; v++, y++) { \ 294 for (int u = -size, x = (X) - size; u <= size; u++, x++) { \ 295 sum += FUNC(kernel->kernel[v][u]) * (IMAGE)->data.F32[y][x]; \ 236 296 /* The (0,0) kernel is subtracted from other kernels to preserve photometric scaling */ \ 237 297 if ((KERNELS)->spatialOrder > 0 && (INDEX) != (KERNELS)->subIndex) { \ 238 sub += FUNC(subKernel->kernel[v][u]) * (IMAGE)->data.F32[ (Y) + v][(X) + u]; \298 sub += FUNC(subKernel->kernel[v][u]) * (IMAGE)->data.F32[y][x]; \ 239 299 } \ 240 300 } \ … … 247 307 } \ 248 308 } 249 250 #if 0 309 #else 251 310 // Generate the convolved pixel value 252 311 static inline double convolvePixel(const pmSubtractionKernels *kernels, // Kernel basis functions … … 273 332 } 274 333 return value; 334 } 335 /* Method for SPAM and FRIES is the same */ 336 case PM_SUBTRACTION_KERNEL_SPAM: 337 case PM_SUBTRACTION_KERNEL_FRIES: { 338 int uStart = kernels->u->data.S32[index]; 339 int uStop = kernels->uStop->data.S32[index]; 340 int vStart = kernels->v->data.S32[index]; 341 int vStop = kernels->vStop->data.S32[index]; 342 for (int v = vStart; v <= vStop; v++) { 343 for (int u = uStart; u <= uStop; u++) { 344 value += weightFunc(polyValue) * image->data.F32[y + v][x + u]; 345 } 346 } 347 if (kernels->spatialOrder > 0 && index != kernels->subIndex) { 348 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ 349 value += weightFunc(-1.0) * image->data.F32[y][x]; 350 } 351 break; 275 352 } 276 353 case PM_SUBTRACTION_KERNEL_ISIS: { … … 333 410 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 334 411 335 psImage *pmSubtractionMask(const psImage *inMask, const psImage *refMask, psMaskType maskVal,336 int size, int footprint)337 {338 PS_ASSERT_IMAGE_NON_NULL(inMask, NULL);339 PS_ASSERT_IMAGE_TYPE(inMask, PS_TYPE_MASK, NULL);340 PS_ASSERT_IMAGE_NON_NULL(refMask, NULL);341 PS_ASSERT_IMAGE_TYPE(refMask, PS_TYPE_MASK, NULL);342 PS_ASSERT_IMAGES_SIZE_EQUAL(inMask, refMask, NULL);343 PS_ASSERT_INT_NONNEGATIVE(size, NULL);344 PS_ASSERT_INT_NONNEGATIVE(footprint, NULL);345 346 // Size of the images347 int numCols = inMask->numCols;348 int numRows = inMask->numRows;349 350 // Worried about the masks for bad pixels and bad stamps colliding, so make our own mask351 psImage *mask = psImageAlloc(numCols, numRows, PS_TYPE_MASK); // The global mask352 psImageInit(mask, 0);353 354 // Dereference for convenience355 psMaskType **maskData = mask->data.PS_TYPE_MASK_DATA;356 psMaskType **inData = inMask->data.PS_TYPE_MASK_DATA;357 psMaskType **refData = refMask->data.PS_TYPE_MASK_DATA;358 359 // Block out a border around the edge of the image360 361 // Bottom stripe362 for (int y = 0; y < PS_MIN(size + footprint, numRows); y++) {363 for (int x = 0; x < numCols; x++) {364 maskData[y][x] |= PM_SUBTRACTION_MASK_BORDER;365 }366 }367 // Either side368 for (int y = PS_MIN(size + footprint, numRows); y < numRows - size - footprint; y++) {369 for (int x = 0; x < PS_MIN(size + footprint, numCols); x++) {370 maskData[y][x] |= PM_SUBTRACTION_MASK_BORDER;371 }372 for (int x = PS_MAX(numCols - size - footprint, 0); x < numCols; x++) {373 maskData[y][x] |= PM_SUBTRACTION_MASK_BORDER;374 }375 }376 // Top stripe377 for (int y = PS_MAX(numRows - size - footprint, 0); y < numRows; y++) {378 for (int x = 0; x < numCols; x++) {379 maskData[y][x] |= PM_SUBTRACTION_MASK_BORDER;380 }381 }382 383 // Mask the bad pixels, and around them384 for (int y = footprint + size; y < numRows - footprint - size; y++) {385 for (int x = 0; x < numCols; x++) {386 if (inData[y][x] & maskVal) {387 maskData[y][x] |= PM_SUBTRACTION_MASK_INPUT;388 // Block out the entire stamp footprint around this pixel389 for (int v = y - footprint; v <= y + footprint; v++) {390 for (int u = x - footprint; u <= x + footprint; u++) {391 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;392 }393 }394 }395 if (refData[y][x] & maskVal) {396 maskData[y][x] |= PM_SUBTRACTION_MASK_REF;397 398 // We want to block out with the CONVOLVE mask anything that would be bad if we convolved with399 // this bad pixel (within 'size'). Then we want to block out with the FOOTPRINT mask400 // everything within a footprint's distance of those (within 'footprint').401 402 // Bottom stripe403 for (int v = PS_MAX(y - footprint - size, 0); v < y - size; v++) {404 for (int u = PS_MAX(x - footprint - size, 0);405 u <= PS_MIN(x + footprint + size, numCols - 1); u++) {406 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;407 }408 }409 // Middle410 for (int v = PS_MAX(y - size, 0); v <= PS_MIN(y + size, numRows - 1); v++) {411 // Left side412 for (int u = PS_MAX(x - footprint - size, 0); u < x - size; u++) {413 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;414 }415 // Centre416 for (int u = PS_MAX(x - size, 0); u <= PS_MIN(x + size, numCols - 1); u++) {417 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT | PM_SUBTRACTION_MASK_CONVOLVE;418 }419 // Right side420 for (int u = x + size + 1; u <= PS_MIN(x + footprint + size, numCols - 1); u++) {421 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;422 }423 }424 // Top stripe425 for (int v = y + size + 1; v <= PS_MIN(y + footprint + size, numRows - 1); v++) {426 for (int u = PS_MAX(x - footprint - size, 0);427 u <= PS_MIN(x + footprint + size, numCols - 1); u++) {428 maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;429 }430 }431 }432 }433 }434 435 return mask;436 }437 438 412 bool pmSubtractionCalculateEquation(psArray *stamps, const psImage *reference, const psImage *input, 439 413 const psImage *weight, const pmSubtractionKernels *kernels, int footprint) … … 504 478 // Generate the convolutions 505 479 for (int i = 0; i < numKernels; i++) { 506 #if 0480 #ifdef CAN_PASS_STATIC_INLINE 507 481 convolutions->data.F64[i] = convolvePixel(kernels, i, x, y, reference, polyValues, 508 482 imageWeighting); … … 533 507 psFree(polyValues); 534 508 535 // Fill in lower diagonal of symmetric matrix, while checking for bad values 536 bool bad = false; // Are there bad values? 509 // Fill in lower diagonal of symmetric matrix 537 510 for (int i = 0; i < numKernels; i++) { 538 511 for (int j = 0; j < i; j++) { 539 if (!isfinite(stampMatrix->data.F64[j][i])) {540 bad = true;541 }542 512 stampMatrix->data.F64[i][j] = stampMatrix->data.F64[j][i]; 543 513 } 544 if (!isfinite(stampMatrix->data.F64[i][bgIndex]) ||545 !isfinite(stampMatrix->data.F64[i][i]) ||546 !isfinite(stampVector->data.F64[i])) {547 bad = true;548 }549 514 stampMatrix->data.F64[bgIndex][i] = stampMatrix->data.F64[i][bgIndex]; 550 515 } 551 if (!isfinite(stampVector->data.F64[bgIndex])) { 552 bad = true; 553 } 554 555 if (bad) { 556 stamp->status = PM_SUBTRACTION_STAMP_REJECTED; 557 psTrace("psModules.imcombine", 3, "Rejecting stamp %d because of bad equation\n", i); 558 } else { 559 stamp->status = PM_SUBTRACTION_STAMP_USED; 560 } 516 517 stamp->status = PM_SUBTRACTION_STAMP_USED; 561 518 562 519 if (psTraceGetLevel("psModules.imcombine.equation") >= 10) { … … 653 610 654 611 int pmSubtractionRejectStamps(psArray *stamps, const psImage *refImage, psImage *inImage, 655 psImage * subMask, const psVector *solution, int footprint, float sigmaRej,656 const pmSubtractionKernels *kernels)612 psImage *mask, psMaskType badStampMaskVal, const psVector *solution, 613 int footprint, float sigmaRej, const pmSubtractionKernels *kernels) 657 614 { 658 615 PS_ASSERT_ARRAY_NON_NULL(stamps, -1); … … 662 619 PS_ASSERT_IMAGE_TYPE(inImage, PS_TYPE_F32, -1); 663 620 PS_ASSERT_IMAGES_SIZE_EQUAL(refImage, inImage, -1); 664 PS_ASSERT_IMAGE_NON_EMPTY( subMask, -1);665 PS_ASSERT_IMAGE_TYPE( subMask, PS_TYPE_MASK, -1);666 PS_ASSERT_IMAGES_SIZE_EQUAL(refImage, subMask, -1);621 PS_ASSERT_IMAGE_NON_EMPTY(mask, -1); 622 PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, -1); 623 PS_ASSERT_IMAGES_SIZE_EQUAL(refImage, mask, -1); 667 624 PS_ASSERT_VECTOR_NON_NULL(solution, -1); 668 625 PS_ASSERT_VECTOR_TYPE(solution, PS_TYPE_F64, -1); … … 707 664 for (int x = footprint; x <= footprint; x++) { 708 665 for (int k = 0; k < numKernels; k++) { 709 #if 0666 #ifdef CAN_PASS_STATIC_INLINE 710 667 convolvedStamp->data.F32[y + footprint][x + footprint] += 711 668 convolvePixel(kernels, k, xStamp + x, yStamp + y, refImage, polyValues, … … 753 710 if (stamp->status == PM_SUBTRACTION_STAMP_USED && deviations->data.F32[i] > limit) { 754 711 // Mask out the stamp in the image so you it's not found again 755 psTrace("psModules.imcombine", 3, " Clipping stamp %d\n", i);712 psTrace("psModules.imcombine", 3, "Rejecting stamp %d\n", i); 756 713 numRejected++; 757 714 for (int y = stamp->y - footprint; y <= stamp->y + footprint; y++) { 758 715 for (int x = stamp->x - footprint; x <= stamp->x + footprint; x++) { 759 subMask->data.PS_TYPE_MASK_DATA[y][x] |= PM_SUBTRACTION_MASK_REJ;716 mask->data.PS_TYPE_MASK_DATA[y][x] |= badStampMaskVal; 760 717 } 761 718 } … … 794 751 795 752 // The appropriate kernel 796 #if 0753 #ifdef CAN_PASS_STATIC_INLINE 797 754 psKernel *kernel = solvedKernel(NULL, solution, kernels, polyValues, imageWeighting); 798 755 #else … … 810 767 811 768 bool pmSubtractionConvolve(psImage **outImage, psImage **outWeight, psImage **outMask, 812 const psImage *inImage, const psImage *inWeight, const psImage *subMask, 813 psMaskType blank, const psVector *solution, const pmSubtractionKernels *kernels) 769 const psImage *inImage, const psImage *inWeight, const psImage *inMask, 770 psMaskType maskVal, psMaskType blank, 771 const psVector *solution, const pmSubtractionKernels *kernels) 814 772 { 815 773 PS_ASSERT_IMAGE_NON_NULL(inImage, false); 816 774 PS_ASSERT_IMAGE_TYPE(inImage, PS_TYPE_F32, false); 817 if ( subMask) {818 PS_ASSERT_IMAGE_NON_NULL( subMask, false);819 PS_ASSERT_IMAGE_TYPE( subMask, PS_TYPE_MASK, false);820 PS_ASSERT_IMAGES_SIZE_EQUAL( subMask, inImage, false);775 if (inMask) { 776 PS_ASSERT_IMAGE_NON_NULL(inMask, false); 777 PS_ASSERT_IMAGE_TYPE(inMask, PS_TYPE_MASK, false); 778 PS_ASSERT_IMAGES_SIZE_EQUAL(inMask, inImage, false); 821 779 } 822 780 if (inWeight) { … … 835 793 PS_ASSERT_IMAGES_SIZE_EQUAL(*outMask, inImage, false); 836 794 PS_ASSERT_IMAGE_TYPE(*outMask, PS_TYPE_MASK, false); 837 PS_ASSERT_IMAGE_NON_NULL( subMask, false);795 PS_ASSERT_IMAGE_NON_NULL(inMask, false); 838 796 } 839 797 if (outWeight && *outWeight) { … … 865 823 } 866 824 psImage *convMask = NULL; // Convolved mask image 867 if (outMask && subMask) {825 if (outMask && inMask) { 868 826 if (!*outMask) { 869 827 *outMask = psImageAlloc(numCols, numRows, PS_TYPE_MASK); … … 896 854 2.0 * (float)(i + size - numCols/2.0) / (float)numCols, 897 855 2.0 * (float)(j + size - numRows/2.0) / (float)numRows); 898 #if 0856 #ifdef CAN_PASS_STATIC_INLINE 899 857 kernelImage = solvedKernel(kernelImage, solution, kernels, polyValues, imageWeighting); 900 858 if (inWeight) { … … 914 872 915 873 // Check and propagate the kernel footprint, if required 916 if ( subMask && (subMask->data.PS_TYPE_MASK_DATA[y][x] &917 (PM_SUBTRACTION_MASK_INPUT | PM_SUBTRACTION_MASK_CONVOLVE))) {918 convMask->data.PS_TYPE_MASK_DATA[y][x] |= blank;919 convImage->data.F32[y][x] = NAN;920 if (inWeight) {921 convWeight->data.F32[y][x] = NAN;874 if (inMask) { 875 for (int v = -size; v <= size; v++) { 876 for (int u = -size; u <= size; u++) { 877 convMask->data.PS_TYPE_MASK_DATA[y][x] |= 878 inMask->data.PS_TYPE_MASK_DATA[y + v][x + u]; 879 } 922 880 } 923 continue; 881 if (convMask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) { 882 convImage->data.F32[y][x] = NAN; 883 if (inWeight) { 884 convWeight->data.F32[y][x] = NAN; 885 } 886 continue; 887 } 924 888 } 925 889
Note:
See TracChangeset
for help on using the changeset viewer.
