All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.transform.wavelet.impl.ImplWaveletTransformNaive Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.6
Show newest version
/*
 * Copyright (c) 2011-2017, 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.core.image.border.BorderIndex1D;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.GrayI;
import boofcv.struct.wavelet.WlBorderCoef;
import boofcv.struct.wavelet.WlCoef_F32;
import boofcv.struct.wavelet.WlCoef_I32;


/**
 * 

* Unoptimized and simplistic implementation of a forward and inverse wavelet transform across one * level. Primary used for validation testing. *

* *

* DO NOT MODIFY: This class was automatically generated by {@link GenerateImplWaveletTransformNaive}. *

* * @author Peter Abeles */ public class ImplWaveletTransformNaive { /** * Performs a single level wavelet transform along the horizontal axis. * * @param coefficients Description of wavelet coefficients. * @param input Input image which is being transform. Not modified. * @param output where the output is written to. Modified */ public static void horizontal(BorderIndex1D border , WlCoef_F32 coefficients , GrayF32 input , GrayF32 output ) { UtilWavelet.checkShape(input,output); final int offsetA = coefficients.offsetScaling; final int offsetB = coefficients.offsetWavelet; final float[] alpha = coefficients.scaling; final float[] beta = coefficients.wavelet; border.setLength(input.width+input.width%2); final boolean isLarger = output.width > input.width; for( int y = 0; y < input.height; y++ ) { for( int x = 0; x < input.width; x += 2 ) { float scale = 0; float wavelet = 0; for( int i = 0; i < alpha.length; i++ ) { int xx = border.getIndex(x+i+offsetA); if( isLarger && xx >= input.width ) continue; scale += input.get(xx,y)*alpha[i]; } for( int i = 0; i < beta.length; i++ ) { int xx = border.getIndex(x+i+offsetB); if( isLarger && xx >= input.width ) continue; wavelet += input.get(xx,y)*beta[i]; } int outX = x/2; output.set(outX,y,scale); output.set(output.width/2 + outX , y , wavelet ); } } } /** * Performs a single level wavelet transform along the vertical axis. * * @param coefficients Description of wavelet coefficients. * @param input Input image which is being transform. Not modified. * @param output where the output is written to. Modified */ public static void vertical(BorderIndex1D border , WlCoef_F32 coefficients , GrayF32 input , GrayF32 output ) { UtilWavelet.checkShape(input,output); final int offsetA = coefficients.offsetScaling; final int offsetB = coefficients.offsetWavelet; final float[] alpha = coefficients.scaling; final float[] beta = coefficients.wavelet; border.setLength(input.height+input.height%2); boolean isLarger = output.height > input.height; for( int x = 0; x < input.width; x++) { for( int y = 0; y < input.height; y += 2 ) { float scale = 0; float wavelet = 0; for( int i = 0; i < alpha.length; i++ ) { int yy = border.getIndex(y+i+offsetA); if( isLarger && yy >= input.height ) continue; scale += input.get(x,yy)*alpha[i]; } for( int i = 0; i < beta.length; i++ ) { int yy = border.getIndex(y+i+offsetB); if( isLarger && yy >= input.height ) continue; wavelet += input.get(x,yy)*beta[i]; } int outY = y/2; output.set(x , outY,scale); output.set(x , output.height/2 + outY , wavelet ); } } } /** * 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 inverseCoef , GrayF32 input , GrayF32 output ) { UtilWavelet.checkShape(output,input); float []trends = new float[ output.width ]; float []details = new float[ 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_F32 coefficients; 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 ) { float a = input.get(x/2,y); float 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 float[] alpha = coefficients.scaling; final float[] 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, trends[x] + details[x]); } } } /** * Performs a single level inverse wavelet transform along the vertical axis. * * @param inverseCoef Description of wavelet coefficients. * @param input Transformed image. Not modified. * @param output Reconstruction of original image. Modified */ public static void verticalInverse(BorderIndex1D border , WlBorderCoef inverseCoef , GrayF32 input , GrayF32 output ) { UtilWavelet.checkShape(output,input); float []trends = new float[ output.height ]; float []details = new float[ output.height ]; boolean isLarger = input.height > output.height; int paddedHeight = output.height + output.height%2; final int lowerBorder = inverseCoef.getLowerLength()*2; final int upperBorder = output.height - inverseCoef.getUpperLength()*2; border.setLength(output.height+output.height%2); WlCoef_F32 coefficients; for( int x = 0; x < output.width; x++) { for( int i = 0; i < details.length; i++ ) { details[i] = 0; trends[i] = 0; } for( int y = 0; y < output.height; y += 2 ) { float a = input.get(x,y/2); float d = input.get(x,y/2+input.height/2); if( y < lowerBorder ) { coefficients = inverseCoef.getBorderCoefficients(y); } else if( y >= upperBorder ) { coefficients = inverseCoef.getBorderCoefficients(y-paddedHeight); } else { coefficients = inverseCoef.getInnerCoefficients(); } final int offsetA = coefficients.offsetScaling; final int offsetB = coefficients.offsetWavelet; final float[] alpha = coefficients.scaling; final float[] beta = coefficients.wavelet; // add the 'average' signal for( int i = 0; i < alpha.length; i++ ) { // if an odd image don't update the outer edge int yy = border.getIndex(y+offsetA+i); if( isLarger && yy >= output.height ) continue; trends[yy] += a*alpha[i]; } // add the detail signal for( int i = 0; i < beta.length; i++ ) { int yy = border.getIndex(y+offsetB+i); if( isLarger && yy >= output.height ) continue; details[yy] += d*beta[i]; } } for( int y = 0; y < output.height; y++ ) { output.set(x,y, trends[y] + details[y]); } } } /** * Performs a single level wavelet transform along the horizontal axis. * * @param coefficients Description of wavelet coefficients. * @param input Input image which is being transform. Not modified. * @param output where the output is written to. Modified */ public static void horizontal(BorderIndex1D border , WlCoef_I32 coefficients , GrayI input , GrayI output ) { UtilWavelet.checkShape(input,output); final int offsetA = coefficients.offsetScaling; final int offsetB = coefficients.offsetWavelet; final int[] alpha = coefficients.scaling; final int[] beta = coefficients.wavelet; border.setLength(input.width+input.width%2); final boolean isLarger = output.width > input.width; for( int y = 0; y < input.height; y++ ) { for( int x = 0; x < input.width; x += 2 ) { int scale = 0; int wavelet = 0; for( int i = 0; i < alpha.length; i++ ) { int xx = border.getIndex(x+i+offsetA); if( isLarger && xx >= input.width ) continue; scale += input.get(xx,y)*alpha[i]; } for( int i = 0; i < beta.length; i++ ) { int xx = border.getIndex(x+i+offsetB); if( isLarger && xx >= input.width ) continue; wavelet += input.get(xx,y)*beta[i]; } int outX = x/2; scale = 2*scale/coefficients.denominatorScaling; wavelet = 2*wavelet/coefficients.denominatorWavelet; output.set(outX,y,scale); output.set(output.width/2 + outX , y , wavelet ); } } } /** * Performs a single level wavelet transform along the vertical axis. * * @param coefficients Description of wavelet coefficients. * @param input Input image which is being transform. Not modified. * @param output where the output is written to. Modified */ public static void vertical(BorderIndex1D border , WlCoef_I32 coefficients , GrayI input , GrayI output ) { UtilWavelet.checkShape(input,output); final int offsetA = coefficients.offsetScaling; final int offsetB = coefficients.offsetWavelet; final int[] alpha = coefficients.scaling; final int[] beta = coefficients.wavelet; border.setLength(input.height+input.height%2); boolean isLarger = output.height > input.height; for( int x = 0; x < input.width; x++) { for( int y = 0; y < input.height; y += 2 ) { int scale = 0; int wavelet = 0; for( int i = 0; i < alpha.length; i++ ) { int yy = border.getIndex(y+i+offsetA); if( isLarger && yy >= input.height ) continue; scale += input.get(x,yy)*alpha[i]; } for( int i = 0; i < beta.length; i++ ) { int yy = border.getIndex(y+i+offsetB); if( isLarger && yy >= input.height ) continue; wavelet += input.get(x,yy)*beta[i]; } int outY = y/2; scale = 2*scale/coefficients.denominatorScaling; wavelet = 2*wavelet/coefficients.denominatorWavelet; output.set(x , outY,scale); output.set(x , output.height/2 + outY , wavelet ); } } } /** * 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 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)); } } } /** * Performs a single level inverse wavelet transform along the vertical axis. * * @param inverseCoef Description of wavelet coefficients. * @param input Transformed image. Not modified. * @param output Reconstruction of original image. Modified */ public static void verticalInverse(BorderIndex1D border , WlBorderCoef inverseCoef , GrayI input , GrayI output ) { UtilWavelet.checkShape(output,input); int []trends = new int[ output.height ]; int []details = new int[ output.height ]; boolean isLarger = input.height > output.height; int paddedHeight = output.height + output.height%2; final int lowerBorder = inverseCoef.getLowerLength()*2; final int upperBorder = output.height - inverseCoef.getUpperLength()*2; border.setLength(output.height+output.height%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 x = 0; x < output.width; x++) { for( int i = 0; i < details.length; i++ ) { details[i] = 0; trends[i] = 0; } for( int y = 0; y < output.height; y += 2 ) { int a = input.get(x,y/2); int d = input.get(x,y/2+input.height/2); if( y < lowerBorder ) { coefficients = inverseCoef.getBorderCoefficients(y); } else if( y >= upperBorder ) { coefficients = inverseCoef.getBorderCoefficients(y-paddedHeight); } 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 'average' signal for( int i = 0; i < alpha.length; i++ ) { // if an odd image don't update the outer edge int yy = border.getIndex(y+offsetA+i); if( isLarger && yy >= output.height ) continue; trends[yy] += a*alpha[i]; } // add the detail signal for( int i = 0; i < beta.length; i++ ) { int yy = border.getIndex(y+offsetB+i); if( isLarger && yy >= output.height ) continue; details[yy] += d*beta[i]; } } for( int y = 0; y < output.height; y++ ) { output.set(x,y, UtilWavelet.round(trends[y]*f + details[y]*e,ef2,ef)); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy