Search in sources :

Example 1 with WlCoef

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

the class TestImplWaveletTransformInner method applyInnerMethod.

public static void applyInnerMethod(String functionName, WaveletDescription<?> desc, ImageGray input, ImageGray output) {
    Method m;
    Object[] args;
    if (functionName.contains("Inverse")) {
        WlCoef coef = desc.getInverse().getInnerCoefficients();
        m = BoofTesting.findMethod(ImplWaveletTransformInner.class, functionName, coef.getClass(), input.getClass(), output.getClass());
        args = new Object[] { coef, input, output };
    } else {
        WlCoef coef = desc.getForward();
        m = BoofTesting.findMethod(ImplWaveletTransformInner.class, functionName, coef.getClass(), input.getClass(), output.getClass());
        args = new Object[] { coef, input, output };
    }
    try {
        m.invoke(null, args);
    } catch (InvocationTargetException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}
Also used : WlCoef(boofcv.struct.wavelet.WlCoef) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with WlCoef

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

the class ImplWaveletTransformBorder method verticalInverse.

public static void verticalInverse(BorderIndex1D border, WlBorderCoef<WlCoef_F32> desc, GrayF32 input, GrayF32 output) {
    float[] trends = new float[input.height];
    float[] details = new float[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_F32 coefficients;
    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 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 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] = (trends[y] + details[y]);
        }
        for (int y = paddedHeight - upperCompute; y < output.height; y++) {
            output.data[indexDst + y * output.stride] = (trends[y] + details[y]);
        }
    }
}
Also used : WlCoef_F32(boofcv.struct.wavelet.WlCoef_F32) WlCoef(boofcv.struct.wavelet.WlCoef)

Example 3 with WlCoef

use of boofcv.struct.wavelet.WlCoef 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 4 with WlCoef

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

the class UtilWavelet method borderInverseLower.

/**
 * Returns the lower border for an inverse wavelet transform.
 */
public static int borderInverseLower(WlBorderCoef<?> desc, BorderIndex1D border) {
    WlCoef inner = desc.getInnerCoefficients();
    int borderSize = borderForwardLower(inner);
    WlCoef ll = borderSize > 0 ? inner : null;
    WlCoef lu = ll;
    WlCoef uu = inner;
    int indexLU = 0;
    if (desc.getLowerLength() > 0) {
        ll = desc.getBorderCoefficients(0);
        indexLU = desc.getLowerLength() * 2 - 2;
        lu = desc.getBorderCoefficients(indexLU);
    }
    if (desc.getUpperLength() > 0) {
        uu = desc.getBorderCoefficients(-2);
    }
    border.setLength(2000);
    borderSize = checkInverseLower(ll, 0, border, borderSize);
    borderSize = checkInverseLower(lu, indexLU, border, borderSize);
    borderSize = checkInverseLower(uu, 1998, border, borderSize);
    return borderSize;
}
Also used : WlCoef(boofcv.struct.wavelet.WlCoef)

Example 5 with WlCoef

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

the class ImplWaveletTransformBorder method horizontalInverse.

public static void horizontalInverse(BorderIndex1D border, WlBorderCoef<WlCoef_I32> desc, GrayS32 input, GrayS32 output) {
    int[] trends = new int[input.width];
    int[] details = new int[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_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 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 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 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] = UtilWavelet.round(trends[x] * f + details[x] * e, ef2, ef);
        }
        for (int x = paddedWidth - upperCompute; x < output.width; x++) {
            output.data[indexDst + x] = UtilWavelet.round(trends[x] * f + details[x] * e, ef2, ef);
        }
    }
}
Also used : WlCoef_I32(boofcv.struct.wavelet.WlCoef_I32) WlCoef(boofcv.struct.wavelet.WlCoef)

Aggregations

WlCoef (boofcv.struct.wavelet.WlCoef)7 WlCoef_F32 (boofcv.struct.wavelet.WlCoef_F32)2 WlCoef_I32 (boofcv.struct.wavelet.WlCoef_I32)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1