Changeset 26473
- Timestamp:
- Dec 22, 2009, 9:55:18 AM (16 years ago)
- Location:
- branches/eam_branches/20091201/psModules/src/imcombine
- Files:
-
- 2 edited
-
pmSubtractionKernels.c (modified) (7 diffs)
-
pmSubtractionKernels.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionKernels.c
r26318 r26473 10 10 #include "pmSubtraction.h" 11 11 #include "pmSubtractionKernels.h" 12 #include "pmSubtractionHermitian.h" 12 13 13 14 #define RINGS_BUFFER 10 // Buffer size for RINGS data 14 15 15 16 16 // Free function for pmSubtractionKernels … … 57 57 for (int i = 0, x = -size; x <= size; i++, x++) { 58 58 kernel->data.F32[i] = norm * power(x, order) * expf(expNorm * PS_SQR(x)); 59 } 60 61 return kernel; 62 } 63 64 // Generate 1D convolution kernel for HERM (normalized for 2D) 65 static psVector *subtractionKernelHERM(float sigma, // Gaussian width 66 int order, // Polynomial order 67 int size // Kernel half-size 68 ) 69 { 70 int fullSize = 2 * size + 1; // Full size of kernel 71 psVector *kernel = psVectorAlloc(fullSize, PS_TYPE_F32); // Kernel to return 72 73 // for now, we are only allowing equal orders and sigmas in X and Y 74 float nf = exp(lgamma(order + 1)); 75 float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI)); 76 77 for (int i = 0, x = -size; x <= size; i++, x++) { 78 float xf = x / sigma; 79 float z = -0.25*xf*xf; 80 kernel->data.F32[i] = norm * p_pmSubtractionHermitianPolynomial(xf, order) * exp(z); 59 81 } 60 82 … … 189 211 190 212 #if 0 213 double sum = 0.0; // Sum of kernel component 214 for (int v = -size; v <= size; v++) { 215 for (int u = -size; u <= size; u++) { 216 sum += kernel->kernel[v][u]; 217 } 218 } 219 fprintf(stderr, "%d sum: %lf\n", index, sum); 220 #endif 221 222 kernels->widths->data.F32[index] = fwhms->data.F32[i]; 223 kernels->u->data.S32[index] = uOrder; 224 kernels->v->data.S32[index] = vOrder; 225 if (kernels->preCalc->data[index]) { 226 psFree(kernels->preCalc->data[index]); 227 } 228 kernels->preCalc->data[index] = preCalc; 229 kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment); 230 231 psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, 232 fwhms->data.F32[i], uOrder, vOrder, fabsf(moment)); 233 } 234 } 235 } 236 237 return kernels; 238 } 239 240 pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder, 241 const psVector *fwhmsIN, const psVector *ordersIN, 242 float penalty, pmSubtractionMode mode) 243 { 244 PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL); 245 PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL); 246 PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL); 247 PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL); 248 PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL); 249 PS_ASSERT_INT_POSITIVE(size, NULL); 250 PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL); 251 252 // check the requested fwhm values: any values <= 0.0 should be dropped 253 psVector *fwhms = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32); 254 psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32); 255 for (int i = 0; i < fwhmsIN->n; i++) { 256 if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue; 257 psVectorAppend(fwhms, fwhmsIN->data.F32[i]); 258 psVectorAppend(orders, ordersIN->data.S32[i]); 259 } 260 261 int numGaussians = fwhms->n; // Number of Gaussians 262 263 int num = 0; // Number of basis functions 264 psString params = NULL; // List of parameters 265 for (int i = 0; i < numGaussians; i++) { 266 int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian 267 psStringAppend(¶ms, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]); 268 num += (gaussOrder + 1) * (gaussOrder + 2) / 2; 269 } 270 271 pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_HERM, size, spatialOrder, penalty, mode); // The kernels 272 psStringAppend(&kernels->description, "HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty); 273 274 psLogMsg("psModules.imcombine", PS_LOG_INFO, "HERM kernel: %s,%d --> %d elements", params, spatialOrder, num); 275 psFree(params); 276 277 // Set the kernel parameters 278 int fullSize = 2 * size + 1; // Full size of kernels 279 for (int i = 0, index = 0; i < numGaussians; i++) { 280 float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma 281 // Iterate over (u,v) order 282 for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) { 283 for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) { 284 psArray *preCalc = psArrayAlloc(3); // Array to hold precalculated values 285 psVector *xKernel = preCalc->data[0] = subtractionKernelHERM(sigma, uOrder, size); // x Kernel 286 psVector *yKernel = preCalc->data[1] = subtractionKernelHERM(sigma, vOrder, size); // y Kernel 287 psKernel *kernel = preCalc->data[2] = psKernelAlloc(-size, size, -size, size); // Kernel 288 289 // Calculate moments 290 double moment = 0.0; // Moment, for penalty 291 for (int v = -size, y = 0; v <= size; v++, y++) { 292 for (int u = -size, x = 0; u <= size; u++, x++) { 293 double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel 294 kernel->kernel[v][u] = value; 295 moment += value * PS_SQR((PS_SQR(u) + PS_SQR(v))); 296 } 297 } 298 299 // Normalise sum of kernel component to unity for even functions 300 if (uOrder % 2 == 0 && vOrder % 2 == 0) { 301 double sum = 0.0; // Sum of kernel component 302 for (int v = 0; v < fullSize; v++) { 303 for (int u = 0; u < fullSize; u++) { 304 sum += xKernel->data.F32[u] * yKernel->data.F32[v]; 305 } 306 } 307 sum = 1.0 / sqrt(sum); 308 psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 309 psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 310 psBinaryOp(kernel->image, kernel->image, "*", psScalarAlloc(PS_SQR(sum), PS_TYPE_F32)); 311 312 #if 1 313 fprintf(stderr, "%d norm: %lf, null: %f\n", index, sum,kernel->kernel[0][0]); 314 #endif 315 316 kernel->kernel[0][0] -= 1.0; 317 moment *= PS_SQR(sum); 318 } 319 320 321 #if 1 191 322 double sum = 0.0; // Sum of kernel component 192 323 for (int v = -size; v <= size; v++) { … … 662 793 case PM_SUBTRACTION_KERNEL_ISIS: 663 794 return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode); 795 case PM_SUBTRACTION_KERNEL_HERM: 796 return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, mode); 664 797 case PM_SUBTRACTION_KERNEL_SPAM: 665 798 return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, mode); … … 724 857 float penalty = 0.0; // Penalty for wideness 725 858 726 if (strncmp(description, "ISIS", 4) == 0) { 727 // XXX Support for GUNK 859 // ISIS and HERM have the same description layout 860 if (!strncmp(description, "ISIS", 4) || !strcmp (description, "HERM")) { 861 // XXX Support for GUNK (not yet supported) 728 862 if (strstr(description, "+POIS")) { 729 863 type = PM_SUBTRACTION_KERNEL_GUNK; 730 864 psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description); 731 } else { 732 type = PM_SUBTRACTION_KERNEL_ISIS; 733 char *ptr = (char*)description + 5; // Eat "ISIS(" 734 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 735 736 // Count the number of Gaussians 737 int numGauss = 0; 738 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 739 numGauss++; 740 } 741 742 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 743 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 744 745 for (int i = 0; i < numGauss; i++) { 746 ptr++; // Eat the '(' 747 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 748 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 749 } 750 751 ptr++; // Eat ',' 752 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 753 penalty = parseStringFloat(ptr); 754 } 755 } else if (strncmp(description, "RINGS", 5) == 0) { 865 } 866 867 type = pmSubtractionKernelsTypeFromString (description); 868 psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must be ISIS or HERM"); 869 870 char *ptr = (char*)description + 5; // Eat "ISIS(" or "HERM(" 871 PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt); 872 873 // Count the number of Gaussians 874 int numGauss = 0; 875 for (char *string = ptr; string; string = strchr(string + 1, '(')) { 876 numGauss++; 877 } 878 879 fwhms = psVectorAlloc(numGauss, PS_TYPE_F32); 880 orders = psVectorAlloc(numGauss, PS_TYPE_S32); 881 882 for (int i = 0; i < numGauss; i++) { 883 ptr++; // Eat the '(' 884 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234," 885 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)" 886 } 887 888 ptr++; // Eat ',' 889 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 890 penalty = parseStringFloat(ptr); 891 892 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 893 } 894 895 if (strncmp(description, "RINGS", 5) == 0) { 756 896 type = PM_SUBTRACTION_KERNEL_RINGS; 757 897 char *ptr = (char*)description + 6; … … 761 901 PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt); 762 902 PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt); 763 } else { 764 psAbort("Deciphering kernels other than ISIS and RINGS is not currently supported.");765 } 766 903 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode); 904 } 905 906 psAbort("Deciphering kernels other than ISIS, HERM and RINGS is not currently supported."); 767 907 768 908 return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, … … 778 918 if (strcasecmp(type, "ISIS") == 0) { 779 919 return PM_SUBTRACTION_KERNEL_ISIS; 920 } 921 if (strcasecmp(type, "HERM") == 0) { 922 return PM_SUBTRACTION_KERNEL_HERM; 780 923 } 781 924 if (strcasecmp(type, "SPAM") == 0) { -
branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionKernels.h
r26157 r26473 10 10 PM_SUBTRACTION_KERNEL_POIS, ///< Pan-STARRS Optimal Image Subtraction --- delta functions 11 11 PM_SUBTRACTION_KERNEL_ISIS, ///< Traditional kernel --- gaussians modified by polynomials 12 PM_SUBTRACTION_KERNEL_HERM, ///< Hermitian polynomial kernels 12 13 PM_SUBTRACTION_KERNEL_SPAM, ///< Summed Pixels for Advanced Matching --- summed delta functions 13 14 PM_SUBTRACTION_KERNEL_FRIES, ///< Fibonacci Radius Increases Excellence of Subtraction … … 30 31 psString description; ///< Description of the kernel parameters 31 32 long num; ///< Number of kernel components (not including the spatial ones) 32 psVector *u, *v; ///< Offset (for POIS) or polynomial order (for ISIS )33 psVector *widths; ///< Gaussian FWHMs (ISIS )33 psVector *u, *v; ///< Offset (for POIS) or polynomial order (for ISIS or HERM) 34 psVector *widths; ///< Gaussian FWHMs (ISIS or HERM) 34 35 psVector *uStop, *vStop; ///< Width of kernel element (SPAM,FRIES only) 35 psArray *preCalc; ///< Array of images containing pre-calculated kernel (for ISIS )36 psArray *preCalc; ///< Array of images containing pre-calculated kernel (for ISIS or HERM) 36 37 float penalty; ///< Penalty for wideness 37 38 psVector *penalties; ///< Penalty for each kernel component … … 64 65 PS_ASSERT_VECTOR_SIZE((KERNELS)->widths, (KERNELS)->num, RETURNVALUE); \ 65 66 } \ 67 if ((KERNELS)->type == PM_SUBTRACTION_KERNEL_HERM) { \ 68 PS_ASSERT_VECTOR_NON_NULL((KERNELS)->widths, RETURNVALUE); \ 69 PS_ASSERT_VECTOR_TYPE((KERNELS)->widths, PS_TYPE_F32, RETURNVALUE); \ 70 PS_ASSERT_VECTOR_SIZE((KERNELS)->widths, (KERNELS)->num, RETURNVALUE); \ 71 } \ 66 72 if ((KERNELS)->uStop || (KERNELS)->vStop) { \ 67 73 PS_ASSERT_VECTOR_NON_NULL((KERNELS)->uStop, RETURNVALUE); \ … … 142 148 ); 143 149 150 /// Generate HERM kernels 151 pmSubtractionKernels *pmSubtractionKernelsHERM(int size, ///< Half-size of the kernel 152 int spatialOrder, ///< Order of spatial variations 153 const psVector *fwhms, ///< Gaussian FWHMs 154 const psVector *orders, ///< order of hermitian polynomials 155 float penalty, ///< Penalty for wideness 156 pmSubtractionMode mode ///< Mode for subtraction 157 ); 158 144 159 /// Generate SPAM kernels 145 160 pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, ///< Half-size of the kernel
Note:
See TracChangeset
for help on using the changeset viewer.
