You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2020/03/26 00:17:53 UTC
[sis] branch geoapi-4.0 updated: Add Lanczos interpolation
(experimental).
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new bc36b68 Add Lanczos interpolation (experimental).
bc36b68 is described below
commit bc36b680ccf811df33986a1b0c4ce5db79cf975a
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Thu Mar 26 01:15:04 2020 +0100
Add Lanczos interpolation (experimental).
---
.../java/org/apache/sis/image/Interpolation.java | 13 +++
.../org/apache/sis/image/LanczosInterpolation.java | 114 +++++++++++++++++++++
2 files changed, 127 insertions(+)
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java b/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java
index f5d8bd3..cdb0498 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java
@@ -27,6 +27,7 @@ import java.nio.DoubleBuffer;
*
* <p>This interface is designed for interpolations in a two-dimensional space only.</p>
*
+ * @author Rémi Marechal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
* @author Johann Sorel (Geomatys)
* @version 1.1
@@ -131,4 +132,16 @@ public interface Interpolation {
return true;
}
};
+
+ /**
+ * Lanczos interpolation. The kernel is:
+ *
+ * <blockquote>
+ * <var>L</var>(<var>x</var>) = <var>a</var>⋅sin(π⋅<var>x</var>)⋅sin(π⋅<var>x</var>/<var>a</var>)/(π⋅<var>x</var>)²
+ * for |<var>x</var>| ≤ lanczos window size
+ * </blockquote>
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Lanczos_resampling">Lanczos resampling on Wikipedia</a>
+ */
+ Interpolation LANCZOS = new LanczosInterpolation(2);
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java b/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java
new file mode 100644
index 0000000..138df5f
--- /dev/null
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.image;
+
+import java.util.Arrays;
+import java.awt.Dimension;
+import java.nio.DoubleBuffer;
+
+
+/**
+ * Lanczos interpolation of arbitrary size.
+ * The kernel is:
+ *
+ * <blockquote>
+ * <var>L</var>(<var>x</var>) = <var>a</var>⋅sin(π⋅<var>x</var>)⋅sin(π⋅<var>x</var>/<var>a</var>)/(π⋅<var>x</var>)²
+ * for |<var>x</var>| ≤ lanczos window size
+ * </blockquote>
+ *
+ * @author Rémi Marechal (Geomatys)
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.1
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Lanczos_resampling">Lanczos resampling on Wikipedia</a>
+ *
+ * @since 1.1
+ * @module
+ */
+final class LanczosInterpolation implements Interpolation {
+ /**
+ * The Lanczos window size. This is denoted <var>a</var> in this class javadoc.
+ */
+ private final double a;
+
+ /**
+ * Width of the interpolation support region.
+ */
+ private final int span;
+
+ /**
+ * Creates a new interpolation.
+ *
+ * @param a the Lanczos window size.
+ */
+ LanczosInterpolation(final int a) {
+ this.a = a;
+ span = 2*a;
+ }
+
+ /**
+ * Interpolation name for debugging purpose.
+ */
+ @Override
+ public String toString() {
+ return "LANCZOS";
+ }
+
+ /**
+ * Size of the area over which to provide values.
+ */
+ @Override
+ public Dimension getSupportSize() {
+ return new Dimension(span, span);
+ }
+
+ /**
+ * Applies Lanczos interpolation.
+ */
+ @Override
+ public boolean interpolate(final DoubleBuffer source, final int numBands,
+ final double xfrac, final double yfrac, final double[] writeTo, final int writeToOffset)
+ {
+ Arrays.fill(writeTo, writeToOffset, writeToOffset + numBands, 0);
+ final double[] kx = new double[span];
+ final double[] ky = new double[span];
+ for (int i=0; i<span; i++) {
+ final double offset = i - a;
+ kx[i] = kernel(offset + xfrac);
+ ky[i] = kernel(offset + yfrac);
+ }
+ source.mark();
+ for (int y=0; y<span; y++) {
+ for (int x=0; x<span; x++) {
+ final double k = kx[x] * ky[y];
+ for (int b=0; b<numBands; b++) {
+ writeTo[writeToOffset + b] += k * source.get();
+ }
+ }
+ }
+ source.reset();
+ return true;
+ }
+
+ /**
+ * Computes a value of the Lanczos reconstruction kernel L(x).
+ */
+ private double kernel(double x) {
+ x *= Math.PI;
+ return (x != 0) ? Math.sin(x) * Math.sin(x/a)*a / (x*x) : 1;
+ }
+}