diff --git a/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java new file mode 100644 index 000000000..e4615dc69 --- /dev/null +++ b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java @@ -0,0 +1,85 @@ +package net.imglib2.interpolation.neighborsearch; + +import java.util.function.DoubleUnaryOperator; + +import net.imglib2.KDTree; +import net.imglib2.RealPoint; +import net.imglib2.RealRandomAccess; +import net.imglib2.neighborsearch.RadiusNeighborSearch; +import net.imglib2.neighborsearch.RadiusNeighborSearchOnKDTree; +import net.imglib2.type.numeric.NumericType; + +/** + * A {@link RealRandomAccess} for {@link KDTree}s using a radial function used + * by {@link RadialKDTreeInterpolatorFactory}. + */ +public class RadialKDTreeInterpolator< T extends NumericType< T > > extends RealPoint implements RealRandomAccess< T > +{ + protected static final double minThreshold = Double.MIN_VALUE * 1000; + + protected final RadiusNeighborSearch< T > search; + + protected final double maxRadius; + + protected final double maxSquaredRadius; + + protected final KDTree< T > tree; + + protected final T value; + + protected final T tmp; + + protected final DoubleUnaryOperator squaredRadiusFunction; + + public RadialKDTreeInterpolator( + final KDTree< T > tree, + final DoubleUnaryOperator squaredRadiusFunction, + final double maxRadius, + final T t ) + { + super( tree.numDimensions() ); + + this.squaredRadiusFunction = squaredRadiusFunction; + this.tree = tree; + this.search = new RadiusNeighborSearchOnKDTree< T >( tree ); + this.maxRadius = maxRadius; + this.maxSquaredRadius = maxRadius * maxRadius; + this.value = t.copy(); + this.tmp = t.copy(); + } + + public double getMaxRadius() + { + return maxRadius; + } + + @Override + public T get() + { + value.setZero(); + search.search( this, maxRadius, false ); + if ( search.numNeighbors() == 0 ) + return value; + + for ( int i = 0; i < search.numNeighbors(); ++i ) + { + // can't multiply the value returned + tmp.set( search.getSampler( i ).get() ); + tmp.mul( squaredRadiusFunction.applyAsDouble( search.getSquareDistance( i ) ) ); + value.add( tmp ); + } + return value; + } + + @Override + public RadialKDTreeInterpolator< T > copy() + { + return new RadialKDTreeInterpolator< T >( tree, squaredRadiusFunction, maxRadius, value ); + } + + @Override + public RadialKDTreeInterpolator< T > copyRealRandomAccess() + { + return copy(); + } +} diff --git a/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java new file mode 100644 index 000000000..a4463202a --- /dev/null +++ b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java @@ -0,0 +1,47 @@ +package net.imglib2.interpolation.neighborsearch; + +import java.util.function.DoubleUnaryOperator; + +import net.imglib2.KDTree; +import net.imglib2.RealInterval; +import net.imglib2.RealRandomAccess; +import net.imglib2.interpolation.InterpolatorFactory; +import net.imglib2.type.numeric.NumericType; + +/** + * An {@link InterpolatorFactory} for {@link KDTree}s using a radial function. + *

+ * The resulting {@link RealRandomAccess} produced by this InterpolatorFactory + * returns values as a linear combination of all points within a certain radius. + * The contribution of each point is weighted according to a function of its + * squared radius. + */ +public class RadialKDTreeInterpolatorFactory< T extends NumericType< T > > implements InterpolatorFactory< T, KDTree< T > > +{ + protected final double maxRadius; + + protected final DoubleUnaryOperator squaredRadiusFunction; + + protected final T val; + + public RadialKDTreeInterpolatorFactory( + final DoubleUnaryOperator squaredRadiusFunction, + final double maxRadius, final T t ) + { + this.maxRadius = maxRadius; + this.squaredRadiusFunction = squaredRadiusFunction; + this.val = t; + } + + @Override + public RadialKDTreeInterpolator< T > create( final KDTree< T > tree ) + { + return new RadialKDTreeInterpolator< T >( tree, squaredRadiusFunction, maxRadius, val ); + } + + @Override + public RealRandomAccess< T > create( final KDTree< T > tree, final RealInterval interval ) + { + return create( tree ); + } +}