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);
}
}
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]);
}
}
}
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);
}
}
}
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;
}
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);
}
}
}
Aggregations