001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.lib.interpolation; 011 012import imagingbook.lib.image.ImageAccessor; 013 014public class LanczosInterpolator extends PixelInterpolator { 015 016 private final int order; // order (tap count) of this interpolator 017 018 public LanczosInterpolator(ImageAccessor.Scalar ia) { 019 this(2); 020 } 021 022 public LanczosInterpolator(int N) { 023 super(); 024 this.order = N; // order >= 2 025 } 026 027 @Override 028 public float getInterpolatedValue(ImageAccessor.Scalar ia, double x, double y) { 029 final int u0 = (int) Math.floor(x); //use floor to handle negative coordinates too 030 final int v0 = (int) Math.floor(y); 031 double q = 0; 032 for (int j = 0; j <= 2*order-1; j++) { 033 int v = v0 + j - order + 1; 034 double p = 0; 035 for (int i = 0; i <= 2*order-1; i++) { 036 int u = u0 + i - order + 1; 037 float pixval = ia.getVal(u, v); 038 p = p + pixval * w_Ln(x - u); 039 } 040 q = q + p * w_Ln(y - v); 041 } 042 return (float) q; 043 } 044 045 046 static final double pi = Math.PI; 047 static final double pi2 = pi*pi; 048 049 private double w_Ln(double x) { // 1D Lanczos interpolator of order n 050 x = Math.abs(x); 051 if (x < 0.001) return 1.0; 052 if (x < order) { 053 return order * (Math.sin(pi*x / order) * Math.sin(pi * x)) / (pi2 * x * x); 054 } 055 else return 0.0; 056 } 057 058 059}