Changeset 13406 for trunk/psModules/src/imcombine/pmSubtraction.c
- Timestamp:
- May 16, 2007, 6:13:19 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/imcombine/pmSubtraction.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtraction.c
r13398 r13406 4 4 * @author GLG, MHPCC 5 5 * 6 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $7 * @date $Date: 2007-05-1 6 21:13:51$6 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 7 * @date $Date: 2007-05-17 04:13:19 $ 8 8 * 9 9 * Copyright 2004-2007 Institute for Astronomy, University of Hawaii … … 53 53 } 54 54 55 // Generate an image of the solved kernel 56 // Meant to replace the following function declaration: 57 // static inline psKernel *solvedKernel(psKernel *kernel, // Kernel, to return 58 // const psVector *solution, // Solution to the least-squares problem 59 // const pmSubtractionKernels *kernels, // Kernel basis functions 60 // const psImage *polyValues, // Spatial polynomial values 61 // double (*weightFunc)(double value) // Function for weighting 62 // ); 63 // because even if the weightFunc can't be "static inline", they still appear in the assembly. 64 // TARGET: Kernel, to return (psKernel*) 65 // SOLUTION: Solution to the least-squares problem (psVector*) 66 // KERNELS: Kernel basis functions (pmSubtractionKernels*) 67 // POLYVALUES: Spatial polynomial values (psImage*) 68 // FUNC: Function for weighting (double (*weightFunc)(double value)) 69 #define SOLVED_KERNEL(TARGET, SOLUTION, KERNELS, POLYVALUES, FUNC) { \ 70 int numKernels = (SOLUTION)->n - 1; /* Number of kernel basis functions */ \ 71 assert((KERNELS)->u->n == numKernels); \ 72 assert((KERNELS)->v->n == numKernels); \ 73 assert((KERNELS)->xOrder->n == numKernels); \ 74 assert((KERNELS)->yOrder->n == numKernels); \ 75 \ 76 /* Ensure the subIndex for POIS kernels is what is expected */ \ 77 assert((KERNELS)->type != PM_SUBTRACTION_KERNEL_POIS || \ 78 ((KERNELS)->u->data.S32[(KERNELS)->subIndex] == 0 && \ 79 (KERNELS)->v->data.S32[(KERNELS)->subIndex] == 0 && \ 80 (KERNELS)->xOrder->data.S32[(KERNELS)->subIndex] == 0 && \ 81 (KERNELS)->yOrder->data.S32[(KERNELS)->subIndex] == 0)); \ 82 \ 83 int size = (KERNELS)->size; /* Kernel half-size */ \ 84 if (!(TARGET)) { \ 85 (TARGET) = psKernelAlloc(-size, size, -size, size); \ 86 } \ 87 psImageInit((TARGET)->image, 0.0); \ 88 \ 89 for (int i = 0; i < numKernels; i++) { \ 90 int xOrder = (KERNELS)->xOrder->data.S32[i]; /* Polynomial order in x */ \ 91 int yOrder = (KERNELS)->yOrder->data.S32[i]; /* Polynomial order in y */ \ 92 float value = FUNC((POLYVALUES)->data.F64[yOrder][xOrder] * (SOLUTION)->data.F64[i]); \ 93 float subValue = FUNC(-(SOLUTION)->data.F64[i]); /* Value to subtract (add because of minus) */ \ 94 switch ((KERNELS)->type) { \ 95 case PM_SUBTRACTION_KERNEL_POIS: { \ 96 int u = (KERNELS)->u->data.S32[i]; /* Offset in x */ \ 97 int v = (KERNELS)->v->data.S32[i]; /* Offset in y */ \ 98 (TARGET)->kernel[v][u] += value; \ 99 if ((KERNELS)->spatialOrder > 0 && i != (KERNELS)->subIndex) { \ 100 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ \ 101 (TARGET)->kernel[0][0] += subValue; \ 102 } \ 103 break; \ 104 } \ 105 case PM_SUBTRACTION_KERNEL_ISIS: { \ 106 psKernel *preCalc = (KERNELS)->preCalc->data[i]; /* Precalculated values */ \ 107 psKernel *subKernel = (KERNELS)->preCalc->data[(KERNELS)->subIndex]; /* Kernel to subtract */ \ 108 for (int v = -size; v <= size; v++) { \ 109 for (int u = -size; u <= size; u++) { \ 110 (TARGET)->kernel[v][u] += value * FUNC(preCalc->kernel[v][u]); \ 111 /* Subtract (0,0) kernel from other kernels to preserve photometric scaling */ \ 112 if ((KERNELS)->spatialOrder > 0 && i != (KERNELS)->subIndex) { \ 113 (TARGET)->kernel[v][u] += subValue * FUNC(subKernel->kernel[v][u]); \ 114 } \ 115 } \ 116 } \ 117 break; \ 118 } \ 119 default: \ 120 psAbort("Should never get here."); \ 121 } \ 122 } \ 123 } 124 125 #if 0 55 126 // Generate an image of the solved kernel 56 127 static inline psKernel *solvedKernel(psKernel *kernel, // Kernel, to return … … 117 188 return kernel; 118 189 } 119 190 #endif 191 192 // Generate the convolved pixel value 193 // Meant to replace the following function declaration: 194 // static inline double convolvePixel(const pmSubtractionKernels *kernels, // Kernel basis functions 195 // int index, // Kernel basis function index 196 // int x, int y, // Pixel around which to convolve 197 // const psImage *image, // Image to convolve 198 // const psImage *polyValues, // Spatial polynomial values 199 // double (*weightFunc)(double value) // Function for weighting 200 // ); 201 // because even if the weightFunc can't be "static inline", they still appear in the assembly. 202 // 203 // TARGET: The value to 'return' (double) 204 // KERNELS: Kernel basis functions (pmSubtractionKernels*) 205 // INDEX: Kernel basis function index (int) 206 // X, Y: Pixel around which to convolve (int) 207 // IMAGE: Image to convolve (psImage*) 208 // POLYVALUES: Spatial polynomial values (psImage*) 209 // FUNC: Function for weighting (double (*weightFunc)(double value)) 210 #define CONVOLVE_PIXEL(TARGET, KERNELS, INDEX, X, Y, IMAGE, POLYVALUES, FUNC) { \ 211 int xOrder = (KERNELS)->xOrder->data.S32[(INDEX)]; /* Polynomial order in x */ \ 212 int yOrder = (KERNELS)->yOrder->data.S32[(INDEX)]; /* Polynomial order in y */ \ 213 double polyValue = (POLYVALUES)->data.F64[yOrder][xOrder]; /* Value of spatial polynomial */ \ 214 \ 215 switch ((KERNELS)->type) { \ 216 case PM_SUBTRACTION_KERNEL_POIS: { \ 217 /* Convolution with a delta function is just the value specified by the offset */ \ 218 int u = (KERNELS)->u->data.S32[(INDEX)]; /* Offset in x */ \ 219 int v = (KERNELS)->v->data.S32[(INDEX)]; /* Offset in y */ \ 220 (TARGET) = FUNC(polyValue) * (IMAGE)->data.F32[(Y) + v][(X) + u]; /* Value of convolution */ \ 221 if ((KERNELS)->spatialOrder > 0 && (INDEX) != (KERNELS)->subIndex) { \ 222 /* The (0,0) element is subtracted from most kernels to preserve photometric scaling */ \ 223 (TARGET) += FUNC(-1.0) * (IMAGE)->data.F32[(Y)][(X)]; \ 224 } \ 225 break; \ 226 } \ 227 case PM_SUBTRACTION_KERNEL_ISIS: { \ 228 psKernel *kernel = (KERNELS)->preCalc->data[(INDEX)]; /* The convolution kernel */ \ 229 psKernel *subKernel = (KERNELS)->preCalc->data[(KERNELS)->subIndex]; /* Kernel to subtract */ \ 230 int size = (KERNELS)->size; /* Kernel half-size */ \ 231 double sum = 0.0; /* Accumulated sum from convolution */ \ 232 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]; \ 236 /* The (0,0) kernel is subtracted from other kernels to preserve photometric scaling */ \ 237 if ((KERNELS)->spatialOrder > 0 && (INDEX) != (KERNELS)->subIndex) { \ 238 sub += FUNC(subKernel->kernel[v][u]) * (IMAGE)->data.F32[(Y) + v][(X) + u]; \ 239 } \ 240 } \ 241 } \ 242 TARGET = FUNC(polyValue) * sum + FUNC(-1.0) * sub; \ 243 break; \ 244 } \ 245 default: \ 246 psAbort("Should never get here."); \ 247 } \ 248 } 249 250 #if 0 120 251 // Generate the convolved pixel value 121 252 static inline double convolvePixel(const pmSubtractionKernels *kernels, // Kernel basis functions … … 165 296 return NAN; 166 297 } 298 #endif 167 299 168 300 // Weighting function for use with convolvePixel: no weighting applied, suitable for combining image pixels … … 269 401 // Generate the convolutions 270 402 for (int i = 0; i < numKernels; i++) { 403 #if 0 271 404 convolutions->data.F64[i] = convolvePixel(kernels, i, x, y, reference, polyValues, 272 405 imageWeighting); 406 #else 407 CONVOLVE_PIXEL(convolutions->data.F64[i], kernels, i, x, y, reference, polyValues, 408 imageWeighting); 409 #endif 273 410 } 274 411 … … 450 587 for (int x = footprint; x <= footprint; x++) { 451 588 for (int k = 0; k < numKernels; k++) { 589 #if 0 452 590 convolvedStamp->data.F32[y + footprint][x + footprint] += 453 591 convolvePixel(kernels, k, xStamp + x, yStamp + y, refImage, polyValues, 454 592 imageWeighting); 593 #else 594 CONVOLVE_PIXEL(convolvedStamp->data.F32[y + footprint][x + footprint], kernels, 595 k, xStamp + x, yStamp + y, refImage, polyValues, imageWeighting); 596 #endif 455 597 } 456 598 } … … 532 674 533 675 // The appropriate kernel 676 #if 0 534 677 psKernel *kernel = solvedKernel(NULL, solution, kernels, polyValues, imageWeighting); 678 #else 679 psKernel *kernel = NULL; 680 SOLVED_KERNEL(kernel, solution, kernels, polyValues, imageWeighting); 681 #endif 535 682 536 683 psFree(polyValues); … … 630 777 2.0 * (float)(i + size - numCols/2.0) / (float)numCols, 631 778 2.0 * (float)(j + size - numRows/2.0) / (float)numRows); 779 #if 0 632 780 kernelImage = solvedKernel(kernelImage, solution, kernels, polyValues, imageWeighting); 633 781 if (inWeight) { … … 635 783 varianceWeighting); 636 784 } 785 #else 786 SOLVED_KERNEL(kernelImage, solution, kernels, polyValues, imageWeighting); 787 if (inWeight) { 788 SOLVED_KERNEL(kernelWeight, solution, kernels, polyValues, varianceWeighting); 789 } 790 #endif 637 791 638 792 for (int y = j; y < j + fullSize; y++) {
Note:
See TracChangeset
for help on using the changeset viewer.
