Changeset 21363 for trunk/psModules/src/imcombine/pmSubtraction.c
- Timestamp:
- Feb 5, 2009, 4:31:25 PM (17 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/imcombine/pmSubtraction.c (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtraction.c
r21351 r21363 60 60 61 61 // Normalise so that the sum of the variance kernel is the square of the sum of the normal kernel 62 // This is required to keep the relative scaling between the image and the weightmap62 // This is required to keep the relative scaling between the image and the variance map 63 63 psBinaryOp(out->image, out->image, "*", psScalarAlloc(PS_SQR(sumNormal) / sumVariance, PS_TYPE_F32)); 64 64 … … 287 287 288 288 // Convolve an image using FFT 289 static void convolve WeightFFT(psImage *target,// Place the result in here290 psImage * weight, // Weightmap to convolve289 static void convolveVarianceFFT(psImage *target,// Place the result in here 290 psImage *variance, // Variance map to convolve 291 291 psImage *sys, // Systematic error image 292 292 psImage *mask, // Mask image … … 302 302 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 303 303 304 psImage *sub Weight = convolveSubsetAlloc(weight, border, threaded); // Weightmap304 psImage *subVariance = convolveSubsetAlloc(variance, border, threaded); // Variance map 305 305 psImage *subSys = convolveSubsetAlloc(sys, border, threaded); // Systematic error image 306 306 psImage *subMask = convolveSubsetAlloc(mask, border, threaded); // Mask 307 307 308 308 // XXX Can trim this a little by combining the convolution: only have to take the FFT of the kernel once 309 psImage *conv Weight = psImageConvolveFFT(NULL, subWeight, subMask, maskVal, kernel); // Convolved weight309 psImage *convVariance = psImageConvolveFFT(NULL, subVariance, subMask, maskVal, kernel); // Convolved variance 310 310 psImage *convSys = subSys ? psImageConvolveFFT(NULL, subSys, subMask, maskVal, kernel) : NULL; // Conv sys 311 311 312 convolveSubsetFree( weight, subWeight, threaded);312 convolveSubsetFree(variance, subVariance, threaded); 313 313 convolveSubsetFree(sys, subSys, threaded); 314 314 convolveSubsetFree(mask, subMask, threaded); … … 319 319 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 320 320 for (int xTarget = xMin, xSource = size; xTarget < xMax; xTarget++, xSource++) { 321 target->data.F32[yTarget][xTarget] = conv Weight->data.F32[ySource][xSource] +321 target->data.F32[yTarget][xTarget] = convVariance->data.F32[ySource][xSource] + 322 322 convSys->data.F32[ySource][xSource]; 323 323 } … … 326 326 int numBytes = (xMax - xMin) * PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy 327 327 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 328 memcpy(&target->data.F32[yTarget][xMin], &conv Weight->data.F32[ySource][size], numBytes);329 } 330 } 331 332 psFree(conv Weight);328 memcpy(&target->data.F32[yTarget][xMin], &convVariance->data.F32[ySource][size], numBytes); 329 } 330 } 331 332 psFree(convVariance); 333 333 psFree(convSys); 334 334 … … 361 361 // Convolve a region of an image 362 362 static inline void convolveRegion(psImage *convImage, // Convolved image (output) 363 psImage *conv Weight, // Convolved weightmap (output), or NULL363 psImage *convVariance, // Convolved variance map (output), or NULL 364 364 psImage *convMask, // Convolve mask (output), or NULL 365 365 psKernel **kernelImage, // Convolution kernel for the image 366 psKernel **kernel Weight, // Convolution kernel for the weightmap, or NULL366 psKernel **kernelVariance, // Convolution kernel for the variance map, or NULL 367 367 psImage *image, // Image to convolve 368 psImage * weight, // Weightmap to convolve, or NULL368 psImage *variance, // Variance map to convolve, or NULL 369 369 psImage *sys, // Systematic error image, or NULL 370 370 psImage *subMask, // Subtraction mask … … 381 381 { 382 382 *kernelImage = solvedKernel(*kernelImage, kernels, polyValues, wantDual); 383 if ( weight|| subMask) {384 *kernel Weight = varianceKernel(*kernelWeight, *kernelImage);383 if (variance || subMask) { 384 *kernelVariance = varianceKernel(*kernelVariance, *kernelImage); 385 385 } 386 386 … … 398 398 } 399 399 400 // Convolve the image and weight400 // Convolve the image and variance 401 401 if (useFFT) { 402 402 // Use Fast Fourier Transform to do the convolution 403 403 // This provides a big speed-up for large kernels 404 404 convolveFFT(convImage, image, subMask, subBad, *kernelImage, region, background, kernels->size); 405 if ( weight) {406 convolve WeightFFT(convWeight, weight, sys, subMask, subBad, *kernelWeight, region, kernels->size);405 if (variance) { 406 convolveVarianceFFT(convVariance, variance, sys, subMask, subBad, *kernelVariance, region, kernels->size); 407 407 } 408 408 } else { 409 409 // XXX Direct convolution doesn't account for bad pixels yet 410 410 convolveDirect(convImage, image, *kernelImage, region, background, kernels->size); 411 if ( weight) {412 convolveDirect(conv Weight, weight, *kernelWeight, region, 0.0, kernels->size);411 if (variance) { 412 convolveDirect(convVariance, variance, *kernelVariance, region, 0.0, kernels->size); 413 413 } 414 414 } … … 885 885 psFree(stamp->image1); 886 886 psFree(stamp->image2); 887 psFree(stamp-> weight);888 stamp->image1 = stamp->image2 = stamp-> weight= NULL;887 psFree(stamp->variance); 888 stamp->image1 = stamp->image2 = stamp->variance = NULL; 889 889 psFree(stamp->matrix1); 890 890 psFree(stamp->matrix2); … … 915 915 } 916 916 917 ps Image *pmSubtractionKernelImage(const pmSubtractionKernels *kernels, float x, float y, bool wantDual)917 psKernel *pmSubtractionKernel(const pmSubtractionKernels *kernels, float x, float y, bool wantDual) 918 918 { 919 919 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, NULL); … … 922 922 PS_ASSERT_FLOAT_WITHIN_RANGE(y, -1.0, 1.0, NULL); 923 923 924 // Precalulate polynomial values 925 psImage *polyValues = p_pmSubtractionPolynomial(NULL, kernels->spatialOrder, x, y); 926 927 // The appropriate kernel 928 psKernel *kernel = solvedKernel(NULL, kernels, polyValues, wantDual); 929 924 psImage *polyValues = p_pmSubtractionPolynomial(NULL, kernels->spatialOrder, x, y); // Solved polynomial 925 psKernel *kernel = solvedKernel(NULL, kernels, polyValues, wantDual); // The appropriate kernel 930 926 psFree(polyValues); 931 927 928 return kernel; 929 } 930 931 psImage *pmSubtractionKernelImage(const pmSubtractionKernels *kernels, float x, float y, bool wantDual) 932 { 933 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, NULL); 934 PM_ASSERT_SUBTRACTION_KERNELS_SOLUTION(kernels, NULL); 935 PS_ASSERT_FLOAT_WITHIN_RANGE(x, -1.0, 1.0, NULL); 936 PS_ASSERT_FLOAT_WITHIN_RANGE(y, -1.0, 1.0, NULL); 937 938 psKernel *kernel = pmSubtractionKernel(kernels, x, y, wantDual); // Convolution kernel 932 939 psImage *image = psMemIncrRefCounter(kernel->image); // Image of the kernel 933 940 psFree(kernel); … … 989 996 990 997 991 // XXX Put kernelImage, kernel Weightand polyValues on thread-dependent data998 // XXX Put kernelImage, kernelVariance and polyValues on thread-dependent data 992 999 static bool subtractionConvolvePatch(int numCols, int numRows, // Size of image 993 1000 int x0, int y0, // Offsets for image … … 1010 1017 1011 1018 psKernel *kernelImage = NULL; // Kernel for the images 1012 psKernel *kernel Weight = NULL; // Kernel for the weightmaps1019 psKernel *kernelVariance = NULL; // Kernel for the variance maps 1013 1020 1014 1021 // Only generate polynomial values every kernel footprint, since we have already assumed … … 1020 1027 1021 1028 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1022 convolveRegion(out1->image, out1-> weight, convMask, &kernelImage, &kernelWeight,1023 ro1->image, ro1-> weight, sys1, subMask, kernels, polyValues, background, *region,1029 convolveRegion(out1->image, out1->variance, convMask, &kernelImage, &kernelVariance, 1030 ro1->image, ro1->variance, sys1, subMask, kernels, polyValues, background, *region, 1024 1031 maskBad, maskPoor, poorFrac, useFFT, false); 1025 1032 } 1026 1033 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1027 convolveRegion(out2->image, out2-> weight, convMask, &kernelImage, &kernelWeight,1028 ro2->image, ro2-> weight, sys2, subMask, kernels, polyValues, background, *region,1034 convolveRegion(out2->image, out2->variance, convMask, &kernelImage, &kernelVariance, 1035 ro2->image, ro2->variance, sys2, subMask, kernels, polyValues, background, *region, 1029 1036 maskBad, maskPoor, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL); 1030 1037 } 1031 1038 1032 1039 psFree(kernelImage); 1033 psFree(kernel Weight);1040 psFree(kernelVariance); 1034 1041 psFree(polyValues); 1035 1042 … … 1148 1155 // XXX } 1149 1156 } 1150 if (ro1-> weight) {1151 if (!out1-> weight) {1152 out1-> weight= psImageAlloc(numCols, numRows, PS_TYPE_F32);1157 if (ro1->variance) { 1158 if (!out1->variance) { 1159 out1->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1153 1160 // XXX if (threaded) { 1154 // XXX psMutexInit(out1-> weight);1161 // XXX psMutexInit(out1->variance); 1155 1162 // XXX } 1156 1163 } 1157 psImageInit(out1-> weight, 0.0);1164 psImageInit(out1->variance, 0.0); 1158 1165 } 1159 1166 } … … 1165 1172 // XXX } 1166 1173 } 1167 if (ro2-> weight) {1168 if (!out2-> weight) {1169 out2-> weight= psImageAlloc(numCols, numRows, PS_TYPE_F32);1174 if (ro2->variance) { 1175 if (!out2->variance) { 1176 out2->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1170 1177 // XXX if (threaded) { 1171 // XXX psMutexInit(out2-> weight);1178 // XXX psMutexInit(out2->variance); 1172 1179 // XXX } 1173 1180 } 1174 psImageInit(out2-> weight, 0.0);1181 psImageInit(out2->variance, 0.0); 1175 1182 } 1176 1183 } … … 1232 1239 psImage *polyValues = NULL; // Pre-calculated polynomial values 1233 1240 psKernel *kernelImage = NULL; // Kernel for the images 1234 psKernel *kernel Weight = NULL; // Kernel for the weightmaps1241 psKernel *kernelVariance = NULL; // Kernel for the variance maps 1235 1242 #endif 1236 1243 … … 1299 1306 psFree(job); 1300 1307 } else { 1301 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, 1302 s ys1, sys2, subMask, maskBad, maskPoor, poorFrac, subRegion,1303 kernels, doBG,useFFT);1308 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, sys1, sys2, 1309 subMask, maskBad, maskPoor, poorFrac, subRegion, kernels, doBG, 1310 useFFT); 1304 1311 } 1305 1312 psFree(subRegion); … … 1334 1341 // XXX } 1335 1342 } 1336 1337 1343 psImageConvolveSetThreads(oldThreads); 1338 1344 1339 1345 psFree(sys1); 1340 1346 psFree(sys2); 1347 1348 // Calculate covariances 1349 // This can take a while, so we only do it for a single instance 1350 // XXX psImageCovarianceCalculate could be multithreaded 1351 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1352 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel 1353 out1->covariance = psImageCovarianceCalculate(kernel, ro1->covariance); 1354 psFree(kernel); 1355 } 1356 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1357 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, 1358 kernels->mode == PM_SUBTRACTION_MODE_DUAL); // Conv. kernel 1359 out2->covariance = psImageCovarianceCalculate(kernel, ro2->covariance); 1360 psFree(kernel); 1361 } 1341 1362 1342 1363 // Copy anything that wasn't convolved … … 1345 1366 if (out2) { 1346 1367 out2->image = psMemIncrRefCounter(ro2->image); 1347 out2-> weight = psMemIncrRefCounter(ro2->weight);1368 out2->variance = psMemIncrRefCounter(ro2->variance); 1348 1369 out2->mask = psMemIncrRefCounter(ro2->mask); 1370 out2->covariance = psMemIncrRefCounter(ro2->covariance); 1349 1371 } 1350 1372 break; … … 1352 1374 if (out1) { 1353 1375 out1->image = psMemIncrRefCounter(ro1->image); 1354 out1-> weight = psMemIncrRefCounter(ro1->weight);1376 out1->variance = psMemIncrRefCounter(ro1->variance); 1355 1377 out1->mask = psMemIncrRefCounter(ro1->mask); 1378 out1->covariance = psMemIncrRefCounter(ro1->covariance); 1356 1379 } 1357 1380 break;
Note:
See TracChangeset
for help on using the changeset viewer.
