IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 5, 2009, 10:15:32 AM (17 years ago)
Author:
Paul Price
Message:

Adding function to truncate a covariance matrix. This should help to keep them from growing too large (we're using kernels of half-size ~ 15 pixels for stack, which makes the covariance matrix grow by 60 pixels, which puts a big stress on psImageCovarianceCalculate).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageCovariance.c

    r21298 r21316  
    55#include <stdio.h>
    66#include <limits.h>
     7#include <string.h>
    78
    89#include "psMemory.h"
     
    172173    return sum;
    173174}
     175
     176
     177psKernel *psImageCovarianceTruncate(const psKernel *covar, float frac)
     178{
     179    PS_ASSERT_KERNEL_NON_NULL(covar, NULL);
     180    PS_ASSERT_FLOAT_WITHIN_RANGE(frac, 0, 1, NULL);
     181
     182    int xMin = covar->xMin, xMax = covar->xMax, yMin = covar->yMin, yMax = covar->yMax; // Range
     183
     184    double sum = 0.0;                   // Sum of covariance
     185    for (int y = yMin; y <= yMax; y++) {
     186        for (int x = xMin; x <= xMax; x++) {
     187            sum += covar->kernel[y][x];
     188        }
     189    }
     190
     191    // Determine radius for truncation
     192    double threshold = (1.0 - frac) * sum; // Threshold for truncation
     193    int maxRadius = PS_MAX(PS_MAX(PS_MAX(xMax, yMax), -xMin), yMin); // Maximum radius of covariance matrix
     194    double enclosed = NAN;              // Enclosed value
     195    int radius;                         // Radius at which to truncate
     196    for (radius = 0; radius <= maxRadius && enclosed < threshold; radius++) {
     197        // Not so efficient to execute, but easy to code; it should be fast anyway
     198        enclosed = 0.0;
     199        for (int y = PS_MAX(yMin, -radius); y <= PS_MIN(yMax, radius); y++) {
     200            for (int x = PS_MAX(xMin, -radius); x <= PS_MIN(xMax, radius); x++) {
     201                enclosed += covar->kernel[y][x];
     202            }
     203        }
     204    }
     205
     206    // Generate truncated version
     207    psKernel *trunc = psKernelAlloc(-radius, radius, -radius, radius); // Truncated covariance matrix
     208    int numBytes = (2 * radius + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy
     209    for (int y = -radius; y <= radius; y++) {
     210        memcpy(trunc->kernel[y], covar->kernel[y], numBytes);
     211    }
     212
     213    return trunc;
     214}
Note: See TracChangeset for help on using the changeset viewer.