Search in sources :

Example 6 with WlCoef_I32

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

the class ImplWaveletTransformBorder method verticalInverse.

public static void verticalInverse(BorderIndex1D border, WlBorderCoef<WlCoef_I32> desc, GrayS32 input, GrayS32 output) {
    int[] trends = new int[input.height];
    int[] details = new int[input.height];
    final int width = output.width;
    final int paddedHeight = output.height + output.height % 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.height) + upperExtra) / 2;
    boolean isLarger = input.height >= output.height;
    // 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] = paddedHeight - (indexes.length - i) * 2;
    border.setLength(output.height + output.height % 2);
    WlCoef_I32 coefficients = desc.getInnerCoefficients();
    final int e = coefficients.denominatorScaling * 2;
    final int f = coefficients.denominatorWavelet * 2;
    final int ef = e * f;
    final int ef2 = ef / 2;
    for (int x = 0; x < width; x++) {
        // initialize details and trends arrays
        for (int i = 0; i < indexes.length; i++) {
            int y = indexes[i];
            details[y] = 0;
            trends[y] = 0;
            y++;
            details[y] = 0;
            trends[y] = 0;
        }
        for (int i = 0; i < indexes.length; i++) {
            int y = indexes[i];
            float a = input.get(x, y / 2);
            float d = input.get(x, input.height / 2 + y / 2);
            if (y < lowerBorder) {
                coefficients = desc.getBorderCoefficients(y);
            } else if (y >= upperBorder) {
                coefficients = desc.getBorderCoefficients(y - paddedHeight);
            } else {
                coefficients = desc.getInnerCoefficients();
            }
            final int offsetA = coefficients.offsetScaling;
            final int offsetB = coefficients.offsetWavelet;
            final int[] alpha = coefficients.scaling;
            final int[] 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 yy = border.getIndex(y + offsetA + j);
                if (isLarger && yy >= output.height)
                    continue;
                trends[yy] += a * alpha[j];
            }
            // add the detail signal
            for (int j = 0; j < beta.length; j++) {
                int yy = border.getIndex(y + offsetB + j);
                if (isLarger && yy >= output.height)
                    continue;
                details[yy] += d * beta[j];
            }
        }
        int indexDst = output.startIndex + x;
        for (int y = 0; y < lowerCompute; y++) {
            output.data[indexDst + y * output.stride] = UtilWavelet.round(trends[y] * f + details[y] * e, ef2, ef);
        }
        for (int y = paddedHeight - upperCompute; y < output.height; y++) {
            output.data[indexDst + y * output.stride] = UtilWavelet.round(trends[y] * f + details[y] * e, ef2, ef);
        }
    }
}
Also used : WlCoef_I32(boofcv.struct.wavelet.WlCoef_I32) WlCoef(boofcv.struct.wavelet.WlCoef)

Example 7 with WlCoef_I32

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

the class ImplWaveletTransformNaive method horizontalInverse.

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

Example 8 with WlCoef_I32

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

the class CommonFactoryWavelet method checkBiorthogonal_I32.

public static void checkBiorthogonal_I32(WaveletDescription<WlCoef_I32> desc) {
    WlCoef_I32 forward = desc.getForward();
    BorderIndex1D border = desc.getBorder();
    int N = Math.max(forward.getScalingLength(), forward.getWaveletLength());
    N += N % 2;
    N *= 2;
    border.setLength(N);
    DMatrixRMaj A = new DMatrixRMaj(N, N);
    DMatrixRMaj B = new DMatrixRMaj(N, N);
    // using the wrapping rule construct a matrix with the coefficients
    for (int i = 0; i < N; i += 2) {
        for (int j = 0; j < forward.scaling.length; j++) {
            int index = border.getIndex(i + j + forward.offsetScaling);
            A.add(i, index, (double) forward.scaling[j] / forward.denominatorScaling);
        }
        for (int j = 0; j < forward.wavelet.length; j++) {
            int index = border.getIndex(i + j + forward.offsetWavelet);
            A.add(i + 1, index, (double) forward.wavelet[j] / forward.denominatorWavelet);
        }
    }
    // the inverse coefficients should be a matrix which is the inverse of the forward coefficients
    final int lowerBorder = desc.getInverse().getLowerLength() * 2;
    final int upperBorder = N - desc.getInverse().getUpperLength() * 2;
    for (int i = 0; i < N; i += 2) {
        WlCoef_I32 inverse;
        if (i < lowerBorder) {
            inverse = desc.getInverse().getBorderCoefficients(i);
        } else if (i >= upperBorder) {
            inverse = desc.getInverse().getBorderCoefficients(i - N);
        } else {
            inverse = desc.getInverse().getInnerCoefficients();
        }
        for (int j = 0; j < inverse.scaling.length; j++) {
            int index = border.getIndex(i + j + inverse.offsetScaling);
            B.add(index, i, (double) inverse.scaling[j] / inverse.denominatorScaling);
        }
        for (int j = 0; j < inverse.wavelet.length; j++) {
            int index = border.getIndex(i + j + inverse.offsetWavelet);
            B.add(index, i + 1, (double) inverse.wavelet[j] / inverse.denominatorWavelet);
        }
    }
    DMatrixRMaj C = new DMatrixRMaj(N, N);
    CommonOps_DDRM.mult(A, B, C);
    assertTrue(MatrixFeatures_DDRM.isIdentity(C, 1e-4));
}
Also used : BorderIndex1D(boofcv.core.image.border.BorderIndex1D) WlCoef_I32(boofcv.struct.wavelet.WlCoef_I32) DMatrixRMaj(org.ejml.data.DMatrixRMaj)

Example 9 with WlCoef_I32

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

the class TestFactoryWaveletDaub method biorthogonal_I32_forward.

@Test
public void biorthogonal_I32_forward() {
    for (int i = 5; i <= 5; i += 2) {
        WlCoef_I32 forward = FactoryWaveletDaub.biorthogonal_I32(i, borderDefault).getForward();
        int sumScaling = UtilWavelet.sumCoefficients(forward.scaling) / forward.denominatorScaling;
        assertEquals(1, sumScaling);
        int sumWavelet = UtilWavelet.sumCoefficients(forward.wavelet);
        assertEquals(0, sumWavelet);
        double energyScaling = UtilWavelet.computeEnergy(forward.scaling, forward.denominatorScaling);
        double energyWavelet = UtilWavelet.computeEnergy(forward.wavelet, forward.denominatorWavelet);
        assertTrue(Math.abs(1 - energyScaling) > 1e-4);
        assertTrue(Math.abs(1 - energyWavelet) > 1e-4);
        int polyOrder = i / 2 - 1;
        checkPolySumToZero(forward.wavelet, polyOrder, -1);
        checkPolySumToZero(forward.scaling, polyOrder, -2);
    }
}
Also used : WlCoef_I32(boofcv.struct.wavelet.WlCoef_I32) Test(org.junit.Test)

Example 10 with WlCoef_I32

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

the class TestFactoryWaveletDaub method biorthogonal_I32_inverse.

@Test
public void biorthogonal_I32_inverse() {
    for (BorderType type : borderTypes) {
        for (int i = 5; i <= 5; i += 2) {
            WaveletDescription<WlCoef_I32> desc = FactoryWaveletDaub.biorthogonal_I32(i, type);
            checkBiorthogonal_I32(desc);
        }
    }
}
Also used : WlCoef_I32(boofcv.struct.wavelet.WlCoef_I32) BorderType(boofcv.core.image.border.BorderType) Test(org.junit.Test)

Aggregations

WlCoef_I32 (boofcv.struct.wavelet.WlCoef_I32)14 Test (org.junit.Test)6 BorderType (boofcv.core.image.border.BorderType)2 GrayS32 (boofcv.struct.image.GrayS32)2 ImageDimension (boofcv.struct.image.ImageDimension)2 WlCoef (boofcv.struct.wavelet.WlCoef)2 WaveletTransform (boofcv.abst.transform.wavelet.WaveletTransform)1 BorderIndex1D (boofcv.core.image.border.BorderIndex1D)1 FactoryWaveletTransform (boofcv.factory.transform.wavelet.FactoryWaveletTransform)1 GrayU8 (boofcv.struct.image.GrayU8)1 WlCoef_F32 (boofcv.struct.wavelet.WlCoef_F32)1 DMatrixRMaj (org.ejml.data.DMatrixRMaj)1