IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 18, 2007, 3:39:28 PM (19 years ago)
Author:
Paul Price
Message:

Adding GUNK (Grid United with Normal Kernels --- a POIS/ISIS hybrid) kernels.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmSubtractionKernels.c

    r14199 r14305  
    5858    kernels->preCalc = NULL;
    5959    kernels->size = size;
     60    kernels->inner = 0;
    6061    kernels->spatialOrder = spatialOrder;
    6162
     
    141142                }
    142143
    143 #if 0
    144                 // Subtract a particular kernel in order to preserve photometric calibration across image
    145                 if (spatialOrder > 0 && index != kernels->subIndex) {
    146                     psKernel *subKernel = kernels->preCalc->data[kernels->subIndex]; // Kernel to subtract
    147                     (void)psBinaryOp(preCalc->image, preCalc->image, "-", subKernel->image);
    148                 }
    149 #endif
    150 
    151144                // Iterate over spatial order.  This loop creates the terms for
    152145                // x^xOrder * y^yOrder  such that (xOrder+yOrder) <= spatialOrder.
     
    390383}
    391384
     385// Grid United with Normal Kernel
     386pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *sigmas,
     387                                               const psVector *orders, int inner)
     388{
     389    PS_ASSERT_INT_POSITIVE(size, NULL);
     390    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
     391    PS_ASSERT_VECTOR_NON_NULL(sigmas, NULL);
     392    PS_ASSERT_VECTOR_TYPE(sigmas, PS_TYPE_F32, NULL);
     393    PS_ASSERT_VECTOR_NON_NULL(orders, NULL);
     394    PS_ASSERT_VECTOR_TYPE(orders, PS_TYPE_S32, NULL);
     395    PS_ASSERT_VECTORS_SIZE_EQUAL(sigmas, orders, NULL);
     396    PS_ASSERT_INT_NONNEGATIVE(inner, NULL);
     397    PS_ASSERT_INT_LESS_THAN(inner, size, NULL);
     398
     399    int numGaussians = sigmas->n;       // Number of Gaussians
     400    int numGaussianVars = 0;            // Number of Gaussian variant functions in the kernel
     401    for (int i = 0; i < numGaussians; i++) {
     402        int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian
     403        numGaussianVars += (gaussOrder + 1) * (gaussOrder + 2) / 2;
     404    }
     405
     406    int numInner = 2 * PS_SQR(inner) + 1; // Number of inner kernel elements
     407    int numSpatial = (spatialOrder + 1) * (spatialOrder + 2) / 2; // Number of spatial variations of a kernel
     408
     409    int num = (numGaussianVars + numInner) * numSpatial; // Total number of basis functions
     410
     411    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_GUNK,
     412                                                              size, spatialOrder); // The kernels
     413    kernels->preCalc = psArrayAlloc(numGaussianVars * numSpatial);
     414    kernels->inner = numGaussianVars * numSpatial;
     415
     416    // Set the Gaussian kernel parameters
     417    for (int i = 0, index = 0; i < numGaussians; i++) {
     418        // Iterate over (u,v) order
     419        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
     420            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++) {
     421
     422
     423                // Set the pre-calculated kernel
     424                psKernel *preCalc = psKernelAlloc(-size, size, -size, size);
     425                for (int v = -size; v <= size; v++) {
     426                    for (int u = -size; u <= size; u++) {
     427                        preCalc->kernel[v][u] = power(u, uOrder) * power(v, vOrder) *
     428                            expf(-0.5 * (PS_SQR(u) + PS_SQR(v)) / PS_SQR(sigmas->data.F32[i]));
     429                    }
     430                }
     431
     432                // Iterate over spatial order.  This loop creates the terms for
     433                // x^xOrder * y^yOrder  such that (xOrder+yOrder) <= spatialOrder.
     434                for (int xOrder = 0; xOrder <= spatialOrder; xOrder++) {
     435                    for (int yOrder = 0; yOrder <= spatialOrder - xOrder; yOrder++, index++) {
     436                        kernels->sigma->data.F32[index] = sigmas->data.F32[i];
     437                        kernels->u->data.S32[index] = uOrder;
     438                        kernels->v->data.S32[index] = vOrder;
     439                        kernels->xOrder->data.S32[index] = xOrder;
     440                        kernels->yOrder->data.S32[index] = yOrder;
     441                        kernels->preCalc->data[index] = psMemIncrRefCounter(preCalc);
     442
     443                        psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %d %d\n", index,
     444                                sigmas->data.F32[i], uOrder, vOrder, xOrder, yOrder);
     445                    }
     446                }
     447
     448                psFree(preCalc);        // Drop reference
     449            }
     450        }
     451    }
     452
     453
     454    // Generate a grid set of kernels for each (u,v)
     455    for (int v = - inner, index = kernels->inner; v <= inner; v++) {
     456        for (int u = - inner; u <= inner; u++) {
     457            // Iterate over spatial order.  This loop creates the terms for
     458            // x^xOrder * y^yOrder  such that (xOrder+yOrder) <= spatialOrder.
     459            for (int xOrder = 0; xOrder <= spatialOrder; xOrder++) {
     460                for (int yOrder = 0; yOrder <= spatialOrder - xOrder; yOrder++, index++) {
     461                    kernels->u->data.S32[index] = u;
     462                    kernels->v->data.S32[index] = v;
     463                    kernels->xOrder->data.S32[index] = xOrder;
     464                    kernels->yOrder->data.S32[index] = yOrder;
     465
     466                    psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d %d\n", index,
     467                            u, v, xOrder, yOrder);
     468                }
     469            }
     470        }
     471    }
     472
     473    kernels->subIndex = kernels->inner + numInner / 2;
     474    assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
     475           kernels->v->data.S32[kernels->subIndex] == 0 &&
     476           kernels->xOrder->data.S32[kernels->subIndex] == 0 &&
     477           kernels->yOrder->data.S32[kernels->subIndex] == 0);
     478
     479    if (psTraceGetLevel("psModules.imcombine.kernel") >= 10) {
     480        for (int i = 0; i < num; i++) {
     481            psKernel *kernel = kernels->preCalc->data[i]; // Kernel of interest
     482            psString kernelName = NULL;
     483            psStringAppend(&kernelName, "kernel%03d.fits", i);
     484            psFits *kernelFile = psFitsOpen(kernelName, "w");
     485            psFree(kernelName);
     486            psFitsWriteImage(kernelFile, NULL, kernel->image, 0, NULL);
     487            psFitsClose(kernelFile);
     488        }
     489    }
     490
     491    return kernels;
     492}
    392493
    393494pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, int size, int spatialOrder,
     
    404505      case PM_SUBTRACTION_KERNEL_FRIES:
    405506        return pmSubtractionKernelsFRIES(size, spatialOrder, inner);
     507      case PM_SUBTRACTION_KERNEL_GUNK:
     508        return pmSubtractionKernelsGUNK(size, spatialOrder, sigmas, orders, inner);
    406509      default:
    407510        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unknown kernel type: %x", type);
Note: See TracChangeset for help on using the changeset viewer.