IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 14, 2007, 4:55:05 PM (19 years ago)
Author:
Paul Price
Message:

Convolution optimisation, mostly for ISIS kernels.

File:
1 edited

Legend:

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

    r13379 r13380  
    44 *  @author GLG, MHPCC
    55 *
    6  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2007-05-15 01:23:19 $
     6 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2007-05-15 02:55:05 $
    88 *
    99 *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    5151
    5252    return polyValues;
     53}
     54
     55// Generate an image of the solved kernel
     56static psKernel *solvedKernel(psKernel *kernel, // Kernel, to return
     57                              const psVector *solution, // Solution to the least-squares problem
     58                              const pmSubtractionKernels *kernels, // Kernel basis functions
     59                              const psImage *polyValues, // Spatial polynomial values
     60                              float (*weightFunc)(float value) // Function for weighting
     61    )
     62{
     63    int numKernels = solution->n - 1;   // Number of kernel basis functions
     64    assert(kernels->u->n == numKernels);
     65    assert(kernels->v->n == numKernels);
     66    assert(kernels->xOrder->n == numKernels);
     67    assert(kernels->yOrder->n == numKernels);
     68
     69    int size = kernels->size;           // Kernel half-size
     70    if (!kernel) {
     71        kernel = psKernelAlloc(-size, size, -size, size);
     72    }
     73    psImageInit(kernel->image, 0.0);
     74
     75    for (int i = 0; i < numKernels; i++) {
     76        int xOrder = kernels->xOrder->data.S32[i]; // Polynomial order in x
     77        int yOrder = kernels->yOrder->data.S32[i]; // Polynomial order in y
     78        double polyValue = polyValues->data.F64[yOrder][xOrder]; // Value of spatial polynomial
     79        switch (kernels->type) {
     80          case PM_SUBTRACTION_KERNEL_POIS: {
     81              int u = kernels->u->data.S32[i]; // Offset in x
     82              int v = kernels->v->data.S32[i]; // Offset in y
     83              kernel->kernel[v][u] += weightFunc(polyValue * solution->data.F64[i]);
     84              break;
     85          }
     86          case PM_SUBTRACTION_KERNEL_ISIS: {
     87              psKernel *preCalc = kernels->preCalc->data[i];// Precalculated values
     88              for (int v = -size; v <= size; v++) {
     89                  for (int u = -size; u <= size; u++) {
     90                      kernel->kernel[v][u] += weightFunc(polyValue * preCalc->kernel[v][u]);
     91                  }
     92              }
     93              break;
     94          }
     95          default:
     96            psAbort("Should never get here.");
     97        }
     98    }
     99
     100    return kernel;
    53101}
    54102
     
    463511    }
    464512
    465     int numKernels = kernels->u->n;     // Number of kernel basis functions
    466     int size = kernels->size;           // Size of kernel
    467 
    468     // We could simply sum the kernel basis functions, but convolving a delta function gives a more 'real'
    469     // picture of what's actually happening in the convolution, and the speed difference can't be too large,
    470     // since the image is small.
    471 
    472     psImage *image = psImageAlloc(2 * size + 1, 2 * size + 1, PS_TYPE_F32); // Output image
    473     psImageInit(image, 0.0);
    474     psImage *reference = psImageAlloc(4 * size + 1, 4 * size + 1, PS_TYPE_F32); // Reference image
    475     psImageInit(reference, 0.0);
    476     reference->data.F32[2 * size][2 * size] = 1.0;
    477 
    478513    // Precalulate polynomial values
    479514    psImage *polyValues = spatialPolyValues(kernels->spatialOrder, x, y);
    480515
    481     for (int j = -size; j <= size; j++) {
    482         for (int i = -size; i <= size; i++) {
    483             for (int k = 0; k < numKernels; k++) {
    484                 image->data.F32[j + size][i + size] += solution->data.F64[k] *
    485                     convolvePixel(kernels, k, 2 * size + i, 2 * size + j,
    486                                   reference, polyValues, imageWeighting);
    487             }
    488         }
    489     }
     516    // The appropriate kernel
     517    psKernel *kernel = solvedKernel(NULL, solution, kernels, polyValues, imageWeighting);
    490518
    491519    psFree(polyValues);
     520
     521    psImage *image = psMemIncrRefCounter(kernel->image); // Image of the kernel
     522    psFree(kernel);
    492523
    493524    return image;
     
    541572    }
    542573
    543     int numKernels = kernels->u->n;     // Number of kernel basis functions
    544574    int size = kernels->size;           // Half-size of kernel
    545575    float background = solution->data.F64[solution->n-1]; // The difference in background
     
    570600    psImage *polyValues = NULL;         // Pre-calculated polynomial values
    571601    int fullSize = 2 * size + 1;        // Full size of kernel
     602
     603    psKernel *kernelImage = NULL;       // Kernel for the image
     604    psKernel *kernelWeight = NULL;      // Kernel for the weight map
    572605
    573606    for (int y = size; y < inImage->numRows - size; y++) {
     
    582615                                               2.0 * (float)(x - numCols/2.0) / (float)numCols,
    583616                                               2.0 * (float)(y - numRows/2.0) / (float)numRows);
     617                kernelImage = solvedKernel(kernelImage, solution, kernels, polyValues, imageWeighting);
     618                if (inWeight) {
     619                    kernelWeight = solvedKernel(kernelWeight, solution, kernels, polyValues,
     620                                                varianceWeighting);
     621                }
    584622            }
    585623
     
    602640
    603641            // Convolve the image
    604             for (int i = 0; i < numKernels; i++) {
    605                 convImage->data.F32[y][x] += solution->data.F64[i] *
    606                     convolvePixel(kernels, i, x, y, inImage, polyValues, imageWeighting);
     642            for (int v = -size; v <= size; v++) {
     643                for (int u = -size; u <= size; u++) {
     644                    convImage->data.F32[y][x] += kernelImage->kernel[v][u] * inImage->data.F32[y + v][x + u];
     645                }
    607646            }
    608647
    609648            // Convolve the weight (variance) map
    610649            if (inWeight) {
    611                 for (int i = 0; i < numKernels; i++) {
    612                     convWeight->data.F32[y][x] += PS_SQR(solution->data.F64[i]) *
    613                         convolvePixel(kernels, i, x, y, inWeight, polyValues, varianceWeighting);
    614                 }
    615             }
    616         }
    617     }
     650                for (int v = -size; v <= size; v++) {
     651                    for (int u = -size; u <= size; u++) {
     652                        convWeight->data.F32[y][x] += kernelWeight->kernel[v][u] *
     653                            inWeight->data.F32[y + v][x + u];
     654                    }
     655                }
     656            }
     657        }
     658    }
     659    psFree(kernelImage);
     660    psFree(kernelWeight);
    618661    psFree(polyValues);
    619662
Note: See TracChangeset for help on using the changeset viewer.