IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 26762


Ignore:
Timestamp:
Feb 2, 2010, 11:45:40 AM (16 years ago)
Author:
Paul Price
Message:

Adding function, psKernelTruncate, to truncate a kernel so as to lose less than some nominated fraction of the total absolute flux.

Location:
branches/eam_branches/20091201/psLib/src/imageops
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20091201/psLib/src/imageops/psImageConvolve.c

    r25383 r26762  
    246246    return kernel;
    247247}
     248
     249bool psKernelTruncate(psKernel *kernel, float frac)
     250{
     251    PS_ASSERT_KERNEL_NON_NULL(kernel, false);
     252    PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(frac, 0.0, false);
     253    PS_ASSERT_FLOAT_LESS_THAN(frac, 1.0, false);
     254
     255    if (frac == 0.0) {
     256        // Nothing to do
     257        return true;
     258    }
     259
     260    int xMin = kernel->xMin, xMax = kernel->xMax, yMin = kernel->yMin, yMax = kernel->yMax; // Bounds
     261    int maxSize = PS_MAX(PS_MAX(PS_MAX(-xMin, xMax), -yMin), yMax); // Maximum size
     262
     263    // Determine the threshold
     264    // Summing absolute values because large negative deviations have power as well
     265    double sumKernel = 0.0;             // Sum of the kernel
     266    for (int y = yMin; y <= yMax; y++) {
     267        for (int x = xMin; x <= xMax; x++) {
     268            sumKernel += fabsf(kernel->kernel[y][x]);
     269        }
     270    }
     271
     272    float threshold = sumKernel * (1.0 - frac); // Threshold for truncation
     273
     274    // Find truncation size
     275    int truncate = 0;                     // Truncation radius
     276    for (int radius = 1; truncate == 0 && radius < maxSize; radius++) {
     277        int uMin = PS_MAX(-radius, xMin);
     278        int uMax = PS_MIN(radius, xMax);
     279        int vMin = PS_MAX(-radius, yMin);
     280        int vMax = PS_MIN(radius, yMax);
     281        int r2 = PS_SQR(radius);
     282        double sum = 0.0;
     283        for (int v = vMin; v <= vMax; v++) {
     284            int v2 = PS_SQR(v);
     285            for (int u = uMin; u <= uMax; u++) {
     286                int u2 = PS_SQR(u);
     287                if (u2 + v2 <= r2) {
     288                    sum += fabsf(kernel->kernel[v][u]);
     289                }
     290            }
     291        }
     292        if (sum > threshold) {
     293            // This is the truncation radius
     294            truncate = radius;
     295        }
     296    }
     297    if (truncate == maxSize) {
     298        // No truncation possible
     299        return true;
     300    }
     301
     302    // Truncate the kernel
     303    {
     304        int uMin = PS_MAX(-truncate, xMin);
     305        int uMax = PS_MIN(truncate, xMax);
     306        int vMin = PS_MAX(-truncate, yMin);
     307        int vMax = PS_MIN(truncate, yMax);
     308        int r2 = PS_SQR(truncate);
     309        for (int v = vMin; v <= vMax; v++) {
     310            int v2 = PS_SQR(v);
     311            for (int u = uMin; u <= uMax; u++) {
     312                int u2 = PS_SQR(u);
     313                if (u2 + v2 > r2) {
     314                    kernel->kernel[v][u] = 0.0;
     315                }
     316            }
     317        }
     318    }
     319    kernel->xMin = PS_MAX(-truncate, kernel->xMin);
     320    kernel->xMax = PS_MIN(truncate, kernel->xMax);
     321    kernel->yMin = PS_MAX(-truncate, kernel->yMin);
     322    kernel->yMax = PS_MIN(truncate, kernel->yMax);
     323
     324    return true;
     325    }
     326
     327
    248328
    249329psImage *psImageConvolveDirect(psImage *out, const psImage *in, const psKernel *kernel)
  • branches/eam_branches/20091201/psLib/src/imageops/psImageConvolve.h

    r25383 r26762  
    138138);
    139139
     140/// Truncate a kernel
     141///
     142/// Truncates the outer parts of the kernel where the contribution is below the nominated fraction of the
     143/// total kernel.
     144bool psKernelTruncate(
     145    psKernel *in,                       ///< Kernel to be truncated
     146    float frac                          ///< Fraction for truncation threshold
     147    );
     148
     149
    140150/// Convolve an image with a kernel, using a direct convolution
    141151///
Note: See TracChangeset for help on using the changeset viewer.