diff --git a/src/main/java/net/imagej/ops/deconvolve/DeconvolveNamespace.java b/src/main/java/net/imagej/ops/deconvolve/DeconvolveNamespace.java index bf01bc5350..09860295be 100644 --- a/src/main/java/net/imagej/ops/deconvolve/DeconvolveNamespace.java +++ b/src/main/java/net/imagej/ops/deconvolve/DeconvolveNamespace.java @@ -141,8 +141,7 @@ RandomAccessibleInterval richardsonLucy( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyF.class) - public < - I extends RealType, O extends RealType & NativeType, K extends RealType, C extends ComplexType> + public , O extends RealType & NativeType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -159,8 +158,7 @@ RandomAccessibleInterval richardsonLucy( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyF.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -178,8 +176,7 @@ RandomAccessibleInterval richardsonLucy( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyF.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -199,48 +196,73 @@ RandomAccessibleInterval richardsonLucy( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval richardsonLucy( + final RandomAccessibleInterval out, + final RandomAccessibleInterval in1, + final RandomAccessibleInterval in2, final int maxIterations) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run( + net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, + maxIterations); + return result; + } + + @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval richardsonLucy( + final RandomAccessibleInterval out, + final RandomAccessibleInterval in1, + final RandomAccessibleInterval in2, + final RandomAccessibleInterval fftInput, final int maxIterations) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run( + net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, + fftInput, maxIterations); + return result; + } + + @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, final RandomAccessibleInterval in2, final RandomAccessibleInterval fftInput, - final RandomAccessibleInterval fftKernel, final int maxIterations, - final Interval imgConvolutionInterval) + final RandomAccessibleInterval fftKernel, final int maxIterations) { @SuppressWarnings("unchecked") final RandomAccessibleInterval result = (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, - fftInput, fftKernel, maxIterations, imgConvolutionInterval); + fftInput, fftKernel, maxIterations); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, final RandomAccessibleInterval in2, final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, - final boolean performInputFFT, final int maxIterations, - final Interval imgConvolutionInterval) + final boolean performInputFFT, final int maxIterations) { @SuppressWarnings("unchecked") final RandomAccessibleInterval result = (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, - fftInput, fftKernel, performInputFFT, maxIterations, - imgConvolutionInterval); + fftInput, fftKernel, performInputFFT, maxIterations); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -248,20 +270,18 @@ RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, final boolean performInputFFT, final boolean performKernelFFT, - final int maxIterations, final Interval imgConvolutionInterval) + final int maxIterations) { @SuppressWarnings("unchecked") final RandomAccessibleInterval result = (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, - fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations, - imgConvolutionInterval); + fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -269,21 +289,19 @@ RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, final boolean performInputFFT, final boolean performKernelFFT, - final int maxIterations, final Interval imgConvolutionInterval, - final UnaryInplaceOp accelerator) + final int maxIterations, final UnaryInplaceOp accelerator) { @SuppressWarnings("unchecked") final RandomAccessibleInterval result = (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations, - imgConvolutionInterval, accelerator); + accelerator); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -291,8 +309,7 @@ RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, final boolean performInputFFT, final boolean performKernelFFT, - final int maxIterations, final Interval imgConvolutionInterval, - final UnaryInplaceOp accelerator, + final int maxIterations, final UnaryInplaceOp accelerator, final UnaryComputerOp, RandomAccessibleInterval> update) { @SuppressWarnings("unchecked") @@ -300,13 +317,12 @@ RandomAccessibleInterval richardsonLucy( (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations, - imgConvolutionInterval, accelerator, update); + accelerator, update); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -314,8 +330,7 @@ RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, final boolean performInputFFT, final boolean performKernelFFT, - final int maxIterations, final Interval imgConvolutionInterval, - final UnaryInplaceOp accelerator, + final int maxIterations, final UnaryInplaceOp accelerator, final UnaryComputerOp, RandomAccessibleInterval> update, RandomAccessibleInterval raiExtendedEstimate) { @@ -324,13 +339,12 @@ RandomAccessibleInterval richardsonLucy( (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations, - imgConvolutionInterval, accelerator, update, raiExtendedEstimate); + accelerator, update, raiExtendedEstimate); return result; } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyC.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -338,8 +352,7 @@ RandomAccessibleInterval richardsonLucy( final RandomAccessibleInterval fftInput, final RandomAccessibleInterval fftKernel, final boolean performInputFFT, final boolean performKernelFFT, - final int maxIterations, final Interval imgConvolutionInterval, - final UnaryInplaceOp accelerator, + final int maxIterations, final UnaryInplaceOp accelerator, final UnaryComputerOp, RandomAccessibleInterval> update, RandomAccessibleInterval raiExtendedEstimate, final ArrayList, RandomAccessibleInterval>> iterativePostProcessing) @@ -349,8 +362,7 @@ RandomAccessibleInterval richardsonLucy( (RandomAccessibleInterval) ops().run( net.imagej.ops.deconvolve.RichardsonLucyC.class, out, in1, in2, fftInput, fftKernel, performInputFFT, performKernelFFT, maxIterations, - imgConvolutionInterval, accelerator, update, raiExtendedEstimate, - iterativePostProcessing); + accelerator, update, raiExtendedEstimate, iterativePostProcessing); return result; } @@ -439,8 +451,7 @@ RandomAccessibleInterval richardsonLucyTV( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyTVF.class) - public < - I extends RealType, O extends RealType & NativeType, K extends RealType, C extends ComplexType> + public , O extends RealType & NativeType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucyTV( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -459,8 +470,7 @@ RandomAccessibleInterval richardsonLucyTV( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyTVF.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucyTV( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -479,8 +489,7 @@ RandomAccessibleInterval richardsonLucyTV( } @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyTVF.class) - public < - I extends RealType, O extends RealType, K extends RealType, C extends ComplexType> + public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucyTV( final RandomAccessibleInterval in, final RandomAccessibleInterval kernel, final long[] borderSize, @@ -502,8 +511,7 @@ RandomAccessibleInterval richardsonLucyTV( // -- richardson lucy correction ops @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyCorrection.class) - public < - I extends RealType, O extends RealType, C extends ComplexType> + public , O extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucyCorrection( final RandomAccessibleInterval out, final RandomAccessibleInterval in1, @@ -522,8 +530,7 @@ RandomAccessibleInterval richardsonLucyCorrection( // -- richardson lucy update ops @OpMethod(op = net.imagej.ops.deconvolve.RichardsonLucyTVUpdate.class) - public < - I extends RealType, O extends RealType, C extends ComplexType> + public , O extends RealType, C extends ComplexType> RandomAccessibleInterval richardsonLucyUpdate( final RandomAccessibleInterval out, final RandomAccessibleInterval in, final float regularizationFactor) diff --git a/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyC.java b/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyC.java index e99c9ca4fc..1730322887 100644 --- a/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyC.java +++ b/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyC.java @@ -60,8 +60,8 @@ /** * Richardson Lucy algorithm for (@link RandomAccessibleInterval) (Lucy, L. B. - * (1974). - * "An iterative technique for the rectification of observed distributions".) + * (1974). "An iterative technique for the rectification of observed + * distributions".) * * @author Brian Northan * @param @@ -70,8 +70,7 @@ * @param */ -@Plugin(type = Ops.Deconvolve.RichardsonLucy.class, - priority = Priority.HIGH) +@Plugin(type = Ops.Deconvolve.RichardsonLucy.class, priority = Priority.HIGH) public class RichardsonLucyC, O extends RealType, K extends RealType, C extends ComplexType> extends AbstractIterativeFFTFilterC implements Ops.Deconvolve.RichardsonLucy @@ -155,17 +154,27 @@ public void initialize() { public void compute(RandomAccessibleInterval in, RandomAccessibleInterval kernel, RandomAccessibleInterval out) { + // create FFT input memory if needed + if (getFFTInput() == null) { + setFFTInput(getCreateOp().calculate(in)); + } + + // create FFT kernel memory if needed + if (getFFTKernel() == null) { + setFFTKernel(getCreateOp().calculate(in)); + } + // if a starting point for the estimate was not passed in then create // estimate Img and use the input as the starting point if (raiExtendedEstimate == null) { - raiExtendedEstimate = createOp.calculate(getImgConvolutionInterval()); + raiExtendedEstimate = createOp.calculate(in); copyOp.compute(in, raiExtendedEstimate); } // create image for the reblurred - raiExtendedReblurred = createOp.calculate(getImgConvolutionInterval()); + raiExtendedReblurred = createOp.calculate(in); // perform fft of psf fftKernelOp.compute(kernel, getFFTKernel()); diff --git a/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyF.java b/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyF.java index 1379ad3b39..1bdd2ffa74 100644 --- a/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyF.java +++ b/src/main/java/net/imagej/ops/deconvolve/RichardsonLucyF.java @@ -42,7 +42,6 @@ import net.imagej.ops.special.function.UnaryFunctionOp; import net.imagej.ops.special.inplace.Inplaces; import net.imagej.ops.special.inplace.UnaryInplaceOp; -import net.imglib2.Interval; import net.imglib2.RandomAccessibleInterval; import net.imglib2.outofbounds.OutOfBoundsConstantValueFactory; import net.imglib2.outofbounds.OutOfBoundsMirrorFactory; @@ -58,8 +57,8 @@ /** * Richardson Lucy function op that operates on (@link RandomAccessibleInterval) - * (Lucy, L. B. (1974). - * "An iterative technique for the rectification of observed distributions".) + * (Lucy, L. B. (1974). "An iterative technique for the rectification of + * observed distributions".) * * @author Brian Northan * @param @@ -67,8 +66,7 @@ * @param * @param */ -@Plugin(type = Ops.Deconvolve.RichardsonLucy.class, - priority = Priority.HIGH) +@Plugin(type = Ops.Deconvolve.RichardsonLucy.class, priority = Priority.HIGH) public class RichardsonLucyF & NativeType, O extends RealType & NativeType, K extends RealType & NativeType, C extends ComplexType & NativeType> extends AbstractFFTFilterF implements Ops.Deconvolve.RichardsonLucy @@ -131,7 +129,7 @@ else if (nonCirculant) { createFilterComputer(RandomAccessibleInterval raiExtendedInput, RandomAccessibleInterval raiExtendedKernel, RandomAccessibleInterval fftImg, RandomAccessibleInterval fftKernel, - RandomAccessibleInterval output, Interval imgConvolutionInterval) + RandomAccessibleInterval output) { UnaryInplaceOp, RandomAccessibleInterval> accelerator = null; @@ -148,7 +146,7 @@ else if (nonCirculant) { normalizer = (UnaryInplaceOp, RandomAccessibleInterval>) Inplaces .unary(ops(), NonCirculantNormalizationFactor.class, output, in(), - in2(), fftImg, fftKernel, imgConvolutionInterval); + in2(), fftImg, fftKernel); ArrayList, RandomAccessibleInterval>> list = new ArrayList<>(); @@ -159,19 +157,19 @@ else if (nonCirculant) { // normalized by image area) UnaryFunctionOp, RandomAccessibleInterval> fg = (UnaryFunctionOp) Functions.unary(ops(), NonCirculantFirstGuess.class, - RandomAccessibleInterval.class, RandomAccessibleInterval.class, - imgConvolutionInterval, Util.getTypeFromInterval(output), in()); + RandomAccessibleInterval.class, RandomAccessibleInterval.class, Util + .getTypeFromInterval(output), in()); return Computers.binary(ops(), RichardsonLucyC.class, output, raiExtendedInput, raiExtendedKernel, fftImg, fftKernel, true, true, - maxIterations, imgConvolutionInterval, accelerator, computeEstimateOp, - fg.calculate(raiExtendedInput), list); + maxIterations, accelerator, computeEstimateOp, fg.calculate( + raiExtendedInput), list); } // return a richardson lucy computer return Computers.binary(ops(), RichardsonLucyC.class, output, raiExtendedInput, raiExtendedKernel, fftImg, fftKernel, true, true, - maxIterations, imgConvolutionInterval, accelerator, computeEstimateOp); + maxIterations, accelerator, computeEstimateOp); } /** diff --git a/src/main/java/net/imagej/ops/filter/AbstractFFTFilterC.java b/src/main/java/net/imagej/ops/filter/AbstractFFTFilterC.java index e94482903c..e088b2b71a 100644 --- a/src/main/java/net/imagej/ops/filter/AbstractFFTFilterC.java +++ b/src/main/java/net/imagej/ops/filter/AbstractFFTFilterC.java @@ -29,7 +29,15 @@ package net.imagej.ops.filter; +import net.imagej.ops.filter.fft.CreateOutputFFTMethods; import net.imagej.ops.special.computer.AbstractBinaryComputerOp; +import net.imagej.ops.special.function.Functions; +import net.imagej.ops.special.function.UnaryFunctionOp; +import net.imglib2.Dimensions; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.type.numeric.ComplexType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.complex.ComplexFloatType; import org.scijava.plugin.Parameter; @@ -42,23 +50,24 @@ * @param * @param */ -public abstract class AbstractFFTFilterC extends - AbstractBinaryComputerOp +public abstract class AbstractFFTFilterC, O extends RealType, K extends RealType, C extends ComplexType> + extends + AbstractBinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> { /** * Buffer to be used to store FFTs for input. Size of fftInput must correspond * to the fft size of raiExtendedInput */ - @Parameter - private C fftInput; + @Parameter(required = false) + private RandomAccessibleInterval fftInput; /** * Buffer to be used to store FFTs for kernel. Size of fftKernel must * correspond to the fft size of raiExtendedKernel */ - @Parameter - private C fftKernel; + @Parameter(required = false) + private RandomAccessibleInterval fftKernel; /** * boolean indicating that the input FFT has already been calculated @@ -72,14 +81,50 @@ public abstract class AbstractFFTFilterC extends @Parameter(required = false) private boolean performKernelFFT = true; - protected C getFFTInput() { + /** + * FFT type + */ + private ComplexType fftType; + + /** + * Op used to create the complex FFTs + */ + private UnaryFunctionOp> createOp; + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void initialize() { + super.initialize(); + + if (fftType == null) { + fftType = (ComplexType) ops().create().nativeType( + ComplexFloatType.class); + } + + /** + * Op used to create the complex FFTs + */ + createOp = (UnaryFunctionOp) Functions.unary(ops(), + CreateOutputFFTMethods.class, RandomAccessibleInterval.class, + Dimensions.class, fftType, true); + } + + protected RandomAccessibleInterval getFFTInput() { return fftInput; } - protected C getFFTKernel() { + public void setFFTInput(RandomAccessibleInterval fftInput) { + this.fftInput = fftInput; + } + + protected RandomAccessibleInterval getFFTKernel() { return fftKernel; } + public void setFFTKernel(RandomAccessibleInterval fftKernel) { + this.fftKernel = fftKernel; + } + protected boolean getPerformInputFFT() { return performInputFFT; } @@ -88,4 +133,10 @@ protected boolean getPerformKernelFFT() { return performKernelFFT; } + public UnaryFunctionOp> + getCreateOp() + { + return createOp; + } + } diff --git a/src/main/java/net/imagej/ops/filter/AbstractFFTFilterF.java b/src/main/java/net/imagej/ops/filter/AbstractFFTFilterF.java index d0b2773204..a9d69bf8f0 100644 --- a/src/main/java/net/imagej/ops/filter/AbstractFFTFilterF.java +++ b/src/main/java/net/imagej/ops/filter/AbstractFFTFilterF.java @@ -38,7 +38,6 @@ import net.imagej.ops.special.function.UnaryFunctionOp; import net.imglib2.Dimensions; import net.imglib2.FinalDimensions; -import net.imglib2.Interval; import net.imglib2.RandomAccessibleInterval; import net.imglib2.type.NativeType; import net.imglib2.type.numeric.ComplexType; @@ -58,7 +57,8 @@ * @param */ public abstract class AbstractFFTFilterF, O extends RealType & NativeType, K extends RealType, C extends ComplexType & NativeType> - extends AbstractFilterF { + extends AbstractFilterF +{ /** * FFT type @@ -80,50 +80,57 @@ public abstract class AbstractFFTFilterF, O extends RealTy @SuppressWarnings({ "unchecked", "rawtypes" }) public void initialize() { super.initialize(); - + /** * Op used to pad the input */ - setPadOp( (BinaryFunctionOp) Functions.binary(ops(), PadInputFFTMethods.class, RandomAccessibleInterval.class, - RandomAccessibleInterval.class, Dimensions.class, true, getOBFInput())); + setPadOp((BinaryFunctionOp) Functions.binary(ops(), + PadInputFFTMethods.class, RandomAccessibleInterval.class, + RandomAccessibleInterval.class, Dimensions.class, true, getOBFInput())); /** * Op used to pad the kernel */ - setPadKernelOp ((BinaryFunctionOp) Functions.binary(ops(), PadShiftKernelFFTMethods.class, - RandomAccessibleInterval.class, RandomAccessibleInterval.class, Dimensions.class, true)); + setPadKernelOp((BinaryFunctionOp) Functions.binary(ops(), + PadShiftKernelFFTMethods.class, RandomAccessibleInterval.class, + RandomAccessibleInterval.class, Dimensions.class, true)); if (fftType == null) { - fftType = (ComplexType) ops().create().nativeType(ComplexFloatType.class); + fftType = (ComplexType) ops().create().nativeType( + ComplexFloatType.class); } /** * Op used to create the complex FFTs */ - createOp = (UnaryFunctionOp) Functions.unary(ops(), CreateOutputFFTMethods.class, - RandomAccessibleInterval.class, Dimensions.class, fftType, true); + createOp = (UnaryFunctionOp) Functions.unary(ops(), + CreateOutputFFTMethods.class, RandomAccessibleInterval.class, + Dimensions.class, fftType, true); } /** * create FFT memory, create FFT filter and run it */ @Override - public void computeFilter(final RandomAccessibleInterval input, final RandomAccessibleInterval kernel, - RandomAccessibleInterval output, long[] paddedSize) { + public void computeFilter(final RandomAccessibleInterval input, + final RandomAccessibleInterval kernel, + RandomAccessibleInterval output, long[] paddedSize) + { - RandomAccessibleInterval fftInput = createOp.calculate(new FinalDimensions(paddedSize)); + RandomAccessibleInterval fftInput = createOp.calculate( + new FinalDimensions(paddedSize)); - RandomAccessibleInterval fftKernel = createOp.calculate(new FinalDimensions(paddedSize)); + RandomAccessibleInterval fftKernel = createOp.calculate( + new FinalDimensions(paddedSize)); // TODO: in this case it is difficult to match the filter op in the // 'initialize' as we don't know the size yet, thus we can't create // memory // for the FFTs - filter = createFilterComputer(input, kernel, fftInput, fftKernel, output, input); + filter = createFilterComputer(input, kernel, fftInput, fftKernel, output); filter.compute(input, kernel, output); } - /** * This function is called after the RAIs and FFTs are set up and create the @@ -134,11 +141,12 @@ public void computeFilter(final RandomAccessibleInterval input, final RandomA * @param fftImg * @param fftKernel * @param output - * @param imgConvolutionInterval */ - abstract public BinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> createFilterComputer( - RandomAccessibleInterval raiExtendedInput, RandomAccessibleInterval raiExtendedKernel, + abstract public + BinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> + createFilterComputer(RandomAccessibleInterval raiExtendedInput, + RandomAccessibleInterval raiExtendedKernel, RandomAccessibleInterval fftImg, RandomAccessibleInterval fftKernel, - RandomAccessibleInterval output, Interval imgConvolutionInterval); + RandomAccessibleInterval output); } diff --git a/src/main/java/net/imagej/ops/filter/AbstractIterativeFFTFilterC.java b/src/main/java/net/imagej/ops/filter/AbstractIterativeFFTFilterC.java index c678288be0..9ea5dc8510 100644 --- a/src/main/java/net/imagej/ops/filter/AbstractIterativeFFTFilterC.java +++ b/src/main/java/net/imagej/ops/filter/AbstractIterativeFFTFilterC.java @@ -30,7 +30,6 @@ package net.imagej.ops.filter; import net.imagej.ops.special.inplace.UnaryInplaceOp; -import net.imglib2.Interval; import net.imglib2.RandomAccessibleInterval; import net.imglib2.type.numeric.ComplexType; import net.imglib2.type.numeric.RealType; @@ -48,8 +47,7 @@ * @param */ public abstract class AbstractIterativeFFTFilterC, O extends RealType, K extends RealType, C extends ComplexType> - extends - AbstractFFTFilterC, RandomAccessibleInterval, RandomAccessibleInterval, RandomAccessibleInterval> + extends AbstractFFTFilterC { @Parameter(required = false) @@ -61,12 +59,6 @@ public abstract class AbstractIterativeFFTFilterC, O exten @Parameter private int maxIterations; - /** - * The interval to process TODO: this is probably redundant - remove - */ - @Parameter - private Interval imgConvolutionInterval; - /** * An op which implements an acceleration strategy (takes a larger step at * each iteration). @@ -74,10 +66,6 @@ public abstract class AbstractIterativeFFTFilterC, O exten @Parameter(required = false) private UnaryInplaceOp, RandomAccessibleInterval> accelerator; - public Interval getImgConvolutionInterval() { - return imgConvolutionInterval; - } - public UnaryInplaceOp, RandomAccessibleInterval> getAccelerator() diff --git a/src/main/java/net/imagej/ops/filter/FFTMethodsLinearFFTFilterC.java b/src/main/java/net/imagej/ops/filter/FFTMethodsLinearFFTFilterC.java index 1b2dc17e25..2174e3fd50 100644 --- a/src/main/java/net/imagej/ops/filter/FFTMethodsLinearFFTFilterC.java +++ b/src/main/java/net/imagej/ops/filter/FFTMethodsLinearFFTFilterC.java @@ -35,6 +35,7 @@ import net.imagej.ops.special.computer.BinaryComputerOp; import net.imagej.ops.special.computer.Computers; import net.imagej.ops.special.computer.UnaryComputerOp; +import net.imglib2.FinalDimensions; import net.imglib2.RandomAccessibleInterval; import net.imglib2.type.numeric.ComplexType; import net.imglib2.type.numeric.RealType; @@ -54,9 +55,7 @@ */ @Plugin(type = Ops.Filter.LinearFilter.class, priority = Priority.LOW) public class FFTMethodsLinearFFTFilterC, O extends RealType, K extends RealType, C extends ComplexType> - extends - AbstractFFTFilterC, RandomAccessibleInterval, RandomAccessibleInterval, RandomAccessibleInterval> - implements Ops.Filter.LinearFilter + extends AbstractFFTFilterC implements Ops.Filter.LinearFilter { // TODO: should this be a parameter? figure out best way to override @@ -93,6 +92,16 @@ public void initialize() { public void compute(RandomAccessibleInterval in, RandomAccessibleInterval kernel, RandomAccessibleInterval out) { + // create FFT input memory if needed + if (getFFTInput() == null) { + setFFTInput(getCreateOp().calculate(in)); + } + + // create FFT kernel memory if needed + if (getFFTKernel() == null) { + setFFTKernel(getCreateOp().calculate(in)); + } + // perform input FFT if needed if (getPerformInputFFT()) { fftIn.compute(in, getFFTInput()); diff --git a/src/main/java/net/imagej/ops/filter/FilterNamespace.java b/src/main/java/net/imagej/ops/filter/FilterNamespace.java index 136eb763a1..f49b71fe62 100644 --- a/src/main/java/net/imagej/ops/filter/FilterNamespace.java +++ b/src/main/java/net/imagej/ops/filter/FilterNamespace.java @@ -287,9 +287,39 @@ RandomAccessibleInterval convolve(final RandomAccessibleInterval out, in, kernel); return result; } + + /** Executes the "convolve" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.convolve.ConvolveFFTC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval convolve( + final RandomAccessibleInterval output, + final RandomAccessibleInterval raiExtendedInput, + final RandomAccessibleInterval raiExtendedKernel) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.Convolve.class, output, + raiExtendedInput, raiExtendedKernel); + return result; + } /** Executes the "convolve" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.convolve.ConvolveFFTC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval convolve( + final RandomAccessibleInterval output, + final RandomAccessibleInterval raiExtendedInput, + final RandomAccessibleInterval raiExtendedKernel, + final RandomAccessibleInterval fftInput) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.Convolve.class, output, + raiExtendedInput, raiExtendedKernel, fftInput); + return result; + } + /** Executes the "convolve" operation on the given arguments. */ @OpMethod(op = net.imagej.ops.filter.convolve.ConvolveFFTC.class) public , O extends RealType, K extends RealType, C extends ComplexType> RandomAccessibleInterval convolve( @@ -440,6 +470,37 @@ RandomAccessibleInterval correlate( kernel, borderSize, obfInput, obfKernel, outType, fftType); return result; } + + /** Executes the "correlate" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.correlate.CorrelateFFTC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval correlate( + final RandomAccessibleInterval output, + final RandomAccessibleInterval raiExtendedInput, + final RandomAccessibleInterval raiExtendedKernel) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.Correlate.class, + output, raiExtendedInput, raiExtendedKernel); + return result; + } + + /** Executes the "correlate" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.correlate.CorrelateFFTC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval correlate( + final RandomAccessibleInterval output, + final RandomAccessibleInterval raiExtendedInput, + final RandomAccessibleInterval raiExtendedKernel, + final RandomAccessibleInterval fftInput) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.Correlate.class, + output, raiExtendedInput, raiExtendedKernel, fftInput); + return result; + } /** Executes the "correlate" operation on the given arguments. */ @OpMethod(op = net.imagej.ops.filter.correlate.CorrelateFFTC.class) @@ -911,6 +972,39 @@ public > RandomAccessibleInterval ifft( } // -- linear filter -- + + /** Executes the "linearFilter" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.FFTMethodsLinearFFTFilterC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval linearFilter( + final RandomAccessibleInterval out, + final RandomAccessibleInterval in1, + final RandomAccessibleInterval in2, + final BinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> frequencyOp) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.LinearFilter.class, + out, in1, in2, frequencyOp); + return result; + } + + /** Executes the "linearFilter" operation on the given arguments. */ + @OpMethod(op = net.imagej.ops.filter.FFTMethodsLinearFFTFilterC.class) + public , O extends RealType, K extends RealType, C extends ComplexType> + RandomAccessibleInterval linearFilter( + final RandomAccessibleInterval out, + final RandomAccessibleInterval in1, + final RandomAccessibleInterval in2, + final RandomAccessibleInterval fftInput, + final BinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> frequencyOp) + { + @SuppressWarnings("unchecked") + final RandomAccessibleInterval result = + (RandomAccessibleInterval) ops().run(Ops.Filter.LinearFilter.class, + out, in1, in2, fftInput, frequencyOp); + return result; + } /** Executes the "linearFilter" operation on the given arguments. */ @OpMethod(op = net.imagej.ops.filter.FFTMethodsLinearFFTFilterC.class) diff --git a/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTC.java b/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTC.java index 95292aaf3e..26de9360c9 100644 --- a/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTC.java +++ b/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTC.java @@ -56,7 +56,7 @@ @Plugin(type = Ops.Filter.Convolve.class, priority = Priority.LOW) public class ConvolveFFTC, O extends RealType, K extends RealType, C extends ComplexType> extends - AbstractFFTFilterC, RandomAccessibleInterval, RandomAccessibleInterval, RandomAccessibleInterval> + AbstractFFTFilterC implements Ops.Filter.Convolve { diff --git a/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTF.java b/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTF.java index 99c20e685d..dd935fec0d 100644 --- a/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTF.java +++ b/src/main/java/net/imagej/ops/filter/convolve/ConvolveFFTF.java @@ -33,7 +33,6 @@ import net.imagej.ops.filter.AbstractFFTFilterF; import net.imagej.ops.special.computer.BinaryComputerOp; import net.imagej.ops.special.computer.Computers; -import net.imglib2.Interval; import net.imglib2.RandomAccessibleInterval; import net.imglib2.outofbounds.OutOfBoundsConstantValueFactory; import net.imglib2.type.NativeType; @@ -81,7 +80,7 @@ public void initialize() { createFilterComputer(RandomAccessibleInterval raiExtendedInput, RandomAccessibleInterval raiExtendedKernel, RandomAccessibleInterval fftImg, RandomAccessibleInterval fftKernel, - RandomAccessibleInterval output, Interval imgConvolutionInterval) + RandomAccessibleInterval output) { return Computers.binary(ops(), ConvolveFFTC.class, output, raiExtendedInput, raiExtendedKernel, fftImg, fftKernel); diff --git a/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTC.java b/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTC.java index ea84c5d1ac..7b28d22af6 100644 --- a/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTC.java +++ b/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTC.java @@ -52,9 +52,7 @@ */ @Plugin(type = Ops.Filter.Correlate.class) public class CorrelateFFTC, O extends RealType, K extends RealType, C extends ComplexType> - extends - AbstractFFTFilterC, RandomAccessibleInterval, RandomAccessibleInterval, RandomAccessibleInterval> - implements Ops.Filter.Correlate + extends AbstractFFTFilterC implements Ops.Filter.Correlate { private BinaryComputerOp, RandomAccessibleInterval, RandomAccessibleInterval> complexConjugateMul; @@ -70,7 +68,8 @@ public void initialize() { ComplexConjugateMultiplyMap.class, getFFTInput(), getFFTKernel(), getFFTInput()); - // create a correlater by creating a linear filter and passing the complex conjugate multiplier + // create a correlater by creating a linear filter and passing the complex + // conjugate multiplier // as the frequency operation linearFilter = (BinaryComputerOp) Computers.binary(ops(), FFTMethodsLinearFFTFilterC.class, RandomAccessibleInterval.class, diff --git a/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTF.java b/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTF.java index 2f7e0514ee..fa933ade51 100644 --- a/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTF.java +++ b/src/main/java/net/imagej/ops/filter/correlate/CorrelateFFTF.java @@ -34,7 +34,6 @@ import net.imagej.ops.filter.AbstractFFTFilterF; import net.imagej.ops.special.computer.BinaryComputerOp; import net.imagej.ops.special.computer.Computers; -import net.imglib2.Interval; import net.imglib2.RandomAccessibleInterval; import net.imglib2.outofbounds.OutOfBoundsMirrorFactory; import net.imglib2.outofbounds.OutOfBoundsMirrorFactory.Boundary; @@ -55,8 +54,7 @@ * @param * @param */ -@Plugin(type = Ops.Filter.Correlate.class, - priority = Priority.VERY_HIGH) +@Plugin(type = Ops.Filter.Correlate.class, priority = Priority.VERY_HIGH) public class CorrelateFFTF & NativeType, O extends RealType & NativeType, K extends RealType & NativeType, C extends ComplexType & NativeType> extends AbstractFFTFilterF implements Contingent, Ops.Filter.Correlate @@ -84,7 +82,7 @@ public void initialize() { createFilterComputer(RandomAccessibleInterval raiExtendedInput, RandomAccessibleInterval raiExtendedKernel, RandomAccessibleInterval fftImg, RandomAccessibleInterval fftKernel, - RandomAccessibleInterval output, Interval imgConvolutionInterval) + RandomAccessibleInterval output) { return Computers.binary(ops(), CorrelateFFTC.class, output, raiExtendedInput, raiExtendedKernel, fftImg, fftKernel);