imglib / imglib2-algorithm

Image processing algorithms for ImgLib2
http://imglib2.net/
Other
22 stars 20 forks source link

bspline interpolation #86

Closed bogovicj closed 3 years ago

bogovicj commented 4 years ago

@axtimwalde @tpietzsch

This pull request adds two kinds of BSpline interpolation.

1) On the fly interpolation

The first is most similar to current interpolation methods:

int splineOrder;
boolean clipping;
int radius;
realImg = Views.interpolate( img, new BSplineInterpolatorFactory<>( splineOrder, clipping, radius ));

This computes the interpolation kernel on-the-fly at every get. The kernel size is defined by radius. clipping=true sets the interpolator to behave like the ClampingNLinearInterpolator

2) Precomputed coefficients

The second method precomputes BSpline coefficients and is substantially faster if get is called many times, but at the cost of memory - it allocates a RandomAccessibleInterval<T> the same size as the image to be interpolated. T defaults to DoubleType. Use it like this:

int splineOrder;
boolean clipping;
factory= new BSplineCoefficientsInterpolatorFactory<>( img, splineOrder, clipping );
realImg = Views.interpolate( img, factory);

here the factory constructor computes the coefficients - which is why it needs to be passed. Unfortunately, this means that the img argument to Views.interpolate is meaningless. For example,

realImgFoo = Views.interpolate( img, factory);
realImgBar = Views.interpolate( someOtherImg, factory);

both result in the same thing. We stuck with this to keep the api consistent. No one should be doing the bottom thing anyway.

Generating the coefficients

BSplineDecomposition and BSplineCoefficientsInterpolator give more control for those who need it. For example

/*
 * Compute the coefficients over an arbitrary interval 
 */
BSplineDecomposition<T,S> decomp = new BSplineDecomposition<>( splineOrder,, extendedImg );
long[] min = Intervals.minAsLongArray( interval );
Img<S> coefficientsBase = coefficientFactory.create( interval );
coefficients = Views.translate( coefficientsBase, min );
decomp.accept( coefficients );

/*
 * Get a RealRandomAccess that uses the spline coefficients computed above
 * and using a custom extension of the coefficients
 */
RealRandomAccess interp = BSplineCoefficientsInterpolator.build( 
     splineOrder, 
     Views.extendMirrorSingle( coefficients), 
     new FloatType());
bogovicj commented 4 years ago

Note: don't merge this quite yet, I'm going to add methodology to lazily compute the coefficients block-wise on demand.

tpietzsch commented 4 years ago

Note: don't merge this quite yet, I'm going to add methodology to lazily compute the coefficients block-wise on demand.

You can mark the PR as a draft while you work on it. Then it cannot be merged yet. It's on the right side in the Reviewers tab

Screenshot 2020-06-26 at 11 31 07

bogovicj commented 4 years ago

@axtimwalde From the hotknife repo, I moved org.janelia.saalfeldlab.hotknife.util.Lazy to net.imglib2.lazy.Lazy, removing some of the Ops- related methods

bogovicj commented 4 years ago

TODO - make all added packages children of net.imglib2.algorithm

imagesc-bot commented 3 years ago

This pull request has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/planned-dev-nonlinear-elastix-imglib2-transforms-feedback-requested/31767/22