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 ip Show documentation
Show all versions of ip Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2013, 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.ImageFloat32;
import boofcv.struct.image.ImageSInt32;
import boofcv.struct.wavelet.WlCoef_F32;
import boofcv.struct.wavelet.WlCoef_I32;
/**
*
* 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
*/
@SuppressWarnings({"ForLoopReplaceableByForEach"})
public class ImplWaveletTransformInner {
public static void horizontal( WlCoef_F32 coefficients , ImageFloat32 input , ImageFloat32 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 , ImageFloat32 input , ImageFloat32 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 , ImageFloat32 input , ImageFloat32 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 , ImageFloat32 input , ImageFloat32 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 , ImageSInt32 input , ImageSInt32 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 , ImageSInt32 input , ImageSInt32 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 , ImageSInt32 input , ImageSInt32 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 , ImageSInt32 input , ImageSInt32 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);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy