/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.image.interpolation; import org.geotoolkit.image.iterator.PixelIterator; /** * <p>This interpolator may produce somewhat sharper results than classic * classic BiCubic Interpolation, but that result is image dependent.<br/> * It's a consequence from increase of biCubic curve amplitude.<br/> * It use the parameter 'a' recommended by Keys.<br/> * (Reference: Digital Image Warping, George Wolberg, 1990, pp 129-131, IEEE Computer Society Press, ISBN 0-8186-8944-7)</p> * * @author RĂ©mi Marechal (Geomatys). */ public class BiCubicInterpolation2 extends BiCubicInterpolation { /** * <p>Parameter use in "cubic convolution" computing.<br/> * a equal -0.5 for classic biCubic interpolation.<br/> * a equal -1.0 for more amplitude between interpolation results.</p> * * @see #getConvolutionValue(double) . */ private final double a = -1.0; /** * {@inheritDoc }. */ public BiCubicInterpolation2(PixelIterator pixelIterator, ResampleBorderComportement rbc, double[] fillValue) { super(pixelIterator, rbc, fillValue); } /** * {@inheritDoc }. */ public BiCubicInterpolation2(PixelIterator pixelIterator) { super(pixelIterator); } /** * Compute coefficient apply on current pixel value. * Compute value of Kernel filter. * * @param t difference between interpolation position and pixel position. * t >= 0 && t<2. * @return Kernel filter value. */ private double getConvolutionValue(double t) { final double tAbs = Math.abs(t); if (tAbs <= 1) { return ((a+2)*tAbs - (a+3))*tAbs*tAbs + 1;//(a + 2)|x|^3 - (a + 3)|x|^2 + 1 } else if(tAbs >1 && tAbs < 2) { return (((tAbs - 5)*tAbs + 8)*tAbs - 4)*a;// a|x|^3 - 5a|x|^2 + 8a|x| - 4a } else { return 0; } } /** * {@inheritDoc } * * Cubic interpolation from 4 values.<br/> * With always t0 <= t<= t0 + 3 <br/> * <p>For example : cubic interpolation between 4 pixels.<br/> * * *    t =   0  1  2  3<br/> * f(t) = |f0|f1|f2|f3|<br/> * In this example t0 = 0.<br/><br/> * * Another example :<br/> *    t =  -5 -4 -3 -2<br/> * f(t) = |f0|f1|f2|f3|<br/> * In this example parameter t0 = -5.</p> * * @param t0 f(t0) = f[0].Current position from first pixel interpolation. * @param t position of interpolation. * @param f pixel values from t = {0, 1, 2, 3}. * @return cubic interpolation at t position. */ @Override protected double interpolate1D(double t0, double t, double... f) { assert (f.length == 4) : "impossible to interpolate with less or more than 4 values"; double res = 0; int compteur = 0; for (double ft : f) { res += getConvolutionValue(t-t0 - compteur++)*ft; } return checkValue(res); } }