Skip to content

Commit f9b9333

Browse files
gselzerhinerm
authored andcommitted
Create Neighborhood parallel Ops
1 parent bd7bc89 commit f9b9333

14 files changed

Lines changed: 484 additions & 433 deletions

File tree

imagej/imagej-ops2/src/main/java/module-info.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,10 @@
6565
opens net.imagej.ops2.filter.gauss to therapi.runtime.javadoc, org.scijava.ops.engine;
6666
opens net.imagej.ops2.filter.hessian to therapi.runtime.javadoc, org.scijava.ops.engine;
6767
opens net.imagej.ops2.filter.ifft to therapi.runtime.javadoc, org.scijava.ops.engine;
68-
opens net.imagej.ops2.filter.max to therapi.runtime.javadoc, org.scijava.ops.engine;
69-
opens net.imagej.ops2.filter.mean to therapi.runtime.javadoc, org.scijava.ops.engine;
70-
opens net.imagej.ops2.filter.median to therapi.runtime.javadoc, org.scijava.ops.engine;
71-
opens net.imagej.ops2.filter.min to therapi.runtime.javadoc, org.scijava.ops.engine;
7268
opens net.imagej.ops2.filter.pad to therapi.runtime.javadoc, org.scijava.ops.engine;
7369
opens net.imagej.ops2.filter.sigma to therapi.runtime.javadoc, org.scijava.ops.engine;
7470
opens net.imagej.ops2.filter.sobel to therapi.runtime.javadoc, org.scijava.ops.engine;
7571
opens net.imagej.ops2.filter.tubeness to therapi.runtime.javadoc, org.scijava.ops.engine;
76-
opens net.imagej.ops2.filter.variance to therapi.runtime.javadoc, org.scijava.ops.engine;
7772
opens net.imagej.ops2.filter.vesselness to therapi.runtime.javadoc, org.scijava.ops.engine;
7873
opens net.imagej.ops2.geom to therapi.runtime.javadoc, org.scijava.ops.engine;
7974
opens net.imagej.ops2.geom.geom2d to org.scijava, therapi.runtime.javadoc, org.scijava.ops.engine;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
2+
package net.imagej.ops2.adapt;
3+
4+
import java.util.function.Function;
5+
6+
import org.scijava.function.Computers;
7+
import org.scijava.ops.spi.OpMethod;
8+
9+
import net.imglib2.RandomAccessibleInterval;
10+
import net.imglib2.algorithm.neighborhood.Neighborhood;
11+
import net.imglib2.algorithm.neighborhood.Shape;
12+
import net.imglib2.loops.LoopBuilder;
13+
import net.imglib2.outofbounds.OutOfBoundsFactory;
14+
import net.imglib2.outofbounds.OutOfBoundsMirrorFactory;
15+
import net.imglib2.view.Views;
16+
17+
public class LiftNeighborhoodComputersToImg {
18+
19+
/**
20+
* @implNote op names='adapt', priority='100.',
21+
* type='java.util.function.Function'
22+
*/
23+
public static <T, U>
24+
Computers.Arity2<RandomAccessibleInterval<T>, Shape, RandomAccessibleInterval<U>>
25+
adapt1UsingShape(Computers.Arity1<Neighborhood<T>, U> op)
26+
{
27+
OutOfBoundsMirrorFactory<T, RandomAccessibleInterval<T>> oobf //
28+
= new OutOfBoundsMirrorFactory<>(
29+
OutOfBoundsMirrorFactory.Boundary.SINGLE);
30+
return (in, shape, out) -> {
31+
var extended = Views.extend(in, oobf);
32+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
33+
var intervaled = Views.interval(neighborhoods, in);
34+
LoopBuilder.setImages(intervaled, out).forEachPixel(op);
35+
};
36+
}
37+
38+
/**
39+
* @implNote op names='adapt', priority='100.',
40+
* type='java.util.function.Function'
41+
*/
42+
@OpMethod(names = "adapt", type = Function.class)
43+
public static <T, U, F extends RandomAccessibleInterval<T>>
44+
Computers.Arity3<F, Shape, OutOfBoundsFactory<T, F>, RandomAccessibleInterval<U>>
45+
adapt1UsingShapeAndOOBF(Computers.Arity1<Neighborhood<T>, U> op)
46+
{
47+
return (in, shape, oobf, out) -> {
48+
var extended = Views.extend(in, oobf);
49+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
50+
var intervaled = Views.interval(neighborhoods, in);
51+
LoopBuilder.setImages(intervaled, out).forEachPixel(op);
52+
};
53+
}
54+
55+
/**
56+
* @implNote op names='adapt', priority='100.',
57+
* type='java.util.function.Function'
58+
*/
59+
public static <T, U, V>
60+
Computers.Arity3<RandomAccessibleInterval<T>, V, Shape, RandomAccessibleInterval<U>>
61+
adapt2UsingShape(Computers.Arity2<Neighborhood<T>, V, U> op)
62+
{
63+
OutOfBoundsMirrorFactory<T, RandomAccessibleInterval<T>> oobf //
64+
= new OutOfBoundsMirrorFactory<>(
65+
OutOfBoundsMirrorFactory.Boundary.SINGLE);
66+
return (in1, in2, shape, out) -> {
67+
var extended = Views.extend(in1, oobf);
68+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
69+
var intervaled = Views.interval(neighborhoods, in1);
70+
LoopBuilder.setImages(intervaled, out).forEachPixel((in, container) -> op
71+
.compute(in, in2, container));
72+
};
73+
}
74+
75+
/**
76+
* @implNote op names='adapt', priority='100.',
77+
* type='java.util.function.Function'
78+
*/
79+
@OpMethod(names = "adapt", type = Function.class)
80+
public static <T, U, V, F extends RandomAccessibleInterval<T>>
81+
Computers.Arity4<F, V, Shape, OutOfBoundsFactory<T, F>, RandomAccessibleInterval<U>>
82+
adapt2UsingShapeAndOOBF(Computers.Arity2<Neighborhood<T>, V, U> op)
83+
{
84+
return (in1, in2, shape, oobf, out) -> {
85+
var extended = Views.extend(in1, oobf);
86+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
87+
var intervaled = Views.interval(neighborhoods, in1);
88+
LoopBuilder.setImages(intervaled, out).forEachPixel((in, container) -> op
89+
.compute(in, in2, container));
90+
};
91+
}
92+
93+
/**
94+
* @implNote op names='adapt', priority='100.',
95+
* type='java.util.function.Function'
96+
*/
97+
public static <T, U, V, W>
98+
Computers.Arity4<RandomAccessibleInterval<T>, V, W, Shape, RandomAccessibleInterval<U>>
99+
adapt3UsingShape(Computers.Arity3<Neighborhood<T>, V, W, U> op)
100+
{
101+
OutOfBoundsMirrorFactory<T, RandomAccessibleInterval<T>> oobf //
102+
= new OutOfBoundsMirrorFactory<>(
103+
OutOfBoundsMirrorFactory.Boundary.SINGLE);
104+
return (in1, in2, in3, shape, out) -> {
105+
var extended = Views.extend(in1, oobf);
106+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
107+
var intervaled = Views.interval(neighborhoods, in1);
108+
LoopBuilder.setImages(intervaled, out).forEachPixel((in, container) -> op
109+
.compute(in, in2, in3, container));
110+
};
111+
}
112+
113+
/**
114+
* @implNote op names='adapt', priority='100.',
115+
* type='java.util.function.Function'
116+
*/
117+
@OpMethod(names = "adapt", type = Function.class)
118+
public static <T, U, V, W, F extends RandomAccessibleInterval<T>>
119+
Computers.Arity5<F, V, W, Shape, OutOfBoundsFactory<T, F>, RandomAccessibleInterval<U>>
120+
adapt3UsingShapeAndOOBF(Computers.Arity3<Neighborhood<T>, V, W, U> op)
121+
{
122+
return (in1, in2, in3, shape, oobf, out) -> {
123+
var extended = Views.extend(in1, oobf);
124+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
125+
var intervaled = Views.interval(neighborhoods, in1);
126+
LoopBuilder.setImages(intervaled, out).forEachPixel((in, container) -> op
127+
.compute(in, in2, in3, container));
128+
};
129+
}
130+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package net.imagej.ops2.adapt.complexLift;
2+
3+
import java.util.function.BiFunction;
4+
import java.util.function.Function;
5+
6+
import net.imglib2.img.Img;
7+
import net.imglib2.util.Util;
8+
import org.scijava.function.Computers;
9+
import org.scijava.function.Functions;
10+
import org.scijava.function.Producer;
11+
import org.scijava.ops.spi.OpDependency;
12+
import org.scijava.ops.spi.OpMethod;
13+
14+
import net.imglib2.Dimensions;
15+
import net.imglib2.RandomAccessibleInterval;
16+
import net.imglib2.algorithm.neighborhood.Neighborhood;
17+
import net.imglib2.algorithm.neighborhood.Shape;
18+
import net.imglib2.loops.LoopBuilder;
19+
import net.imglib2.outofbounds.OutOfBoundsFactory;
20+
import net.imglib2.outofbounds.OutOfBoundsMirrorFactory;
21+
import net.imglib2.type.Type;
22+
import net.imglib2.type.operators.SetZero;
23+
import net.imglib2.view.Views;
24+
25+
public class LiftNeighborhoodComputersToFunctionsOnImgs {
26+
27+
28+
/**
29+
* @implNote op names='adapt', priority='100.', type='java.util.function.Function'
30+
*/
31+
public static <T, U> BiFunction<RandomAccessibleInterval<T>, Shape, Img<T>>
32+
adaptUsingShape(
33+
@OpDependency(name="create", adaptable = false) BiFunction<Dimensions, T, Img<T>> creator,
34+
Computers.Arity1<Neighborhood<T>, T> op
35+
)
36+
{
37+
OutOfBoundsMirrorFactory<T, RandomAccessibleInterval<T>> oobf //
38+
= new OutOfBoundsMirrorFactory<>(OutOfBoundsMirrorFactory.Boundary.SINGLE);
39+
return (in, shape) -> {
40+
var output = creator.apply(in, Util.getTypeFromInterval(in));
41+
var extended = Views.extend(in, oobf);
42+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
43+
var intervaled = Views.interval(neighborhoods, in);
44+
LoopBuilder.setImages(intervaled, output).forEachPixel(op);
45+
return output;
46+
};
47+
}
48+
49+
/**
50+
* @implNote op names='adapt', priority='100.', type='java.util.function.Function'
51+
*/
52+
@OpMethod(names = "adapt", type = Function.class)
53+
public static <T, F extends RandomAccessibleInterval<T>>
54+
Functions.Arity3<F, Shape, OutOfBoundsFactory<T, ? super F>, Img<T>>
55+
adaptUsingShapeAndOOBF(
56+
@OpDependency(name="create", adaptable = false) BiFunction<Dimensions, T, Img<T>> creator,
57+
Computers.Arity1<Neighborhood<T>, T> op)
58+
{
59+
return (in, shape, oobf) -> {
60+
var output = creator.apply(in, Util.getTypeFromInterval(in));
61+
var extended = Views.extend(in, oobf);
62+
var neighborhoods = shape.neighborhoodsRandomAccessible(extended);
63+
var intervaled = Views.interval(neighborhoods, in);
64+
LoopBuilder.setImages(intervaled, output).forEachPixel(op);
65+
return output;
66+
};
67+
}
68+
69+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
package net.imagej.ops2.filter;
3+
4+
import net.imglib2.algorithm.neighborhood.Neighborhood;
5+
import net.imglib2.type.numeric.RealType;
6+
import net.imglib2.type.numeric.real.DoubleType;
7+
import org.scijava.function.Computers;
8+
import org.scijava.ops.spi.OpDependency;
9+
10+
public class NeighborhoodFilters {
11+
12+
/**
13+
* Computes the maximum over a {@link Neighborhood}, and stores it in the
14+
* passed output container
15+
*
16+
* @param op the Op able to compute the maximum
17+
* @param neighborhood the {@link Neighborhood} to compute over
18+
* @param output the preallocated output container
19+
* @param <T> the {@link java.lang.reflect.Type} of the elements of
20+
* {@code neighborhood}
21+
* @param <V> the {@link java.lang.reflect.Type} of the output container
22+
* @implNote op name='filter.max',type='org.scijava.function.Computers$Arity1'
23+
*/
24+
public static <T, V> void defaultMax(@OpDependency(
25+
name = "stats.max") Computers.Arity1<Iterable<T>, V> op,
26+
Neighborhood<T> neighborhood, V output)
27+
{
28+
op.compute(neighborhood, output);
29+
}
30+
31+
/**
32+
* Computes the mean over a {@link Neighborhood}, and stores it in the passed
33+
* output container
34+
*
35+
* @param op the Op able to compute the mean
36+
* @param neighborhood the {@link Neighborhood} to compute over
37+
* @param output the preallocated output container
38+
* @param <T> the {@link java.lang.reflect.Type} of the elements of
39+
* {@code neighborhood}
40+
* @param <V> the {@link java.lang.reflect.Type} of the output container
41+
* @implNote op
42+
* name='filter.mean',type='org.scijava.function.Computers$Arity1'
43+
*/
44+
public static <T, V> void defaultMean(@OpDependency(
45+
name = "stats.mean") Computers.Arity1<Iterable<T>, V> op,
46+
Neighborhood<T> neighborhood, V output)
47+
{
48+
op.compute(neighborhood, output);
49+
}
50+
51+
/**
52+
* Computes the median over a {@link Neighborhood}, and stores it in the
53+
* passed output container
54+
*
55+
* @param op the Op able to compute the median
56+
* @param neighborhood the {@link Neighborhood} to compute over
57+
* @param output the preallocated output container
58+
* @param <T> the {@link java.lang.reflect.Type} of the elements of
59+
* {@code neighborhood}
60+
* @param <V> the {@link java.lang.reflect.Type} of the output container
61+
* @implNote op
62+
* name='filter.median',type='org.scijava.function.Computers$Arity1'
63+
*/
64+
public static <T, V> void defaultMedian(@OpDependency(
65+
name = "stats.median") Computers.Arity1<Iterable<T>, V> op,
66+
Neighborhood<T> neighborhood, V output)
67+
{
68+
op.compute(neighborhood, output);
69+
}
70+
71+
/**
72+
* Computes the minimum over a {@link Neighborhood}, and stores it in the
73+
* passed output container
74+
*
75+
* @param op the Op able to compute the minimum
76+
* @param neighborhood the {@link Neighborhood} to compute over
77+
* @param output the preallocated output container
78+
* @param <T> the {@link java.lang.reflect.Type} of the elements of
79+
* {@code neighborhood}
80+
* @param <V> the {@link java.lang.reflect.Type} of the output container
81+
* @implNote op name='filter.min',type='org.scijava.function.Computers$Arity1'
82+
*/
83+
public static <T, V> void defaultMinimum(@OpDependency(
84+
name = "stats.min") Computers.Arity1<Iterable<T>, V> op,
85+
Neighborhood<T> neighborhood, V output)
86+
{
87+
op.compute(neighborhood, output);
88+
}
89+
90+
/**
91+
* Computes the variance over a {@link Neighborhood}, and stores it in the
92+
* passed output container
93+
*
94+
* @param op the Op able to compute the variance
95+
* @param neighborhood the {@link Neighborhood} to compute over
96+
* @param output the preallocated output container
97+
* @param <T> the {@link java.lang.reflect.Type} of the elements of
98+
* {@code neighborhood}
99+
* @param <V> the {@link java.lang.reflect.Type} of the output container
100+
* @implNote op
101+
* name='filter.variance',type='org.scijava.function.Computers$Arity1'
102+
*/
103+
public static <T, V> void defaultVariance(@OpDependency(
104+
name = "stats.variance") Computers.Arity1<Iterable<T>, V> op,
105+
Neighborhood<T> neighborhood, V output)
106+
{
107+
op.compute(neighborhood, output);
108+
}
109+
}

0 commit comments

Comments
 (0)