IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 28667 for trunk/psModules


Ignore:
Timestamp:
Jul 13, 2010, 2:34:04 PM (16 years ago)
Author:
Paul Price
Message:

It's bothered me for a while that the noise model that we have been using is only kind of spatially variable. The variance map is intended to track the change in the noise properties as a function of position, and while it does keep track of different noise levels due to, e.g., different detectors, vignetting, etc., it has not tracked the different noise that comes from convolution kernels changing over an image. This had been an intentional oversight --- the prescription we were using for calculating the variance and covariance removed the spatial variation (by prescribing that the variance level under a convolution remain unchanged) and we were sweeping it under the carpet so we could calculate the covariance pseudo-matrix and use that for setting the absolute level of the noise.

I've now figured out how to have our cake and eat it too. By changing where the scalings are applied, the variance map can track the changing noise introduced by a varying convolution kernel, while the covariance pseudo-matrix tracks an absolute change. This fix is purely algorithmic --- it does not affect any of the variances/covariances stored on disk, nor is it affected by them. I hope that this means that any Magic recertification required is either minimal or completely unnecessary.

Again, all that has changed is where the scalings are applied.

File:
1 edited

Legend:

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

    r28405 r28667  
    5252
    5353    // Take the square of the normal kernel
    54     double sumVariance = 0.0; // Sum of the variance kernels
    5554    for (int v = yMin; v <= yMax; v++) {
    5655        for (int u = xMin; u <= xMax; u++) {
    57             sumVariance += out->kernel[v][u] = PS_SQR(normalKernel->kernel[v][u]);
    58         }
    59     }
    60 
    61     // Normalise so that the sum of the variance kernel is the square of the sum of the normal kernel
    62     // This is required to keep the relative scaling between the image and the variance map
    63     psBinaryOp(out->image, out->image, "*", psScalarAlloc(1.0 / sumVariance, PS_TYPE_F32));
    64 
     56            out->kernel[v][u] = PS_SQR(normalKernel->kernel[v][u]);
     57        }
     58    }
    6559    return out;
    6660}
     
    271265// Convolve an image using FFT
    272266static void convolveVarianceFFT(psImage *target,// Place the result in here
    273                               psImage *variance, // Variance map to convolve
    274                               psImage *kernelErr, // Kernel error image
    275                               psImage *mask, // Mask image
    276                               psImageMaskType maskVal, // Value to mask
    277                               const psKernel *kernel, // Kernel by which to convolve
    278                               psRegion region,// Region of interest
    279                               int size        // Size of (square) kernel
    280                               )
     267                                psImage *variance, // Variance map to convolve
     268                                psImage *kernelErr, // Kernel error image
     269                                psImage *mask, // Mask image
     270                                psImageMaskType maskVal, // Value to mask
     271                                const psKernel *kernel, // Kernel by which to convolve
     272                                psRegion region,// Region of interest
     273                                int size        // Size of (square) kernel
     274                                )
    281275{
    282276    psRegion border = psRegionSet(region.x0 - size, region.x1 + size,
     
    348342                                  psImage *image, // Image to convolve
    349343                                  psImage *variance, // Variance map to convolve, or NULL
     344                                  const psKernel *covar,               // Covariance, or NULL
    350345                                  psImage *kernelErr, // Kernel error image, or NULL
    351346                                  psImage *subMask, // Subtraction mask
     
    393388        if (variance) {
    394389            convolveDirect(convVariance, variance, *kernelVariance, region, 0.0, kernels->size);
     390        }
     391    }
     392
     393    if (variance && covar) {
     394        // Apply covariance factor to variance map, to allow for spatial variation
     395        float factor = psImageCovarianceCalculateFactor(*kernelImage, covar); // Factor to apply
     396        for (int y = region.y0; y < region.y1; y++) {
     397            for (int x = region.x0; x < region.x1; x++) {
     398                convVariance->data.F32[y][x] *= factor;
     399            }
    395400        }
    396401    }
     
    10851090    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    10861091        convolveRegion(out1->image, out1->variance, out1->mask, &kernelImage, &kernelVariance,
    1087                        ro1->image, ro1->variance, kernelErr1, subMask, kernels, polyValues, background,
    1088                        *region, maskBad, maskPoor, poorFrac, useFFT, false);
     1092                       ro1->image, ro1->variance, ro1->covariance, kernelErr1, subMask, kernels,
     1093                       polyValues, background, *region, maskBad, maskPoor, poorFrac, useFFT, false);
    10891094    }
    10901095    if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    10911096        convolveRegion(out2->image, out2->variance, out2->mask, &kernelImage, &kernelVariance,
    1092                        ro2->image, ro2->variance, kernelErr2, subMask, kernels, polyValues, background,
    1093                        *region, maskBad, maskPoor, poorFrac, useFFT,
     1097                       ro2->image, ro2->variance, ro2->covariance, kernelErr2, subMask, kernels,
     1098                       polyValues, background, *region, maskBad, maskPoor, poorFrac, useFFT,
    10941099                       kernels->mode == PM_SUBTRACTION_MODE_DUAL);
    10951100    }
     
    13251330
    13261331    // Calculate covariances
    1327     // This can be fairly involved, so we only do it for a single instance
    1328     // Enable threads for covariance calculation, since we're not threading on top of it.
     1332    // This can be fairly involved, so we only do it for a small number of instances
    13291333    float position[NUM_COVAR_POS] = { -1.0, -0.5, 0.0, +0.5, +1.0 }; // Positions for covariance calculations
     1334    // Enable threads for covariance calculation, since we're not threading on top of it
    13301335    oldThreads = psImageCovarianceSetThreads(true);
    13311336    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
     
    13421347        out1->covariance = psImageCovarianceAverage(covars);
    13431348        psFree(covars);
     1349        // Remove covariance factor from covariance, since we've put it in the variance map already
     1350        float factor = psImageCovarianceFactor(out1->covariance);
     1351        psBinaryOp(out1->covariance->image, out1->covariance->image, "/", psScalarAlloc(factor, PS_TYPE_F32));
    13441352    }
    13451353    if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
     
    13561364        out2->covariance = psImageCovarianceAverage(covars);
    13571365        psFree(covars);
     1366        // Remove covariance factor from covariance, since we've put it in the variance map already
     1367        float factor = psImageCovarianceFactor(out2->covariance);
     1368        psBinaryOp(out2->covariance->image, out2->covariance->image, "/", psScalarAlloc(factor, PS_TYPE_F32));
    13581369    }
    13591370    psImageCovarianceSetThreads(oldThreads);
Note: See TracChangeset for help on using the changeset viewer.