|
30 | 30 | * |
31 | 31 | * RandomAccessibleInterval<O> result = ... |
32 | 32 | * |
33 | | - * new ImgMath<A, O>( Div<O>( Max<O>( img1, img2, img3 ), 3.0 ) ).into( result ); |
| 33 | + * compute( div( max( img1, img2, img3 ), 3.0 ) ).into( result ); |
34 | 34 | * } |
35 | 35 | * </pre> |
36 | 36 | * |
|
43 | 43 | */ |
44 | 44 | public class ImgMath |
45 | 45 | { |
46 | | - private final IFunction operation; |
47 | | - private final Converter< RealType< ? >, RealType< ? > > converter; |
48 | | - |
49 | | - public ImgMath( final IFunction operation ) |
50 | | - { |
51 | | - this( operation, |
52 | | - new Converter< RealType< ? >, RealType< ? > >() |
53 | | - { |
54 | | - @Override |
55 | | - public final void convert( final RealType< ? > input, final RealType< ? > output) { |
56 | | - output.setReal( input.getRealDouble() ); |
57 | | - } |
58 | | - }); |
59 | | - } |
60 | | - |
61 | | - public ImgMath( |
62 | | - final IFunction operation, |
63 | | - final Converter< RealType< ? >, RealType< ? > > converter |
64 | | - ) |
65 | | - { |
66 | | - this.operation = operation; |
67 | | - this.converter = converter; |
68 | | - } |
69 | | - |
70 | | - public < O extends RealType< O > > RandomAccessibleInterval< O > into( final RandomAccessibleInterval< O > target ) |
71 | | - { |
72 | | - // Recursive copy: initializes interval iterators |
73 | | - final IFunction f = this.operation.copy(); |
74 | | - // Set temporary computation holders |
75 | | - final O scrap = target.randomAccess().get().createVariable(); |
76 | | - f.setScrap( scrap ); |
77 | | - |
78 | | - final boolean compatible_iteration_order = this.setup( f, converter ); |
79 | | - |
80 | | - // Check compatible iteration order and dimensions |
81 | | - if ( compatible_iteration_order ) |
82 | | - { |
83 | | - // Evaluate function for every pixel |
84 | | - for ( final O output : Views.iterable( target ) ) |
85 | | - f.eval( output ); |
86 | | - } |
87 | | - else |
88 | | - { |
89 | | - // Incompatible iteration order |
90 | | - final Cursor< O > cursor = Views.iterable( target ).cursor(); |
91 | | - |
92 | | - while ( cursor.hasNext() ) |
93 | | - { |
94 | | - cursor.fwd(); |
95 | | - f.eval( cursor.get(), cursor ); |
96 | | - } |
97 | | - } |
98 | | - |
99 | | - return target; |
100 | | - } |
101 | | - |
102 | | - @SuppressWarnings({ "rawtypes", "unchecked" }) |
103 | | - private boolean setup( final IFunction f, final Converter< ?, ? > converter ) |
104 | | - { |
105 | | - final LinkedList< IFunction > ops = new LinkedList<>(); |
106 | | - ops.add( f ); |
107 | | - |
108 | | - // child-parent map |
109 | | - final HashMap< IFunction, IFunction > cp = new HashMap<>(); |
110 | | - |
111 | | - // Collect images to later check their iteration order |
112 | | - final LinkedList< RandomAccessibleInterval< ? > > images = new LinkedList<>(); |
113 | | - |
114 | | - // Collect Var instances to check that each corresponds to an upstream Let |
115 | | - final ArrayList< Var > vars = new ArrayList<>(); |
116 | | - |
117 | | - IFunction parent = null; |
118 | | - |
119 | | - // Iterate into the nested operations |
120 | | - while ( ! ops.isEmpty() ) |
121 | | - { |
122 | | - final IFunction op = ops.removeFirst(); |
123 | | - cp.put( op, parent ); |
124 | | - parent = op; |
125 | | - |
126 | | - if ( op instanceof IterableImgSource ) |
127 | | - { |
128 | | - final IterableImgSource iis = ( IterableImgSource )op; |
129 | | - // Side effect: set the converter from input to output types |
130 | | - iis.setConverter( converter ); |
131 | | - images.addLast( iis.rai ); |
132 | | - } |
133 | | - else if ( op instanceof IUnaryFunction ) |
134 | | - { |
135 | | - ops.addLast( ( ( IUnaryFunction )op ).getFirst() ); |
136 | | - |
137 | | - if ( op instanceof IBinaryFunction ) |
138 | | - { |
139 | | - ops.addLast( ( ( IBinaryFunction )op ).getSecond() ); |
140 | | - |
141 | | - if ( op instanceof ITrinaryFunction ) |
142 | | - { |
143 | | - ops.addLast( ( ( ITrinaryFunction )op ).getThird() ); |
144 | | - } |
145 | | - } |
146 | | - } |
147 | | - else if ( op instanceof Var ) |
148 | | - { |
149 | | - final Var var = ( Var )op; |
150 | | - vars.add( var ); |
151 | | - } |
152 | | - } |
153 | | - |
154 | | - // Check Vars: are they all using names declared in upstream Lets |
155 | | - all: for ( final Var var : vars ) |
156 | | - { |
157 | | - parent = var; |
158 | | - while ( null != ( parent = cp.get( parent ) ) ) |
159 | | - { |
160 | | - if ( parent instanceof Let ) |
161 | | - { |
162 | | - Let let = ( Let )parent; |
163 | | - if ( let.varName != var.name ) |
164 | | - continue; |
165 | | - // Else, found: Var is in use |
166 | | - continue all; |
167 | | - } |
168 | | - } |
169 | | - // No upstream Let found |
170 | | - throw new RuntimeException( "The Var(\"" + var.name + "\") does not read from any upstream Let. " ); |
171 | | - } |
172 | | - |
173 | | - return Util.compatibleIterationOrder( images ); |
174 | | - } |
175 | | - |
176 | | - static public final ImgMath compute( final IFunction operation ) |
| 46 | + static public final Compute compute( final IFunction operation ) |
177 | 47 | { |
178 | | - return new ImgMath( operation ); |
| 48 | + return new Compute( operation ); |
179 | 49 | } |
180 | 50 |
|
181 | | - static public final ImgMath compute( final IFunction operation, final Converter< RealType< ? >, RealType< ? > > converter ) |
| 51 | + static public final Compute compute( final IFunction operation, final Converter< RealType< ? >, RealType< ? > > converter ) |
182 | 52 | { |
183 | | - return new ImgMath( operation, converter ); |
| 53 | + return new Compute( operation, converter ); |
184 | 54 | } |
185 | 55 |
|
186 | 56 | static public final Add add( final Object o1, final Object o2 ) |
|
0 commit comments