IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 10, 2007, 1:54:26 PM (19 years ago)
Author:
Paul Price
Message:

Adding additional convolution kernels: SPAM (binned pixels around a central single-pixel core) and FRIES (binning changes as a (Fibonacci-like) function of radius).

File:
1 edited

Legend:

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

    r13390 r14106  
    1515    psFree(kernels->v);
    1616    psFree(kernels->sigma);
     17    psFree(kernels->uStop);
     18    psFree(kernels->vStop);
    1719    psFree(kernels->xOrder);
    1820    psFree(kernels->yOrder);
     
    4850    kernels->u = psVectorAlloc(numBasisFunctions, PS_TYPE_S32);
    4951    kernels->v = psVectorAlloc(numBasisFunctions, PS_TYPE_S32);
     52    kernels->sigma = NULL;
     53    kernels->uStop = NULL;
     54    kernels->vStop = NULL;
    5055    kernels->xOrder = psVectorAlloc(numBasisFunctions, PS_TYPE_S32);
    5156    kernels->yOrder = psVectorAlloc(numBasisFunctions, PS_TYPE_S32);
    52     kernels->sigma = NULL;
    5357    kernels->subIndex = 0;
    5458    kernels->preCalc = NULL;
     
    187191}
    188192
     193/// Generate SPAM kernels
     194pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, ///< Half-size of the kernel
     195                                               int spatialOrder, ///< Order of spatial variations
     196                                               int inner, ///< Inner radius to preserve unbinned
     197                                               int binning ///< Kernel binning factor
     198    )
     199{
     200    PS_ASSERT_INT_POSITIVE(size, NULL);
     201    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
     202    PS_ASSERT_INT_NONNEGATIVE(inner, NULL);
     203    PS_ASSERT_INT_LARGER_THAN(size, inner, NULL);
     204    PS_ASSERT_INT_POSITIVE(binning, NULL);
     205
     206    // The outer region should be divisible by the "binning"; otherwise allocate remainder to the inner region
     207    int numOuter = (size - inner) / binning; // Number of summed pixels in the outer region
     208    int numInner = inner + (size - inner) % binning; // Number of pixels in the inner region
     209    assert(numOuter * binning + numInner == size);
     210    int numTotal = numOuter + numInner; // Total number of summed pixels
     211
     212    psTrace("psModules.imcombine", 3, "Inner: %d Outer: %d\n", numInner, numOuter);
     213
     214    int num = PS_SQR(2 * numTotal + 1) *
     215        (spatialOrder + 1) * (spatialOrder + 2) / 2; // Number of basis functions
     216
     217    psTrace("psModules.imcombine", 3, "Number of basis functions: %d\n", num);
     218
     219    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_SPAM,
     220                                                              size, spatialOrder); // The kernels
     221
     222    kernels->uStop = psVectorAlloc(num, PS_TYPE_F32);
     223    kernels->vStop = psVectorAlloc(num, PS_TYPE_F32);
     224
     225    psVector *locations = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32); // Locations for each kernel element
     226    psVector *widths = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32); // Widths for each kernel element
     227    locations->data.S32[numTotal] = 0;
     228    widths->data.S32[numTotal] = 0;
     229    for (int i = 1; i <= numInner; i++) {
     230        locations->data.S32[numTotal + i] = i;
     231        widths->data.S32[numTotal + i] = 0;
     232        locations->data.S32[numTotal - i] = - i;
     233        widths->data.S32[numTotal - i] = 0;
     234    }
     235    for (int i = numInner + 1; i <= numTotal; i++) {
     236        locations->data.S32[numTotal + i] = locations->data.S32[numTotal + i - 1] +
     237            widths->data.S32[numTotal + i - 1] + 1;
     238        widths->data.S32[numTotal + i] = binning - 1;
     239        locations->data.S32[numTotal - i] = locations->data.S32[numTotal - i + 1] -
     240            widths->data.S32[numTotal - i + 1] - binning;
     241        widths->data.S32[numTotal - i] = binning - 1;
     242    }
     243
     244    if (psTraceGetLevel("psModules.imcombine") >= 10) {
     245        for (int i = 0; i < 2 * numTotal + 1; i++) {
     246            psTrace("psModules.imcombine", 10, "%d: %d -> %d\n", i, locations->data.S32[i],
     247                    locations->data.S32[i] + widths->data.S32[i]);
     248        }
     249    }
     250
     251    // Set the kernel parameters
     252    for (int i = - numTotal, index = 0; i <= numTotal; i++) {
     253        int u = locations->data.S32[numTotal + i]; // Location of pixel
     254        int uStop = u + widths->data.S32[numTotal + i]; // Width of pixel
     255
     256        for (int j = - numTotal; j <= numTotal; j++) {
     257            int v = locations->data.S32[numTotal + j]; // Location of pixel
     258            int vStop = v + widths->data.S32[numTotal + j]; // Width of pixel
     259
     260            // Iterate over spatial order.  This loop creates the terms for
     261            // x^xOrder * y^yOrder  such that (xOrder+yOrder) <= spatialOrder.
     262            for (int xOrder = 0; xOrder <= spatialOrder; xOrder++) {
     263                for (int yOrder = 0; yOrder <= spatialOrder - xOrder; yOrder++, index++) {
     264                    kernels->u->data.S32[index] = u;
     265                    kernels->v->data.S32[index] = v;
     266                    kernels->uStop->data.S32[index] = uStop;
     267                    kernels->vStop->data.S32[index] = vStop;
     268                    kernels->xOrder->data.S32[index] = xOrder;
     269                    kernels->yOrder->data.S32[index] = yOrder;
     270
     271                    psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d %d %d %d\n", index,
     272                            u, uStop, v, vStop, xOrder, yOrder);
     273                }
     274            }
     275        }
     276    }
     277
     278    kernels->subIndex = (num - (spatialOrder + 1) * (spatialOrder + 2) / 2) / 2;
     279    assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
     280           kernels->v->data.S32[kernels->subIndex] == 0 &&
     281           kernels->uStop->data.S32[kernels->subIndex] == 0 &&
     282           kernels->vStop->data.S32[kernels->subIndex] == 0 &&
     283           kernels->xOrder->data.S32[kernels->subIndex] == 0 &&
     284           kernels->yOrder->data.S32[kernels->subIndex] == 0);
     285
     286    psFree(locations);
     287    psFree(widths);
     288
     289    return kernels;
     290}
     291
     292
     293/// Generate FRIES kernels
     294pmSubtractionKernels *pmSubtractionKernelsFRIES(int size, ///< Half-size of the kernel
     295                                                int spatialOrder, ///< Order of spatial variations
     296                                                int inner ///< Inner radius to preserve unbinned
     297    )
     298{
     299    PS_ASSERT_INT_POSITIVE(size, NULL);
     300    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
     301    PS_ASSERT_INT_NONNEGATIVE(inner, NULL);
     302    PS_ASSERT_INT_LARGER_THAN(size, inner, NULL);
     303
     304    int fibNum = 0;                     // Number of Fibonacci values
     305    int fibLast = 1, fibTotal = 2;      // Fibonacci sequence
     306    while (fibTotal < size - inner) {
     307        int temp = fibTotal;
     308        fibTotal += fibLast;
     309        fibLast = temp;
     310        fibNum++;
     311    }
     312
     313    int numInner = inner;               // Number of pixels in the inner region
     314    int numOuter = fibNum;              // Number of summed pixels in the outer region
     315    int numTotal = numOuter + numInner; // Total number of summed pixels
     316
     317    psTrace("psModules.imcombine", 3, "Inner: %d Outer: %d\n", numInner, numOuter);
     318
     319    int num = PS_SQR(2 * numTotal + 1) *
     320        (spatialOrder + 1) * (spatialOrder + 2) / 2; // Number of basis functions
     321
     322    psTrace("psModules.imcombine", 3, "Number of basis functions: %d\n", num);
     323
     324    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_SPAM,
     325                                                              size, spatialOrder); // The kernels
     326    kernels->uStop = psVectorAlloc(num, PS_TYPE_F32);
     327    kernels->vStop = psVectorAlloc(num, PS_TYPE_F32);
     328
     329    psVector *start = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32);
     330    psVector *stop = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32);
     331    start->data.S32[numTotal] = 0;
     332    stop->data.S32[numTotal] = 0;
     333    for (int i = 1; i <= numInner; i++) {
     334        start->data.S32[numTotal + i] = i;
     335        stop->data.S32[numTotal + i] = i;
     336        start->data.S32[numTotal - i] = -i;
     337        stop->data.S32[numTotal - i] = -i;
     338    }
     339    for (int i = numInner + 1, fibLast = 1, fib = 2, temp; i <= numTotal;
     340         i++, fib = (temp = fib) + fibLast, fibLast = temp) {
     341        start->data.S32[numTotal + i] = stop->data.S32[numTotal + i - 1] + 1;
     342        stop->data.S32[numTotal + i] = PS_MIN(start->data.S32[numTotal + i] + fib - 1, size);
     343        start->data.S32[numTotal - i] = - stop->data.S32[numTotal + i];
     344        stop->data.S32[numTotal - i] = - start->data.S32[numTotal + i];
     345    }
     346
     347    if (psTraceGetLevel("psModules.imcombine") >= 10) {
     348        for (int i = 0; i < 2 * numTotal + 1; i++) {
     349            psTrace("psModules.imcombine", 10, "%d: %d -> %d\n", i, start->data.S32[i], stop->data.S32[i]);
     350        }
     351    }
     352
     353    // Set the kernel parameters
     354    for (int i = - numTotal, index = 0; i <= numTotal; i++) {
     355        int u = start->data.S32[numTotal + i]; // Location of pixel
     356        int uStop = stop->data.S32[numTotal + i]; // Width of pixel
     357        for (int j = - numTotal; j <= numTotal; j++) {
     358            int v = start->data.S32[numTotal + j]; // Location of pixel
     359            int vStop = stop->data.S32[numTotal + j]; // Width of pixel
     360
     361            // Iterate over spatial order.  This loop creates the terms for
     362            // x^xOrder * y^yOrder  such that (xOrder+yOrder) <= spatialOrder.
     363            for (int xOrder = 0; xOrder <= spatialOrder; xOrder++) {
     364                for (int yOrder = 0; yOrder <= spatialOrder - xOrder; yOrder++, index++) {
     365                    kernels->u->data.S32[index] = u;
     366                    kernels->v->data.S32[index] = v;
     367                    kernels->uStop->data.S32[index] = uStop;
     368                    kernels->vStop->data.S32[index] = vStop;
     369                    kernels->xOrder->data.S32[index] = xOrder;
     370                    kernels->yOrder->data.S32[index] = yOrder;
     371
     372                    psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d %d %d %d\n", index,
     373                            u, uStop, v, vStop, xOrder, yOrder);
     374                }
     375            }
     376        }
     377    }
     378
     379    kernels->subIndex = (num - (spatialOrder + 1) * (spatialOrder + 2) / 2) / 2;
     380    assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
     381           kernels->v->data.S32[kernels->subIndex] == 0 &&
     382           kernels->uStop->data.S32[kernels->subIndex] == 0 &&
     383           kernels->vStop->data.S32[kernels->subIndex] == 0 &&
     384           kernels->xOrder->data.S32[kernels->subIndex] == 0 &&
     385           kernels->yOrder->data.S32[kernels->subIndex] == 0);
     386
     387    psFree(start);
     388    psFree(stop);
     389
     390    return kernels;
     391}
     392
     393
    189394pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, int size, int spatialOrder,
    190                                                    const psVector *sigmas, const psVector *orders)
     395                                                   const psVector *sigmas, const psVector *orders, int inner,
     396                                                   int binning)
    191397{
    192398    switch (type) {
     
    195401      case PM_SUBTRACTION_KERNEL_ISIS:
    196402        return pmSubtractionKernelsISIS(size, spatialOrder, sigmas, orders);
     403      case PM_SUBTRACTION_KERNEL_SPAM:
     404        return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning);
     405      case PM_SUBTRACTION_KERNEL_FRIES:
     406        return pmSubtractionKernelsFRIES(size, spatialOrder, inner);
    197407      default:
    198408        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unknown kernel type: %x", type);
Note: See TracChangeset for help on using the changeset viewer.