IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14305


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.

Location:
trunk/psModules/src/imcombine
Files:
3 edited

Legend:

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

    r14304 r14305  
    44 *  @author GLG, MHPCC
    55 *
    6  *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2007-07-19 01:10:57 $
     6 *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2007-07-19 01:39:28 $
    88 *
    99 *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    2525#include "pmSubtraction.h"
    2626
    27 //#define USE_FUNCTIONS_INSTEAD_OF_MACROS          // Can I pass the address of a static inline function?
     27#define USE_FUNCTIONS_INSTEAD_OF_MACROS          // Can I pass the address of a static inline function?
    2828
    2929//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    209209              break;
    210210          }
     211          case PM_SUBTRACTION_KERNEL_GUNK: {
     212              if (i < kernels->inner) {
     213                  // Using pre-calculated function
     214                  psKernel *preCalc = kernels->preCalc->data[i]; // Precalculated values
     215                  for (int v = -size; v <= size; v++) {
     216                      for (int u = -size; u <= size; u++) {
     217                          kernel->kernel[v][u] += value * weightFunc(preCalc->kernel[v][u]);
     218                      }
     219                  }
     220              } else {
     221                  // Using delta function
     222                  int u = kernels->u->data.S32[i]; // Offset in x
     223                  int v = kernels->v->data.S32[i]; // Offset in y
     224                  kernel->kernel[v][u] += value;
     225              }
     226              // The (0,0) kernel is subtracted from other kernels to preserve photometric scaling
     227              if (kernels->spatialOrder > 0 && i != kernels->subIndex) {
     228                  kernel->kernel[0][0] += subValue;
     229              }
     230              break;
     231          }
    211232          case PM_SUBTRACTION_KERNEL_ISIS: {
    212233              psKernel *preCalc = kernels->preCalc->data[i];// Precalculated values
     
    355376          return sum;
    356377      }
     378      case PM_SUBTRACTION_KERNEL_GUNK: {
     379          double value;                 // The value to return
     380          if (index < kernels->inner) {
     381              // Using pre-calculated function
     382              psKernel *kernel = kernels->preCalc->data[index]; // The convolution kernel
     383              int size = kernels->size;     // Kernel half-size
     384              double sum = 0.0;             // Accumulated sum from convolution
     385              double sub = 0.0;             // Accumulated sum to subtract
     386              for (int v = -size; v <= size; v++) {
     387                  for (int u = -size; u <= size; u++) {
     388                      sum += weightFunc(kernel->kernel[v][u]) * image->data.F32[y + v][x + u];
     389                  }
     390              }
     391              value = weightFunc(polyValue) * sum + weightFunc(-1.0) * sub;
     392          } else {
     393              // Using delta function
     394              int u = kernels->u->data.S32[index]; // Offset in x
     395              int v = kernels->v->data.S32[index]; // Offset in y
     396              value = weightFunc(polyValue) * image->data.F32[y + v][x + u]; // Value of convolution
     397          }
     398          /* The (0,0) delta function is subtracted from most kernels to preserve photometric scaling */
     399          if (kernels->spatialOrder > 0 && index != kernels->subIndex) {
     400              value += weightFunc(-1.0) * image->data.F32[y][x];
     401          }
     402          return value;
     403      }
    357404      case PM_SUBTRACTION_KERNEL_ISIS: {
    358405          psKernel *kernel = kernels->preCalc->data[index]; // The convolution kernel
  • 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);
  • trunk/psModules/src/imcombine/pmSubtractionKernels.h

    r14106 r14305  
    1010    PM_SUBTRACTION_KERNEL_SPAM,         ///< Summed Pixels for Advanced Matching --- summed delta functions
    1111    PM_SUBTRACTION_KERNEL_FRIES,        ///< Fibonacci Radius Increases Excellence of Subtraction
     12    PM_SUBTRACTION_KERNEL_GUNK,         ///< Grid United with Normal Kernel --- POIS and ISIS hybrid
    1213} pmSubtractionKernelsType;
    1314
     
    2223    psArray *preCalc;                   ///< Array of images containing pre-calculated kernel (for ISIS)
    2324    int size;                           ///< The half-size of the kernel
     25    int inner;                          ///< The size of an inner region
    2426    int spatialOrder;                   ///< The spatial order of the kernels
    2527} pmSubtractionKernels;
     
    6062    );
    6163
     64/// Generate GUNK kernels
     65pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, ///< Half-size of the kernel
     66                                               int spatialOrder, ///< Order of spatial variations
     67                                               const psVector *sigmas, ///< Gaussian widths
     68                                               const psVector *orders, ///< Polynomial order of gaussians
     69                                               int inner ///< Inner radius containing grid of delta functions
     70    );
     71
    6272/// Generate a kernel of a specified type
    6373pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, ///< Kernel type
Note: See TracChangeset for help on using the changeset viewer.