Skip to content

Commit a0dd279

Browse files
gselzerctrueden
authored andcommitted
WIP: filter.convolve/pad/fft/ifft
1 parent 4620d66 commit a0dd279

23 files changed

Lines changed: 1653 additions & 354 deletions

src/main/java/net/imagej/ops/filter/AbstractFFTFilterC.java

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@
2929

3030
package net.imagej.ops.filter;
3131

32-
import net.imagej.ops.filter.fft.CreateOutputFFTMethods;
33-
import net.imagej.ops.special.function.Functions;
34-
import net.imagej.ops.special.function.UnaryFunctionOp;
32+
import java.util.function.Function;
33+
3534
import net.imglib2.Dimensions;
3635
import net.imglib2.RandomAccessibleInterval;
3736
import net.imglib2.type.numeric.ComplexType;
3837
import net.imglib2.type.numeric.RealType;
39-
import net.imglib2.type.numeric.complex.ComplexFloatType;
4038

41-
import org.scijava.ops.core.computer.Computer6;
39+
import org.scijava.ops.OpDependency;
40+
import org.scijava.ops.core.function.Function3;
41+
import org.scijava.ops.util.Adapt;
4242

4343
/**
4444
* Abstract class for FFT based filter computers
@@ -50,61 +50,41 @@
5050
* @param <K>
5151
* @param <C>
5252
*/
53-
public abstract class AbstractFFTFilterC<I extends RealType<I>, O extends RealType<O>, K extends RealType<K>, C extends ComplexType<C>>
54-
implements
55-
Computer6<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<C>, RandomAccessibleInterval<C>, Boolean, Boolean, RandomAccessibleInterval<O>> {
56-
57-
// /**
58-
// * Buffer to be used to store FFTs for input. Size of fftInput must correspond
59-
// * to the fft size of raiExtendedInput
60-
// */
61-
// @Parameter(required = false)
62-
// private RandomAccessibleInterval<C> fftInput;
63-
//
64-
// /**
65-
// * Buffer to be used to store FFTs for kernel. Size of fftKernel must correspond
66-
// * to the fft size of raiExtendedKernel
67-
// */
68-
// @Parameter(required = false)
69-
// private RandomAccessibleInterval<C> fftKernel;
70-
//
71-
// /**
72-
// * boolean indicating that the input FFT has already been calculated
73-
// */
74-
// @Parameter(required = false)
75-
// private boolean performInputFFT = true;
76-
//
77-
// /**
78-
// * boolean indicating that the kernel FFT has already been calculated
79-
// */
80-
// @Parameter(required = false)
81-
// private boolean performKernelFFT = true;
53+
public abstract class AbstractFFTFilterC<I extends RealType<I>, O extends RealType<O>, K extends RealType<K>, C extends ComplexType<C>>{
54+
55+
/**
56+
* Buffer to be used to store FFTs for input. Size of fftInput must correspond
57+
* to the fft size of raiExtendedInput
58+
*/
59+
private RandomAccessibleInterval<C> fftInput;
60+
61+
/**
62+
* Buffer to be used to store FFTs for kernel. Size of fftKernel must correspond
63+
* to the fft size of raiExtendedKernel
64+
*/
65+
private RandomAccessibleInterval<C> fftKernel;
66+
67+
/**
68+
* boolean indicating that the input FFT has already been calculated
69+
*/
70+
private boolean performInputFFT = true;
71+
72+
/**
73+
* boolean indicating that the kernel FFT has already been calculated
74+
*/
75+
private boolean performKernelFFT = true;
8276

8377
/**
8478
* FFT type
8579
*/
86-
private ComplexType<C> fftType;
80+
private C fftType;
8781

8882
/**
8983
* Op used to create the complex FFTs
84+
* NOTE: Boolean is always true.
9085
*/
91-
private UnaryFunctionOp<Dimensions, RandomAccessibleInterval<C>> createOp;
92-
93-
@Override
94-
@SuppressWarnings({ "unchecked", "rawtypes" })
95-
public void initialize() {
96-
super.initialize();
97-
98-
if (fftType == null) {
99-
fftType = (ComplexType<C>) ops().create().nativeType(ComplexFloatType.class);
100-
}
101-
102-
/**
103-
* Op used to create the complex FFTs
104-
*/
105-
createOp = (UnaryFunctionOp) Functions.unary(ops(), CreateOutputFFTMethods.class,
106-
RandomAccessibleInterval.class, Dimensions.class, fftType, true);
107-
}
86+
@OpDependency(name = "filter.createFFTOutput")
87+
private Function3<Dimensions, C, Boolean, RandomAccessibleInterval<C>> createOp;
10888

10989
protected RandomAccessibleInterval<C> getFFTInput() {
11090
return fftInput;
@@ -130,8 +110,8 @@ protected boolean getPerformKernelFFT() {
130110
return performKernelFFT;
131111
}
132112

133-
public UnaryFunctionOp<Dimensions, RandomAccessibleInterval<C>> getCreateOp() {
134-
return createOp;
113+
public Function<Dimensions, RandomAccessibleInterval<C>> getCreateOp() {
114+
return Adapt.Functions.asFunction(createOp, fftType, true);
135115
}
136116

137117
}

src/main/java/net/imagej/ops/filter/AbstractFFTFilterF.java

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,22 @@
2929

3030
package net.imagej.ops.filter;
3131

32-
import net.imagej.ops.filter.fft.CreateOutputFFTMethods;
33-
import net.imagej.ops.filter.pad.PadInputFFTMethods;
34-
import net.imagej.ops.filter.pad.PadShiftKernelFFTMethods;
35-
import net.imagej.ops.special.computer.BinaryComputerOp;
36-
import net.imagej.ops.special.function.BinaryFunctionOp;
37-
import net.imagej.ops.special.function.Functions;
38-
import net.imagej.ops.special.function.UnaryFunctionOp;
32+
import java.util.function.BiFunction;
33+
3934
import net.imglib2.Dimensions;
4035
import net.imglib2.FinalDimensions;
4136
import net.imglib2.RandomAccessibleInterval;
37+
import net.imglib2.outofbounds.OutOfBoundsFactory;
4238
import net.imglib2.type.NativeType;
4339
import net.imglib2.type.numeric.ComplexType;
4440
import net.imglib2.type.numeric.RealType;
45-
import net.imglib2.type.numeric.complex.ComplexFloatType;
4641

47-
import org.scijava.plugin.Parameter;
42+
import org.scijava.ops.OpDependency;
43+
import org.scijava.ops.core.computer.BiComputer;
44+
import org.scijava.ops.core.function.Function3;
45+
import org.scijava.ops.core.function.Function4;
46+
import org.scijava.ops.core.function.Function7;
47+
import org.scijava.ops.util.Adapt;
4848

4949
/**
5050
* Abstract class for binary filter that performs operations using an image and
@@ -57,71 +57,57 @@
5757
* @param <C>
5858
*/
5959
public abstract class AbstractFFTFilterF<I extends RealType<I>, O extends RealType<O> & NativeType<O>, K extends RealType<K>, C extends ComplexType<C> & NativeType<C>>
60-
extends AbstractFilterF<I, O, K, C>
61-
{
60+
extends AbstractFilterF<I, O, K, C> implements
61+
Function7<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, long[], OutOfBoundsFactory<I, RandomAccessibleInterval<I>>, OutOfBoundsFactory<K, RandomAccessibleInterval<K>>, C, O, RandomAccessibleInterval<O>> {
6262

63-
/**
64-
* FFT type
65-
*/
66-
@Parameter(required = false)
67-
private ComplexType<C> fftType;
63+
// /**
64+
// * FFT type
65+
// */
66+
// @Parameter(required = false)
67+
// private ComplexType<C> fftType;
6868

69-
/**
70-
* Op used to create the complex FFTs
71-
*/
72-
private UnaryFunctionOp<Dimensions, RandomAccessibleInterval<C>> createOp;
69+
@OpDependency(name = "filter.pad")
70+
private Function4<RandomAccessibleInterval<I>, Dimensions, Boolean, OutOfBoundsFactory<I, RandomAccessibleInterval<I>>, RandomAccessibleInterval<I>> padOp;
71+
72+
@OpDependency(name = "filter.padShiftFFTKernel")
73+
private BiFunction<RandomAccessibleInterval<K>, Dimensions, RandomAccessibleInterval<K>> padKernelOp;
74+
75+
@OpDependency(name = "filter.createFFTOutput")
76+
private Function3<Dimensions, C, Boolean, RandomAccessibleInterval<C>> createOp;
77+
78+
@OpDependency(name = "create.img")
79+
private BiFunction<Dimensions, O, RandomAccessibleInterval<O>> outputCreator;
80+
81+
private C complexType;
7382

7483
/**
7584
* Filter Op
7685
*/
77-
private BinaryComputerOp<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>> filter;
86+
private BiComputer<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>> filter;
7887

7988
@Override
80-
@SuppressWarnings({ "unchecked", "rawtypes" })
81-
public void initialize() {
82-
super.initialize();
83-
84-
/**
85-
* Op used to pad the input
86-
*/
87-
setPadOp((BinaryFunctionOp) Functions.binary(ops(),
88-
PadInputFFTMethods.class, RandomAccessibleInterval.class,
89-
RandomAccessibleInterval.class, Dimensions.class, true, getOBFInput()));
90-
91-
/**
92-
* Op used to pad the kernel
93-
*/
94-
setPadKernelOp((BinaryFunctionOp) Functions.binary(ops(),
95-
PadShiftKernelFFTMethods.class, RandomAccessibleInterval.class,
96-
RandomAccessibleInterval.class, Dimensions.class, true));
97-
98-
if (fftType == null) {
99-
fftType = (ComplexType<C>) ops().create().nativeType(
100-
ComplexFloatType.class);
101-
}
102-
103-
/**
104-
* Op used to create the complex FFTs
105-
*/
106-
createOp = (UnaryFunctionOp) Functions.unary(ops(),
107-
CreateOutputFFTMethods.class, RandomAccessibleInterval.class,
108-
Dimensions.class, fftType, true);
89+
public RandomAccessibleInterval<O> apply(final RandomAccessibleInterval<I> input,
90+
final RandomAccessibleInterval<K> kernel, final long[] borderSize,
91+
final OutOfBoundsFactory<I, RandomAccessibleInterval<I>> obfInput,
92+
final OutOfBoundsFactory<K, RandomAccessibleInterval<K>> obfKernel, C fftType, final O outType) {
93+
final RandomAccessibleInterval<O> output = outputCreator.apply(input, outType);
94+
BiFunction<RandomAccessibleInterval<I>, Dimensions, RandomAccessibleInterval<I>> adaptedPadInput = Adapt.Functions
95+
.asBiFunction(padOp, true, obfInput);
96+
complexType = fftType;
97+
computeOutput(input, kernel, borderSize, obfInput, obfKernel, adaptedPadInput, padKernelOp, output);
98+
return output;
10999
}
110100

111101
/**
112102
* create FFT memory, create FFT filter and run it
113103
*/
114104
@Override
115-
public void computeFilter(final RandomAccessibleInterval<I> input,
116-
final RandomAccessibleInterval<K> kernel,
117-
RandomAccessibleInterval<O> output, long[] paddedSize)
118-
{
105+
public void computeFilter(final RandomAccessibleInterval<I> input, final RandomAccessibleInterval<K> kernel,
106+
RandomAccessibleInterval<O> output, long[] paddedSize) {
119107

120-
RandomAccessibleInterval<C> fftInput = createOp.calculate(
121-
new FinalDimensions(paddedSize));
108+
RandomAccessibleInterval<C> fftInput = createOp.apply(new FinalDimensions(paddedSize), complexType, true);
122109

123-
RandomAccessibleInterval<C> fftKernel = createOp.calculate(
124-
new FinalDimensions(paddedSize));
110+
RandomAccessibleInterval<C> fftKernel = createOp.apply(new FinalDimensions(paddedSize), complexType, true);
125111

126112
// TODO: in this case it is difficult to match the filter op in the
127113
// 'initialize' as we don't know the size yet, thus we can't create
@@ -142,10 +128,8 @@ public void computeFilter(final RandomAccessibleInterval<I> input,
142128
* @param fftKernel
143129
* @param output
144130
*/
145-
abstract public
146-
BinaryComputerOp<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>>
147-
createFilterComputer(RandomAccessibleInterval<I> raiExtendedInput,
148-
RandomAccessibleInterval<K> raiExtendedKernel,
131+
abstract public BiComputer<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>> createFilterComputer(
132+
RandomAccessibleInterval<I> raiExtendedInput, RandomAccessibleInterval<K> raiExtendedKernel,
149133
RandomAccessibleInterval<C> fftImg, RandomAccessibleInterval<C> fftKernel,
150134
RandomAccessibleInterval<O> output);
151135

0 commit comments

Comments
 (0)