Search in sources :

Example 16 with WlCoef_F32

use of boofcv.struct.wavelet.WlCoef_F32 in project BoofCV by lessthanoptimal.

the class ImplWaveletTransformBorder method horizontalInverse.

public static void horizontalInverse(BorderIndex1D border, WlBorderCoef<WlCoef_F32> desc, GrayF32 input, GrayF32 output) {
    float[] trends = new float[input.width];
    float[] details = new float[input.width];
    final int height = output.height;
    final int paddedWidth = output.width + output.width % 2;
    WlCoef inner = desc.getInnerCoefficients();
    // need to convolve coefficients that influence the ones being updated
    int lowerExtra = -Math.min(inner.offsetScaling, inner.offsetWavelet);
    int upperExtra = Math.max(inner.getScalingLength() + inner.offsetScaling, inner.getWaveletLength() + inner.offsetWavelet);
    lowerExtra += lowerExtra % 2;
    upperExtra += upperExtra % 2;
    int lowerBorder = (UtilWavelet.borderInverseLower(desc, border) + lowerExtra) / 2;
    int upperBorder = (UtilWavelet.borderInverseUpper(desc, border, output.width) + upperExtra) / 2;
    boolean isLarger = input.width >= output.width;
    // where updated wavelet values are stored
    int lowerCompute = lowerBorder * 2 - lowerExtra;
    int upperCompute = upperBorder * 2 - upperExtra;
    int[] indexes = new int[lowerBorder + upperBorder];
    for (int i = 0; i < lowerBorder; i++) indexes[i] = i * 2;
    for (int i = lowerBorder; i < indexes.length; i++) indexes[i] = paddedWidth - (indexes.length - i) * 2;
    border.setLength(output.width + output.width % 2);
    WlCoef_F32 coefficients;
    for (int y = 0; y < height; y++) {
        // initialize details and trends arrays
        for (int i = 0; i < indexes.length; i++) {
            int x = indexes[i];
            details[x] = 0;
            trends[x] = 0;
            x++;
            details[x] = 0;
            trends[x] = 0;
        }
        for (int i = 0; i < indexes.length; i++) {
            int x = indexes[i];
            float a = input.get(x / 2, y);
            float d = input.get(input.width / 2 + x / 2, y);
            if (x < lowerBorder) {
                coefficients = desc.getBorderCoefficients(x);
            } else if (x >= upperBorder) {
                coefficients = desc.getBorderCoefficients(x - paddedWidth);
            } else {
                coefficients = desc.getInnerCoefficients();
            }
            final int offsetA = coefficients.offsetScaling;
            final int offsetB = coefficients.offsetWavelet;
            final float[] alpha = coefficients.scaling;
            final float[] beta = coefficients.wavelet;
            // add the trend
            for (int j = 0; j < alpha.length; j++) {
                // if an odd image don't update the outer edge
                int xx = border.getIndex(x + offsetA + j);
                if (isLarger && xx >= output.width)
                    continue;
                trends[xx] += a * alpha[j];
            }
            // add the detail signal
            for (int j = 0; j < beta.length; j++) {
                int xx = border.getIndex(x + offsetB + j);
                if (isLarger && xx >= output.width)
                    continue;
                details[xx] += d * beta[j];
            }
        }
        int indexDst = output.startIndex + y * output.stride;
        for (int x = 0; x < lowerCompute; x++) {
            output.data[indexDst + x] = (trends[x] + details[x]);
        }
        for (int x = paddedWidth - upperCompute; x < output.width; x++) {
            output.data[indexDst + x] = (trends[x] + details[x]);
        }
    }
}
Also used : WlCoef_F32(boofcv.struct.wavelet.WlCoef_F32) WlCoef(boofcv.struct.wavelet.WlCoef)

Example 17 with WlCoef_F32

use of boofcv.struct.wavelet.WlCoef_F32 in project BoofCV by lessthanoptimal.

the class ImplWaveletTransformNaive method verticalInverse.

/**
 * Performs a single level inverse wavelet transform along the vertical axis.
 *
 * @param inverseCoef Description of wavelet coefficients.
 * @param input Transformed image. Not modified.
 * @param output Reconstruction of original image. Modified
 */
public static void verticalInverse(BorderIndex1D border, WlBorderCoef<WlCoef_F32> inverseCoef, GrayF32 input, GrayF32 output) {
    UtilWavelet.checkShape(output, input);
    float[] trends = new float[output.height];
    float[] details = new float[output.height];
    boolean isLarger = input.height > output.height;
    int paddedHeight = output.height + output.height % 2;
    final int lowerBorder = inverseCoef.getLowerLength() * 2;
    final int upperBorder = output.height - inverseCoef.getUpperLength() * 2;
    border.setLength(output.height + output.height % 2);
    WlCoef_F32 coefficients;
    for (int x = 0; x < output.width; x++) {
        for (int i = 0; i < details.length; i++) {
            details[i] = 0;
            trends[i] = 0;
        }
        for (int y = 0; y < output.height; y += 2) {
            float a = input.get(x, y / 2);
            float d = input.get(x, y / 2 + input.height / 2);
            if (y < lowerBorder) {
                coefficients = inverseCoef.getBorderCoefficients(y);
            } else if (y >= upperBorder) {
                coefficients = inverseCoef.getBorderCoefficients(y - paddedHeight);
            } else {
                coefficients = inverseCoef.getInnerCoefficients();
            }
            final int offsetA = coefficients.offsetScaling;
            final int offsetB = coefficients.offsetWavelet;
            final float[] alpha = coefficients.scaling;
            final float[] beta = coefficients.wavelet;
            // add the 'average' signal
            for (int i = 0; i < alpha.length; i++) {
                // if an odd image don't update the outer edge
                int yy = border.getIndex(y + offsetA + i);
                if (isLarger && yy >= output.height)
                    continue;
                trends[yy] += a * alpha[i];
            }
            // add the detail signal
            for (int i = 0; i < beta.length; i++) {
                int yy = border.getIndex(y + offsetB + i);
                if (isLarger && yy >= output.height)
                    continue;
                details[yy] += d * beta[i];
            }
        }
        for (int y = 0; y < output.height; y++) {
            output.set(x, y, trends[y] + details[y]);
        }
    }
}
Also used : WlCoef_F32(boofcv.struct.wavelet.WlCoef_F32)

Example 18 with WlCoef_F32

use of boofcv.struct.wavelet.WlCoef_F32 in project BoofCV by lessthanoptimal.

the class TestWaveletTransformFloat32 method compareToWaveletTransformOps.

@Test
public void compareToWaveletTransformOps() {
    GrayF32 orig = new GrayF32(width, height);
    GImageMiscOps.fillUniform(orig, rand, 0, 20);
    GrayF32 origCopy = orig.clone();
    int N = 3;
    ImageDimension dimen = UtilWavelet.transformDimension(orig, N);
    GrayF32 found = new GrayF32(dimen.width, dimen.height);
    GrayF32 expected = new GrayF32(dimen.width, dimen.height);
    WaveletDescription<WlCoef_F32> desc = FactoryWaveletDaub.biorthogonal_F32(5, BorderType.REFLECT);
    GrayF32 storage = new GrayF32(dimen.width, dimen.height);
    WaveletTransformOps.transformN(desc, orig.clone(), expected, storage, N);
    WaveletTransformFloat32 alg = new WaveletTransformFloat32(desc, N, 0, 255);
    alg.transform(orig, found);
    // make sure the original input was not modified like it is in WaveletTransformOps
    BoofTesting.assertEquals(origCopy, orig, 1e-4);
    // see if the two techniques produced the same results
    BoofTesting.assertEquals(expected, found, 1e-4);
    // test inverse transform
    GrayF32 reconstructed = new GrayF32(width, height);
    alg.invert(found, reconstructed);
    BoofTesting.assertEquals(orig, reconstructed, 1e-4);
    // make sure the input has not been modified
    BoofTesting.assertEquals(expected, found, 1e-4);
}
Also used : WlCoef_F32(boofcv.struct.wavelet.WlCoef_F32) GrayF32(boofcv.struct.image.GrayF32) ImageDimension(boofcv.struct.image.ImageDimension) Test(org.junit.Test)

Aggregations

WlCoef_F32 (boofcv.struct.wavelet.WlCoef_F32)18 Test (org.junit.Test)7 BorderType (boofcv.core.image.border.BorderType)2 WlCoef (boofcv.struct.wavelet.WlCoef)2 WaveletTransform (boofcv.abst.transform.wavelet.WaveletTransform)1 BorderIndex1D (boofcv.core.image.border.BorderIndex1D)1 BorderIndex1D_Wrap (boofcv.core.image.border.BorderIndex1D_Wrap)1 FactoryWaveletTransform (boofcv.factory.transform.wavelet.FactoryWaveletTransform)1 GrayF32 (boofcv.struct.image.GrayF32)1 ImageDimension (boofcv.struct.image.ImageDimension)1 WaveletDescription (boofcv.struct.wavelet.WaveletDescription)1 WlBorderCoefStandard (boofcv.struct.wavelet.WlBorderCoefStandard)1 WlCoef_I32 (boofcv.struct.wavelet.WlCoef_I32)1 DMatrixRMaj (org.ejml.data.DMatrixRMaj)1