Skip to content

Commit 54e67f6

Browse files
gselzerctrueden
authored andcommitted
WIP: filter.convolve work
TODO: squash into another commit later
1 parent fd0c44a commit 54e67f6

15 files changed

Lines changed: 1773 additions & 0 deletions
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2018 ImageJ developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package net.imagej.ops.filter;
31+
32+
import net.imagej.ops.filter.fft.CreateOutputFFTMethods;
33+
import net.imagej.ops.special.function.Functions;
34+
import net.imagej.ops.special.function.UnaryFunctionOp;
35+
import net.imglib2.Dimensions;
36+
import net.imglib2.RandomAccessibleInterval;
37+
import net.imglib2.type.numeric.ComplexType;
38+
import net.imglib2.type.numeric.RealType;
39+
import net.imglib2.type.numeric.complex.ComplexFloatType;
40+
41+
import org.scijava.ops.core.computer.Computer6;
42+
43+
/**
44+
* Abstract class for FFT based filter computers
45+
*
46+
* @author Brian Northan
47+
* @param <I>
48+
* @param <O>
49+
* gene
50+
* @param <K>
51+
* @param <C>
52+
*/
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;
82+
83+
/**
84+
* FFT type
85+
*/
86+
private ComplexType<C> fftType;
87+
88+
/**
89+
* Op used to create the complex FFTs
90+
*/
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+
}
108+
109+
protected RandomAccessibleInterval<C> getFFTInput() {
110+
return fftInput;
111+
}
112+
113+
public void setFFTInput(RandomAccessibleInterval<C> fftInput) {
114+
this.fftInput = fftInput;
115+
}
116+
117+
protected RandomAccessibleInterval<C> getFFTKernel() {
118+
return fftKernel;
119+
}
120+
121+
public void setFFTKernel(RandomAccessibleInterval<C> fftKernel) {
122+
this.fftKernel = fftKernel;
123+
}
124+
125+
protected boolean getPerformInputFFT() {
126+
return performInputFFT;
127+
}
128+
129+
protected boolean getPerformKernelFFT() {
130+
return performKernelFFT;
131+
}
132+
133+
public UnaryFunctionOp<Dimensions, RandomAccessibleInterval<C>> getCreateOp() {
134+
return createOp;
135+
}
136+
137+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2018 ImageJ developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package net.imagej.ops.filter;
31+
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;
39+
import net.imglib2.Dimensions;
40+
import net.imglib2.FinalDimensions;
41+
import net.imglib2.RandomAccessibleInterval;
42+
import net.imglib2.type.NativeType;
43+
import net.imglib2.type.numeric.ComplexType;
44+
import net.imglib2.type.numeric.RealType;
45+
import net.imglib2.type.numeric.complex.ComplexFloatType;
46+
47+
import org.scijava.plugin.Parameter;
48+
49+
/**
50+
* Abstract class for binary filter that performs operations using an image and
51+
* kernel in the frequency domain using the imglib2 FFTMethods library.
52+
*
53+
* @author Brian Northan
54+
* @param <I>
55+
* @param <O>
56+
* @param <K>
57+
* @param <C>
58+
*/
59+
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+
{
62+
63+
/**
64+
* FFT type
65+
*/
66+
@Parameter(required = false)
67+
private ComplexType<C> fftType;
68+
69+
/**
70+
* Op used to create the complex FFTs
71+
*/
72+
private UnaryFunctionOp<Dimensions, RandomAccessibleInterval<C>> createOp;
73+
74+
/**
75+
* Filter Op
76+
*/
77+
private BinaryComputerOp<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>> filter;
78+
79+
@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);
109+
}
110+
111+
/**
112+
* create FFT memory, create FFT filter and run it
113+
*/
114+
@Override
115+
public void computeFilter(final RandomAccessibleInterval<I> input,
116+
final RandomAccessibleInterval<K> kernel,
117+
RandomAccessibleInterval<O> output, long[] paddedSize)
118+
{
119+
120+
RandomAccessibleInterval<C> fftInput = createOp.calculate(
121+
new FinalDimensions(paddedSize));
122+
123+
RandomAccessibleInterval<C> fftKernel = createOp.calculate(
124+
new FinalDimensions(paddedSize));
125+
126+
// TODO: in this case it is difficult to match the filter op in the
127+
// 'initialize' as we don't know the size yet, thus we can't create
128+
// memory
129+
// for the FFTs
130+
filter = createFilterComputer(input, kernel, fftInput, fftKernel, output);
131+
132+
filter.compute(input, kernel, output);
133+
}
134+
135+
/**
136+
* This function is called after the RAIs and FFTs are set up and create the
137+
* frequency filter computer.
138+
*
139+
* @param raiExtendedInput
140+
* @param raiExtendedKernel
141+
* @param fftImg
142+
* @param fftKernel
143+
* @param output
144+
*/
145+
abstract public
146+
BinaryComputerOp<RandomAccessibleInterval<I>, RandomAccessibleInterval<K>, RandomAccessibleInterval<O>>
147+
createFilterComputer(RandomAccessibleInterval<I> raiExtendedInput,
148+
RandomAccessibleInterval<K> raiExtendedKernel,
149+
RandomAccessibleInterval<C> fftImg, RandomAccessibleInterval<C> fftKernel,
150+
RandomAccessibleInterval<O> output);
151+
152+
}

0 commit comments

Comments
 (0)