boofcv.alg.transform.wavelet.impl.ImplWaveletTransformInner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-ip Show documentation
Show all versions of boofcv-ip Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2020, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.transform.wavelet.impl;
import boofcv.alg.transform.wavelet.UtilWavelet;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.GrayS32;
import boofcv.struct.wavelet.WlCoef_F32;
import boofcv.struct.wavelet.WlCoef_I32;
import javax.annotation.Generated;
/**
*
* Standard algorithm for forward and inverse wavelet transform which has been optimized to only
* process the inner portion of the image by excluding the border.
*
*
*
* DO NOT MODIFY: This class was automatically generated by {@link GenerateImplWaveletTransformInner}
*
*
* @author Peter Abeles
*/
@Generated("boofcv.alg.transform.wavelet.impl.GenerateImplWaveletTransformInner")
@SuppressWarnings({"ForLoopReplaceableByForEach"})
public class ImplWaveletTransformInner {
public static void horizontal(WlCoef_F32 coefficients , GrayF32 input , GrayF32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final float[] alpha = coefficients.scaling;
final float[] beta = coefficients.wavelet;
final float dataIn[] = input.data;
final float dataOut[] = output.data;
final int width = output.width;
final int height = input.height;
final int widthD2 = width/2;
final int startX = UtilWavelet.borderForwardLower(coefficients);
final int endOffsetX = input.width - UtilWavelet.borderForwardUpper(coefficients,input.width) - startX;
for( int y = 0; y < height; y++ ) {
int indexIn = input.startIndex + input.stride*y + startX;
int indexOut = output.startIndex + output.stride*y + startX/2;
int end = indexIn + endOffsetX;
for( ; indexIn < end; indexIn += 2 ) {
float scale = 0;
int index = indexIn+offsetA;
for( int i = 0; i < alpha.length; i++ ) {
scale += (dataIn[index++])*alpha[i];
}
float wavelet = 0;
index = indexIn+offsetB;
for( int i = 0; i < beta.length; i++ ) {
wavelet += (dataIn[index++])*beta[i];
}
dataOut[ indexOut+widthD2] = wavelet;
dataOut[ indexOut++ ] = scale;
}
}
}
public static void vertical(WlCoef_F32 coefficients , GrayF32 input , GrayF32 output )
{
final int offsetA = coefficients.offsetScaling*input.stride;
final int offsetB = coefficients.offsetWavelet*input.stride;
final float[] alpha = coefficients.scaling;
final float[] beta = coefficients.wavelet;
final float dataIn[] = input.data;
final float dataOut[] = output.data;
final int width = input.width;
final int height = output.height;
final int heightD2 = (height/2)*output.stride;
final int startY = UtilWavelet.borderForwardLower(coefficients);
final int endY = input.height - UtilWavelet.borderForwardUpper(coefficients,input.width);
for( int y = startY; y < endY; y += 2 ) {
int indexIn = input.startIndex + input.stride*y;
int indexOut = output.startIndex + output.stride*(y/2);
for( int x = 0; x < width; x++, indexIn++) {
float scale = 0;
int index = indexIn + offsetA;
for( int i = 0; i < alpha.length; i++ ) {
scale += (dataIn[index])*alpha[i];
index += input.stride;
}
float wavelet = 0;
index = indexIn + offsetB;
for( int i = 0; i < beta.length; i++ ) {
wavelet += (dataIn[index])*beta[i];
index += input.stride;
}
dataOut[indexOut+heightD2] = wavelet;
dataOut[indexOut++] = scale;
}
}
}
public static void horizontalInverse(WlCoef_F32 coefficients , GrayF32 input , GrayF32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final float[] alpha = coefficients.scaling;
final float[] beta = coefficients.wavelet;
float []trends = new float[ output.width ];
float []details = new float[ output.width ];
final int width = input.width;
final int height = output.height;
final int widthD2 = width/2;
final int lowerBorder = UtilWavelet.borderForwardLower(coefficients);
final int upperBorder = output.width - UtilWavelet.borderForwardUpper(coefficients,output.width);
for( int y = 0; y < height; y++ ) {
// initialize details and trends arrays
int indexSrc = input.startIndex + y*input.stride+lowerBorder/2;
for( int x = lowerBorder; x < upperBorder; x += 2 , indexSrc++ ) {
float a = input.data[ indexSrc ] ;
float d = input.data[ indexSrc + widthD2 ] ;
// add the trend
for( int i = 0; i < 2; i++ )
trends[i+x+offsetA] = a*alpha[i];
// add the detail signal
for( int i = 0; i < 2; i++ )
details[i+x+offsetB] = d*beta[i];
}
for( int i = upperBorder+offsetA; i < upperBorder; i++ )
trends[i] = 0;
for( int i = upperBorder+offsetB; i < upperBorder; i++ )
details[i] = 0;
// perform the normal inverse transform
indexSrc = input.startIndex + y*input.stride+lowerBorder/2;
for( int x = lowerBorder; x < upperBorder; x += 2 , indexSrc++ ) {
float a = input.data[ indexSrc ] ;
float d = input.data[ indexSrc + widthD2 ] ;
// add the trend
for( int i = 2; i < alpha.length; i++ ) {
trends[i+x+offsetA] += a*alpha[i];
}
// add the detail signal
for( int i = 2; i < beta.length; i++ ) {
details[i+x+offsetB] += d*beta[i];
}
}
int indexDst = output.startIndex + y*output.stride + lowerBorder;
for( int x = lowerBorder; x < upperBorder; x++ ) {
output.data[ indexDst++ ] = (trends[x] + details[x]);
}
}
}
public static void verticalInverse(WlCoef_F32 coefficients , GrayF32 input , GrayF32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final float[] alpha = coefficients.scaling;
final float[] beta = coefficients.wavelet;
float []trends = new float[ output.height ];
float []details = new float[ output.height ];
final int width = output.width;
final int height = input.height;
final int heightD2 = (height/2)*input.stride;
final int lowerBorder = UtilWavelet.borderForwardLower(coefficients);
final int upperBorder = output.height - UtilWavelet.borderForwardUpper(coefficients,output.height);
for( int x = 0; x < width; x++) {
int indexSrc = input.startIndex + (lowerBorder/2)*input.stride + x;
for( int y = lowerBorder; y < upperBorder; y += 2 , indexSrc += input.stride ) {
float a = input.data[ indexSrc ] ;
float d = input.data[ indexSrc + heightD2 ] ;
// add the trend
for( int i = 0; i < 2; i++ )
trends[i+y+offsetA] = a*alpha[i];
// add the detail signal
for( int i = 0; i < 2; i++ )
details[i+y+offsetB] = d*beta[i];
}
for( int i = upperBorder+offsetA; i < upperBorder; i++ )
trends[i] = 0;
for( int i = upperBorder+offsetB; i < upperBorder; i++ )
details[i] = 0;
// perform the normal inverse transform
indexSrc = input.startIndex + (lowerBorder/2)*input.stride + x;
for( int y = lowerBorder; y < upperBorder; y += 2 , indexSrc += input.stride ) {
float a = input.data[indexSrc] ;
float d = input.data[indexSrc+heightD2] ;
// add the 'average' signal
for( int i = 2; i < alpha.length; i++ ) {
trends[y+offsetA+i] += a*alpha[i];
}
// add the detail signal
for( int i = 2; i < beta.length; i++ ) {
details[y+offsetB+i] += d*beta[i];
}
}
int indexDst = output.startIndex + x + lowerBorder*output.stride;
for( int y = lowerBorder; y < upperBorder; y++ , indexDst += output.stride ) {
output.data[ indexDst ] = (trends[y] + details[y]);
}
}
}
public static void horizontal(WlCoef_I32 coefficients , GrayS32 input , GrayS32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final int[] alpha = coefficients.scaling;
final int[] beta = coefficients.wavelet;
final int dataIn[] = input.data;
final int dataOut[] = output.data;
final int width = output.width;
final int height = input.height;
final int widthD2 = width/2;
final int startX = UtilWavelet.borderForwardLower(coefficients);
final int endOffsetX = input.width - UtilWavelet.borderForwardUpper(coefficients,input.width) - startX;
for( int y = 0; y < height; y++ ) {
int indexIn = input.startIndex + input.stride*y + startX;
int indexOut = output.startIndex + output.stride*y + startX/2;
int end = indexIn + endOffsetX;
for( ; indexIn < end; indexIn += 2 ) {
int scale = 0;
int index = indexIn+offsetA;
for( int i = 0; i < alpha.length; i++ ) {
scale += (dataIn[index++])*alpha[i];
}
int wavelet = 0;
index = indexIn+offsetB;
for( int i = 0; i < beta.length; i++ ) {
wavelet += (dataIn[index++])*beta[i];
}
scale = 2*scale/coefficients.denominatorScaling;
wavelet = 2*wavelet/coefficients.denominatorWavelet;
dataOut[ indexOut+widthD2] = wavelet;
dataOut[ indexOut++ ] = scale;
}
}
}
public static void vertical(WlCoef_I32 coefficients , GrayS32 input , GrayS32 output )
{
final int offsetA = coefficients.offsetScaling*input.stride;
final int offsetB = coefficients.offsetWavelet*input.stride;
final int[] alpha = coefficients.scaling;
final int[] beta = coefficients.wavelet;
final int dataIn[] = input.data;
final int dataOut[] = output.data;
final int width = input.width;
final int height = output.height;
final int heightD2 = (height/2)*output.stride;
final int startY = UtilWavelet.borderForwardLower(coefficients);
final int endY = input.height - UtilWavelet.borderForwardUpper(coefficients,input.width);
for( int y = startY; y < endY; y += 2 ) {
int indexIn = input.startIndex + input.stride*y;
int indexOut = output.startIndex + output.stride*(y/2);
for( int x = 0; x < width; x++, indexIn++) {
int scale = 0;
int index = indexIn + offsetA;
for( int i = 0; i < alpha.length; i++ ) {
scale += (dataIn[index])*alpha[i];
index += input.stride;
}
int wavelet = 0;
index = indexIn + offsetB;
for( int i = 0; i < beta.length; i++ ) {
wavelet += (dataIn[index])*beta[i];
index += input.stride;
}
scale = 2*scale/coefficients.denominatorScaling;
wavelet = 2*wavelet/coefficients.denominatorWavelet;
dataOut[indexOut+heightD2] = wavelet;
dataOut[indexOut++] = scale;
}
}
}
public static void horizontalInverse(WlCoef_I32 coefficients , GrayS32 input , GrayS32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final int[] alpha = coefficients.scaling;
final int[] beta = coefficients.wavelet;
int []trends = new int[ output.width ];
int []details = new int[ output.width ];
final int width = input.width;
final int height = output.height;
final int widthD2 = width/2;
final int lowerBorder = UtilWavelet.borderForwardLower(coefficients);
final int upperBorder = output.width - UtilWavelet.borderForwardUpper(coefficients,output.width);
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
int indexSrc = input.startIndex + y*input.stride+lowerBorder/2;
for( int x = lowerBorder; x < upperBorder; x += 2 , indexSrc++ ) {
int a = input.data[ indexSrc ] ;
int d = input.data[ indexSrc + widthD2 ] ;
// add the trend
for( int i = 0; i < 2; i++ )
trends[i+x+offsetA] = a*alpha[i];
// add the detail signal
for( int i = 0; i < 2; i++ )
details[i+x+offsetB] = d*beta[i];
}
for( int i = upperBorder+offsetA; i < upperBorder; i++ )
trends[i] = 0;
for( int i = upperBorder+offsetB; i < upperBorder; i++ )
details[i] = 0;
// perform the normal inverse transform
indexSrc = input.startIndex + y*input.stride+lowerBorder/2;
for( int x = lowerBorder; x < upperBorder; x += 2 , indexSrc++ ) {
int a = input.data[ indexSrc ] ;
int d = input.data[ indexSrc + widthD2 ] ;
// add the trend
for( int i = 2; i < alpha.length; i++ ) {
trends[i+x+offsetA] += a*alpha[i];
}
// add the detail signal
for( int i = 2; i < beta.length; i++ ) {
details[i+x+offsetB] += d*beta[i];
}
}
int indexDst = output.startIndex + y*output.stride + lowerBorder;
for( int x = lowerBorder; x < upperBorder; x++ ) {
output.data[ indexDst++ ] = UtilWavelet.round(trends[x]*f + details[x]*e , ef2,ef);
}
}
}
public static void verticalInverse(WlCoef_I32 coefficients , GrayS32 input , GrayS32 output )
{
final int offsetA = coefficients.offsetScaling;
final int offsetB = coefficients.offsetWavelet;
final int[] alpha = coefficients.scaling;
final int[] beta = coefficients.wavelet;
int []trends = new int[ output.height ];
int []details = new int[ output.height ];
final int width = output.width;
final int height = input.height;
final int heightD2 = (height/2)*input.stride;
final int lowerBorder = UtilWavelet.borderForwardLower(coefficients);
final int upperBorder = output.height - UtilWavelet.borderForwardUpper(coefficients,output.height);
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++) {
int indexSrc = input.startIndex + (lowerBorder/2)*input.stride + x;
for( int y = lowerBorder; y < upperBorder; y += 2 , indexSrc += input.stride ) {
int a = input.data[ indexSrc ] ;
int d = input.data[ indexSrc + heightD2 ] ;
// add the trend
for( int i = 0; i < 2; i++ )
trends[i+y+offsetA] = a*alpha[i];
// add the detail signal
for( int i = 0; i < 2; i++ )
details[i+y+offsetB] = d*beta[i];
}
for( int i = upperBorder+offsetA; i < upperBorder; i++ )
trends[i] = 0;
for( int i = upperBorder+offsetB; i < upperBorder; i++ )
details[i] = 0;
// perform the normal inverse transform
indexSrc = input.startIndex + (lowerBorder/2)*input.stride + x;
for( int y = lowerBorder; y < upperBorder; y += 2 , indexSrc += input.stride ) {
int a = input.data[indexSrc] ;
int d = input.data[indexSrc+heightD2] ;
// add the 'average' signal
for( int i = 2; i < alpha.length; i++ ) {
trends[y+offsetA+i] += a*alpha[i];
}
// add the detail signal
for( int i = 2; i < beta.length; i++ ) {
details[y+offsetB+i] += d*beta[i];
}
}
int indexDst = output.startIndex + x + lowerBorder*output.stride;
for( int y = lowerBorder; y < upperBorder; y++ , indexDst += output.stride ) {
output.data[ indexDst ] = UtilWavelet.round(trends[y]*f + details[y]*e , ef2 , ef);
}
}
}
}