Changeset 19765
- Timestamp:
- Sep 26, 2008, 4:03:24 PM (18 years ago)
- Location:
- trunk/psModules/src/imcombine
- Files:
-
- 4 edited
-
pmSubtraction.c (modified) (20 diffs)
-
pmSubtractionEquation.c (modified) (5 diffs)
-
pmSubtractionKernels.c (modified) (3 diffs)
-
pmSubtractionThreads.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtraction.c
r19540 r19765 30 30 #define MIN_SAMPLE_STATS 7 // Minimum number to use sample statistics; otherwise use quartiles 31 31 32 #define SYS_ERROR 0.05 // Relative error in derived convolution kernel pixels 32 33 33 34 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 135 136 } 136 137 case PM_SUBTRACTION_KERNEL_ISIS: { 137 psKernel *preCalc = kernels->preCalc->data[i]; // Precalculated values 138 psArray *preCalc = kernels->preCalc->data[i]; // Precalculated values 139 psVector *xKernel = preCalc->data[0]; // Kernel in x 140 psVector *yKernel = preCalc->data[1]; // Kernel in y 138 141 // Iterating over the kernel 139 for (int v = -size; v <= size; v++) { 140 for (int u = -size; u <= size; u++) { 141 kernel->kernel[v][u] += preCalc->kernel[v][u] * value; 142 // Photometric scaling is built into the preCalc kernel --- no subtraction! 142 for (int y = 0, v = -size; v <= size; y++, v++) { 143 for (int x = 0, u = -size; u <= size; x++, u++) { 144 kernel->kernel[v][u] += value * xKernel->data.F32[x] * yKernel->data.F32[y]; 143 145 } 146 } 147 // Photometric scaling for even kernels only 148 if (kernels->u->data.S32[i] % 2 == 0 && kernels->v->data.S32[i] % 2 == 0) { 149 kernel->kernel[0][0] -= value; 144 150 } 145 151 break; … … 200 206 } 201 207 208 // Take a subset of an image 209 static inline psImage *convolveSubsetAlloc(psImage *image, // Image to be convolved 210 psRegion region, // Region of interest (with border) 211 bool threaded // Are we running threaded? 212 ) 213 { 214 if (!image) { 215 return NULL; 216 } 217 if (threaded) { 218 psMutexLock(image); 219 } 220 psImage *subset = psImageSubset(image, region); // Subset image, to return 221 if (threaded) { 222 psMutexUnlock(image); 223 } 224 return subset; 225 } 226 227 // Free the subset of an image 228 static inline void convolveSubsetFree(psImage *parent, // Parent image 229 psImage *child, // Child (subset) image 230 bool threaded // Are we running threaded? 231 ) 232 { 233 if (!child || !parent) { 234 return; 235 } 236 if (threaded) { 237 psMutexLock(parent); 238 } 239 psFree(child); 240 if (threaded) { 241 psMutexUnlock(parent); 242 } 243 return; 244 } 202 245 203 246 // Convolve an image using FFT … … 217 260 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 218 261 219 if (threaded) { 220 psMutexLock(image); 221 } 222 psImage *subImage = psImageSubset(image, border); // Subimage to convolve 223 if (threaded) { 224 psMutexUnlock(image); 225 } 226 227 psImage *subMask; // Subimage mask 228 if (mask) { 229 if (threaded) { 230 psMutexLock(mask); 231 } 232 subMask = psImageSubset(mask, border); 233 if (threaded) { 234 psMutexUnlock(mask); 235 } 236 } else { 237 subMask = NULL; 238 } 262 psImage *subImage = convolveSubsetAlloc(image, border, threaded); // Subimage to convolve 263 psImage *subMask = convolveSubsetAlloc(mask, border, threaded); // Subimage mask 239 264 240 265 psImage *convolved = psImageConvolveFFT(NULL, subImage, subMask, maskVal, kernel); // Convolution 241 266 242 if (threaded) { 243 psMutexLock(image); 244 } 245 psFree(subImage); 246 if (threaded) { 247 psMutexUnlock(image); 248 } 249 250 if (mask) { 251 if (threaded) { 252 psMutexLock(mask); 253 } 254 psFree(subMask); 255 if (threaded) { 256 psMutexUnlock(mask); 257 } 258 } 267 convolveSubsetFree(image, subImage, threaded); 268 convolveSubsetFree(mask, subMask, threaded); 259 269 260 270 // Now, we have to stick it in where it belongs … … 276 286 return; 277 287 } 288 289 290 // Convolve an image using FFT 291 static void convolveWeightFFT(psImage *target,// Place the result in here 292 psImage *weight, // Weight map to convolve 293 psImage *sys, // Systematic error image 294 psImage *mask, // Mask image 295 psMaskType maskVal, // Value to mask 296 const psKernel *kernel, // Kernel by which to convolve 297 psRegion region,// Region of interest 298 int size // Size of (square) kernel 299 ) 300 { 301 psRegion border = psRegionSet(region.x0 - size, region.x1 + size, 302 region.y0 - size, region.y1 + size); // Add a border 303 304 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 305 306 psImage *subWeight = convolveSubsetAlloc(weight, border, threaded); // Weight map 307 psImage *subSys = convolveSubsetAlloc(sys, border, threaded); // Systematic error image 308 psImage *subMask = convolveSubsetAlloc(mask, border, threaded); // Mask 309 310 // XXX Can trim this a little by combining the convolution: only have to take the FFT of the kernel once 311 psImage *convWeight = psImageConvolveFFT(NULL, subWeight, subMask, maskVal, kernel); // Convolved weight 312 psImage *convSys = subSys ? psImageConvolveFFT(NULL, subSys, subMask, maskVal, kernel) : NULL; // Conv sys 313 314 convolveSubsetFree(weight, subWeight, threaded); 315 convolveSubsetFree(sys, subSys, threaded); 316 convolveSubsetFree(mask, subMask, threaded); 317 318 // Now, we have to stick it in where it belongs 319 int xMin = region.x0, xMax = region.x1, yMin = region.y0, yMax = region.y1; // Bounds of region 320 if (convSys) { 321 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 322 for (int xTarget = xMin, xSource = size; xTarget < xMax; xTarget++, xSource++) { 323 target->data.F32[yTarget][xTarget] = convWeight->data.F32[ySource][xSource] + 324 convSys->data.F32[ySource][xSource]; 325 } 326 } 327 } else { 328 int numBytes = (xMax - xMin) * PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy 329 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 330 memcpy(&target->data.F32[yTarget][xMin], &convWeight->data.F32[ySource][size], numBytes); 331 } 332 } 333 334 psFree(convWeight); 335 psFree(convSys); 336 337 return; 338 } 339 278 340 279 341 // Convolve an image directly … … 307 369 psImage *image, // Image to convolve 308 370 psImage *weight, // Weight map to convolve, or NULL 371 psImage *sys, // Systematic error image, or NULL 309 372 psImage *subMask, // Subtraction mask 310 373 const pmSubtractionKernels *kernels, // Kernels … … 343 406 convolveFFT(convImage, image, subMask, subBad, *kernelImage, region, background, kernels->size); 344 407 if (weight) { 345 convolve FFT(convWeight, weight, subMask, subBad, *kernelWeight, region, 0.0, kernels->size);408 convolveWeightFFT(convWeight, weight, sys, subMask, subBad, *kernelWeight, region, kernels->size); 346 409 } 347 410 } else { … … 361 424 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 362 425 363 if (threaded) { 364 psMutexLock(subMask); 365 } 366 psImage *image = psImageSubset(subMask, psRegionSet(colMin - box, colMax + box, 367 rowMin - box, rowMax + box)); // Mask 368 if (threaded) { 369 psMutexUnlock(subMask); 370 } 426 psRegion region = psRegionSet(colMin - box, colMax + box, 427 rowMin - box, rowMax + box); // Region to convolve 428 429 psImage *image = convolveSubsetAlloc(subMask, region, threaded); // Mask to convolve 371 430 372 431 psImage *convolved = psImageConvolveMask(NULL, image, subBad, subConvBad, 373 432 -box, box, -box, box); // Convolved subtraction mask 374 433 375 if (threaded) { 376 psMutexLock(subMask); 377 } 378 psFree(image); 379 if (threaded) { 380 psMutexUnlock(subMask); 381 } 434 convolveSubsetFree(subMask, image, threaded); 382 435 383 436 psAssert(convolved->numCols - 2 * box == colMax - colMin, "Bad number of columns"); … … 405 458 } 406 459 407 460 // Generate an image that can be used to track systematic errors 461 static psImage *subtractionSysErrImage(const psImage *image // Image from which to make sys err image 462 ) 463 { 464 int numCols = image->numCols, numRows = image->numRows; // Size of image 465 psImage *sys = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Systematic error image 466 467 for (int y = 0; y < numRows; y++) { 468 for (int x = 0; x < numCols; x++) { 469 sys->data.F32[y][x] = PS_SQR(image->data.F32[y][x]) * PS_SQR(SYS_ERROR); 470 } 471 } 472 473 return sys; 474 } 408 475 409 476 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 575 642 } 576 643 case PM_SUBTRACTION_KERNEL_ISIS: { 644 psArray *preCalc = kernels->preCalc->data[index]; // Precalculated values 645 psVector *xKernel = preCalc->data[0]; // Kernel in x 646 psVector *yKernel = preCalc->data[1]; // Kernel in y 647 int size = kernels->size; // Size of kernel 648 649 // Convolve in x 650 // Need to convolve a bit more than the footprint, for the y convolution 651 int yMin = -size - footprint, yMax = size + footprint; // Range for y 652 psKernel *temp = psKernelAlloc(yMin, yMax, 653 -footprint, footprint); // Temporary convolution; NOTE: wrong way! 654 for (int y = yMin; y <= yMax; y++) { 655 for (int x = -footprint; x <= footprint; x++) { 656 float value = 0.0; // Value of convolved pixel 657 int uMin = x - size, uMax = x + size; // Range for u 658 psF32 *xKernelData = xKernel->data.F32; // Kernel values 659 psF32 *imageData = &image->kernel[y][uMin]; // Image values 660 for (int u = uMin; u <= uMax; u++, xKernelData++, imageData++) { 661 value += *xKernelData * *imageData; 662 } 663 temp->kernel[x][y] = value; // NOTE: putting in wrong way! 664 } 665 } 666 667 // Convolve in y 668 psKernel *convolved = psKernelAlloc(-footprint, footprint, -footprint, footprint);// Convolved image 669 for (int x = -footprint; x <= footprint; x++) { 670 for (int y = -footprint; y <= footprint; y++) { 671 float value = 0.0; // Value of convolved pixel 672 int vMin = y - size, vMax = y + size; // Range for v 673 psF32 *yKernelData = yKernel->data.F32; // Kernel values 674 psF32 *imageData = &temp->kernel[x][vMin]; // Image values; NOTE: wrong way! 675 for (int v = vMin; v <= vMax; v++, yKernelData++, imageData++) { 676 value += *yKernelData * *imageData; 677 } 678 convolved->kernel[y][x] = value; 679 } 680 } 681 psFree(temp); 682 683 // Photometric scaling for even kernels only 684 if (kernels->u->data.S32[index] % 2 == 0 && kernels->v->data.S32[index] % 2 == 0) { 685 convolveSub(convolved, image, footprint); 686 } 687 return convolved; 688 #if 0 577 689 // Photometric scaling is already built in to the precalculated kernel 578 690 return p_pmSubtractionConvolveStampPrecalc(image, kernels->preCalc->data[index]); 691 #endif 579 692 } 580 693 case PM_SUBTRACTION_KERNEL_RINGS: { … … 889 1002 psImage *convMask, // Output convolved mask 890 1003 const pmReadout *ro1, const pmReadout *ro2, // Input readouts 1004 psImage *sys1, psImage *sys2, // Systematic error images 891 1005 psImage *subMask, // Input subtraction mask 892 1006 psMaskType maskBad, // Mask value to give bad pixels … … 914 1028 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 915 1029 convolveRegion(out1->image, out1->weight, convMask, &kernelImage, &kernelWeight, 916 ro1->image, ro1->weight, s ubMask, kernels, polyValues, background, *region,1030 ro1->image, ro1->weight, sys1, subMask, kernels, polyValues, background, *region, 917 1031 maskBad, maskPoor, poorFrac, useFFT, false); 918 1032 } 919 1033 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 920 1034 convolveRegion(out2->image, out2->weight, convMask, &kernelImage, &kernelWeight, 921 ro2->image, ro2->weight, s ubMask, kernels, polyValues, background, *region,1035 ro2->image, ro2->weight, sys2, subMask, kernels, polyValues, background, *region, 922 1036 maskBad, maskPoor, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL); 923 1037 } … … 965 1079 const pmReadout *ro1 = args->data[7]; // Input readout 1 966 1080 const pmReadout *ro2 = args->data[8]; // Input readout 2 967 psImage *subMask = args->data[9]; // Subtraction mask 968 psMaskType maskBad = PS_SCALAR_VALUE(args->data[10], U8); // Output mask value for bad pixels 969 psMaskType maskPoor = PS_SCALAR_VALUE(args->data[11], U8); // Output mask value for poor pixels 970 float poorFrac = PS_SCALAR_VALUE(args->data[12], F32); // Fraction for "poor" 971 const psRegion *region = args->data[13]; // Region to convolve 972 const pmSubtractionKernels *kernels = args->data[14]; // Kernels 973 bool doBG = PS_SCALAR_VALUE(args->data[15], U8); // Do background subtraction? 974 bool useFFT = PS_SCALAR_VALUE(args->data[16], U8); // Use FFT for convolution? 975 976 return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, subMask, 977 maskBad, maskPoor, poorFrac, region, kernels, doBG, useFFT); 1081 psImage *sys1 = args->data[9]; // Systematic error image 1 1082 psImage *sys2 = args->data[10]; // Systematic error image 2 1083 psImage *subMask = args->data[11]; // Subtraction mask 1084 psMaskType maskBad = PS_SCALAR_VALUE(args->data[12], U8); // Output mask value for bad pixels 1085 psMaskType maskPoor = PS_SCALAR_VALUE(args->data[13], U8); // Output mask value for poor pixels 1086 float poorFrac = PS_SCALAR_VALUE(args->data[14], F32); // Fraction for "poor" 1087 const psRegion *region = args->data[15]; // Region to convolve 1088 const pmSubtractionKernels *kernels = args->data[16]; // Kernels 1089 bool doBG = PS_SCALAR_VALUE(args->data[17], U8); // Do background subtraction? 1090 bool useFFT = PS_SCALAR_VALUE(args->data[18], U8); // Use FFT for convolution? 1091 1092 return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, sys1, sys2, 1093 subMask, maskBad, maskPoor, poorFrac, region, kernels, doBG, useFFT); 978 1094 } 979 1095 … … 1022 1138 } 1023 1139 1024 // Inputs1025 psImage *image1 = NULL, *weight1 = NULL; // Image and weight map from input 11026 if (ro1) {1027 image1 = ro1->image;1028 weight1 = ro1->weight;1029 }1030 psImage *image2 = NULL, *weight2 = NULL; // Image and weight map from input 21031 if (ro2) {1032 image2 = ro2->image;1033 weight2 = ro2->weight;1034 }1035 1036 1140 bool threaded = pmSubtractionThreaded(); // Running threaded? 1037 1141 1038 1142 // Outputs 1039 psImage *convImage1 = NULL, *convWeight1 = NULL; // Convolved image and weight from input 11040 1143 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1041 convImage1 = out1->image; 1042 if (!convImage1) { 1043 convImage1 = out1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1144 if (!out1->image) { 1145 out1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1044 1146 if (threaded) { 1045 psMutexInit( convImage1);1147 psMutexInit(out1->image); 1046 1148 } 1047 1149 } 1048 if ( weight1) {1150 if (ro1->weight) { 1049 1151 if (!out1->weight) { 1050 1152 out1->weight = psImageAlloc(numCols, numRows, PS_TYPE_F32); … … 1053 1155 } 1054 1156 } 1055 convWeight1 = out1->weight; 1056 psImageInit(convWeight1, 0.0); 1057 } 1058 } 1059 psImage *convImage2 = NULL, *convWeight2 = NULL; // Convolved image and weight from input 2 1157 psImageInit(out1->weight, 0.0); 1158 } 1159 } 1060 1160 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1061 convImage2 = out2->image; 1062 if (!convImage2) { 1063 convImage2 = out2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1161 if (!out2->image) { 1162 out2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 1064 1163 if (threaded) { 1065 psMutexInit( convImage2);1164 psMutexInit(out2->image); 1066 1165 } 1067 1166 } 1068 if ( weight2) {1167 if (ro2->weight) { 1069 1168 if (!out2->weight) { 1070 1169 out2->weight = psImageAlloc(numCols, numRows, PS_TYPE_F32); … … 1073 1172 } 1074 1173 } 1075 convWeight2 = out2->weight; 1076 psImageInit(convWeight2, 0.0); 1174 psImageInit(out2->weight, 0.0); 1077 1175 } 1078 1176 } … … 1104 1202 } 1105 1203 1204 psImage *sys1 = NULL, *sys2 = NULL; // Systematic error images 1205 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1206 sys1 = subtractionSysErrImage(ro1->image); 1207 if (threaded) { 1208 psMutexInit(sys1); 1209 } 1210 } 1211 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 1212 sys2 = subtractionSysErrImage(ro2->image); 1213 if (threaded) { 1214 psMutexInit(sys2); 1215 } 1216 } 1106 1217 1107 1218 int size = kernels->size; // Half-size of kernel … … 1144 1255 psArrayAdd(args, 1, (pmReadout*)ro2); // Casting away const 1145 1256 // Since adding to the array can impact the reference count, we need to lock 1257 if (sys1) { 1258 psMutexLock(sys1); 1259 } 1260 psArrayAdd(args, 1, sys1); 1261 if (sys1) { 1262 psMutexUnlock(sys1); 1263 } 1264 if (sys2) { 1265 psMutexLock(sys2); 1266 } 1267 psArrayAdd(args, 1, sys2); 1268 if (sys2) { 1269 psMutexUnlock(sys2); 1270 } 1146 1271 if (subMask) { 1147 1272 psMutexLock(subMask); … … 1165 1290 psFree(job); 1166 1291 } else { 1167 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, subMask, 1168 maskBad, maskPoor, poorFrac, subRegion, kernels, doBG, useFFT); 1292 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, 1293 sys1, sys2, subMask, maskBad, maskPoor, poorFrac, subRegion, 1294 kernels, doBG, useFFT); 1169 1295 } 1170 1296 psFree(subRegion); … … 1190 1316 psMutexDestroy(subMask); 1191 1317 } 1318 if (sys1) { 1319 psMutexDestroy(sys1); 1320 } 1321 if (sys2) { 1322 psMutexDestroy(sys2); 1323 } 1192 1324 } 1193 1325 -
trunk/psModules/src/imcombine/pmSubtractionEquation.c
r19532 r19765 758 758 calculatePenalty(sumVector, kernels); 759 759 760 #ifdef TESTING 761 { 762 psImage *inverse = psMatrixInvert(NULL, sumMatrix, NULL); 763 psFits *fits = psFitsOpen("matrixInv.fits", "w"); 764 psFitsWriteImage(fits, NULL, inverse, 0, NULL); 765 psFitsClose(fits); 766 psFree(inverse); 767 } 768 { 769 psImage *X = psMatrixInvert(NULL, sumMatrix, NULL); 770 psImage *Xt = psMatrixTranspose(NULL, X); 771 psImage *XtX = psMatrixMultiply(NULL, Xt, X); 772 psFits *fits = psFitsOpen("matrixErr.fits", "w"); 773 psFitsWriteImage(fits, NULL, XtX, 0, NULL); 774 psFitsClose(fits); 775 psFree(X); 776 psFree(Xt); 777 psFree(XtX); 778 } 779 #endif 780 760 781 psVector *permutation = NULL; // Permutation vector, required for LU decomposition 761 782 psImage *luMatrix = psMatrixLUD(NULL, &permutation, sumMatrix); … … 769 790 } 770 791 kernels->solution1 = psMatrixLUSolve(kernels->solution1, luMatrix, sumVector, permutation); 792 771 793 psFree(sumVector); 772 794 psFree(luMatrix); … … 806 828 calculatePenalty(sumVector2, kernels); 807 829 808 #if 0809 // Apply weighting to maximise the difference between solution coefficients for the same functions810 double fudge = PS_SQR(2 * stamps->footprint + 1); // Fudge factor811 for (int i = 0; i < kernels->num; i++) {812 sumMatrix1->data.F64[i][i] -= fudge;813 sumMatrix2->data.F64[i][i] += fudge;814 }815 #endif816 817 830 // Pure matrix operations 818 831 … … 941 954 #endif 942 955 956 #ifdef TESTING 943 957 { 944 958 psFits *fits = psFitsOpen("sumMatrix1.fits", "w"); … … 961 975 psFitsClose(fits); 962 976 } 963 977 #endif 964 978 965 979 kernels->solution1 = a; -
trunk/psModules/src/imcombine/pmSubtractionKernels.c
r19209 r19765 42 42 } 43 43 return result; 44 } 45 46 // Generate 1D convolution kernel for ISIS 47 static psVector *subtractionKernelISIS(float sigma, // Gaussian width 48 int order, // Polynomial order 49 int size // Kernel half-size 50 ) 51 { 52 int fullSize = 2 * size + 1; // Full size of kernel 53 psVector *kernel = psVectorAlloc(fullSize, PS_TYPE_F32); // Kernel to return 54 55 float expNorm = -0.5 / PS_SQR(sigma); // Normalisation for exponential 56 float norm = 1.0 / (M_2_PI * sqrtf(sigma)); // Normalisation for Gaussian 57 for (int i = 0, x = -size; x <= size; i++, x++) { 58 kernel->data.F32[i] = norm * power(x, order) * expf(expNorm * PS_SQR(x)); 59 } 60 61 return kernel; 44 62 } 45 63 … … 116 134 117 135 // Set the kernel parameters 136 int fullSize = 2 * size + 1; // Full size of kernels 118 137 for (int i = 0, index = 0; i < numGaussians; i++) { 119 138 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 120 float norm = 1.0 / (M_2_PI * sqrtf(sigma)); // Normalisation for Gaussian121 139 // Iterate over (u,v) order 122 140 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 123 141 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 124 // Set the pre-calculated kernel 125 psKernel *preCalc = psKernelAlloc(-size, size, -size, size); 126 double sum = 0.0; // Normalisation 142 psArray *preCalc = psArrayAlloc(2); // Array to hold precalculated values 143 psVector *xKernel = preCalc->data[0] = subtractionKernelISIS(sigma, uOrder, size); // x Kernel 144 psVector *yKernel = preCalc->data[1] = subtractionKernelISIS(sigma, vOrder, size); // y Kernel 145 146 // Calculate moments 147 double sum = 0.0; // Sum of kernel component, for normalisation 127 148 double moment = 0.0; // Moment, for penalty 128 for (int v = -size ; v <= size; v++) {129 for (int u = -size ; u <= size; u++) {130 sum += preCalc->kernel[v][u] = norm * power(u, uOrder) * power(v, vOrder) *131 expf(-0.5 * (PS_SQR(u) + PS_SQR(v)) / PS_SQR(sigma));132 moment += preCalc->kernel[v][u]* (PS_SQR(u) + PS_SQR(v));149 for (int v = -size, y = 0; v <= size; v++, y++) { 150 for (int u = -size, x = 0; u <= size; u++, x++) { 151 double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel 152 sum += value; 153 moment += value * (PS_SQR(u) + PS_SQR(v)); 133 154 } 134 155 } 156 moment = 0.0; 135 157 136 158 // Normalise sum of kernel component to unity for even functions 137 159 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 138 for (int v = -size; v <= size; v++) { 139 for (int u = -size; u <= size; u++) { 140 preCalc->kernel[v][u] = preCalc->kernel[v][u] / sum; 160 double sum = 0.0; // Sum of kernel component 161 for (int v = 0; v < fullSize; v++) { 162 for (int u = 0; u < fullSize; u++) { 163 sum += xKernel->data.F32[u] * yKernel->data.F32[v]; 141 164 } 142 165 } 143 preCalc->kernel[0][0] -= 1.0; 166 sum = 1.0 / sum; 167 psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 168 psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 169 moment *= sum; 144 170 } 145 171 … … 702 728 // Count the number of Gaussians 703 729 int numGauss = 0; 704 for (char *string = ptr; string; string = strchr(string , '(')) {730 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 705 731 numGauss++; 706 732 } -
trunk/psModules/src/imcombine/pmSubtractionThreads.c
r19340 r19765 76 76 77 77 { 78 psThreadTask *task = psThreadTaskAlloc("PSMODULES_SUBTRACTION_CONVOLVE", 1 7);78 psThreadTask *task = psThreadTaskAlloc("PSMODULES_SUBTRACTION_CONVOLVE", 19); 79 79 task->function = &pmSubtractionConvolveThread; 80 80 psThreadTaskAdd(task);
Note:
See TracChangeset
for help on using the changeset viewer.
