4343
4444import net .imglib2 .Cursor ;
4545import net .imglib2 .FinalInterval ;
46- import net .imglib2 .RandomAccess ;
4746import net .imglib2 .RandomAccessible ;
4847import net .imglib2 .RandomAccessibleInterval ;
48+ import net .imglib2 .loops .LoopBuilder ;
4949import net .imglib2 .type .numeric .NumericType ;
5050import net .imglib2 .util .Intervals ;
5151import net .imglib2 .view .IntervalView ;
5454/**
5555 * @author Tobias Pietzsch
5656 * @author Philipp Hanslovsky
57+ * @author Tim-Oliver Buchholz
58+ * @author Matthias Arzt
5759 *
5860 */
5961public class PartialDerivative
6062{
6163 // nice version...
6264 /**
63- * Compute the partial derivative of source in a particular dimension.
65+ * Compute the partial derivative (central difference approximation) of source
66+ * in a particular dimension:
67+ * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2},
68+ * where {@code e} is the unit vector along that dimension.
6469 *
6570 * @param source
6671 * source image, has to provide valid data in the interval of the
@@ -85,7 +90,10 @@ public static < T extends NumericType< T > > void gradientCentralDifference2( fi
8590
8691 // parallel version...
8792 /**
88- * Compute the partial derivative of source in a particular dimension.
93+ * Compute the partial derivative (central difference approximation) of source
94+ * in a particular dimension:
95+ * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2},
96+ * where {@code e} is the unit vector along that dimension.
8997 *
9098 * @param source
9199 * source image, has to provide valid data in the interval of the
@@ -157,81 +165,73 @@ public static < T extends NumericType< T > > void gradientCentralDifferenceParal
157165
158166 // fast version
159167 /**
160- * Compute the partial derivative of source in a particular dimension.
168+ * Compute the partial derivative (central difference approximation) of source
169+ * in a particular dimension:
170+ * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2},
171+ * where {@code e} is the unit vector along that dimension.
161172 *
162173 * @param source
163174 * source image, has to provide valid data in the interval of the
164175 * gradient image plus a one pixel border in dimension.
165- * @param gradient
176+ * @param result
166177 * output image
167178 * @param dimension
168179 * along which dimension the partial derivatives are computed
169180 */
170- public static < T extends NumericType < T > > void gradientCentralDifference ( final RandomAccessible < T > source , final RandomAccessibleInterval < T > gradient , final int dimension )
181+ public static < T extends NumericType < T > > void gradientCentralDifference ( final RandomAccessible < T > source ,
182+ final RandomAccessibleInterval < T > result , final int dimension )
171183 {
172- final int n = gradient .numDimensions ();
173-
174- final long [] min = new long [ n ];
175- gradient .min ( min );
176- final long [] max = new long [ n ];
177- gradient .max ( max );
178- final long [] shiftback = new long [ n ];
179- for ( int d = 0 ; d < n ; ++d )
180- shiftback [ d ] = min [ d ] - max [ d ];
181-
182- final RandomAccess < T > result = gradient .randomAccess ();
183- final RandomAccess < T > back = source .randomAccess ( Intervals .translate ( gradient , -1 , dimension ) );
184- final RandomAccess < T > front = source .randomAccess ( Intervals .translate ( gradient , 1 , dimension ) );
185-
186- result .setPosition ( min );
187- back .setPosition ( min );
188- back .bck ( dimension );
189- front .setPosition ( min );
190- front .fwd ( dimension );
191-
192- final long max0 = max [ 0 ];
193- while ( true )
194- {
195- // process pixel
196- final T t = result .get ();
197- t .set ( front .get () );
198- t .sub ( back .get () );
199- t .mul ( 0.5 );
184+ final RandomAccessibleInterval < T > back = Views .interval ( source , Intervals .translate ( result , -1 , dimension ) );
185+ final RandomAccessibleInterval < T > front = Views .interval ( source , Intervals .translate ( result , 1 , dimension ) );
186+
187+ LoopBuilder .setImages ( result , back , front ).forEachPixel ( ( r , b , f ) -> {
188+ r .set ( f );
189+ r .sub ( b );
190+ r .mul ( 0.5 );
191+ } );
192+ }
200193
201- // move to next pixel
202- // check dimension 0 separately to avoid the loop over d in most
203- // iterations
204- if ( result .getLongPosition ( 0 ) == max0 )
205- {
206- if ( n == 1 )
207- return ;
208- result .move ( shiftback [ 0 ], 0 );
209- back .move ( shiftback [ 0 ], 0 );
210- front .move ( shiftback [ 0 ], 0 );
211- // now check the remaining dimensions
212- for ( int d = 1 ; d < n ; ++d )
213- if ( result .getLongPosition ( d ) == max [ d ] )
214- {
215- result .move ( shiftback [ d ], d );
216- back .move ( shiftback [ d ], d );
217- front .move ( shiftback [ d ], d );
218- if ( d == n - 1 )
219- return ;
220- }
221- else
222- {
223- result .fwd ( d );
224- back .fwd ( d );
225- front .fwd ( d );
226- break ;
227- }
228- }
229- else
230- {
231- result .fwd ( 0 );
232- back .fwd ( 0 );
233- front .fwd ( 0 );
234- }
235- }
194+ /**
195+ * Compute the backward difference of source in a particular dimension:
196+ * {@code d_f( x ) = ( f( x ) - f( x - e ) )}
197+ * where {@code e} is the unit vector along that dimension
198+ *
199+ * @param source source image, has to provide valid data in the interval of
200+ * the gradient image plus a one pixel border in dimension.
201+ * @param result output image
202+ * @param dimension along which dimension the partial derivatives are computed
203+ */
204+ public static < T extends NumericType < T > > void gradientBackwardDifference ( final RandomAccessible < T > source ,
205+ final RandomAccessibleInterval < T > result , final int dimension )
206+ {
207+ final RandomAccessibleInterval < T > back = Views .interval ( source , Intervals .translate ( result , -1 , dimension ) );
208+ final RandomAccessibleInterval < T > front = Views .interval ( source , result );
209+
210+ LoopBuilder .setImages ( result , back , front ).forEachPixel ( ( r , b , f ) -> {
211+ r .set ( f );
212+ r .sub ( b );
213+ } );
214+ }
215+
216+ /**
217+ * Compute the forward difference of source in a particular dimension:
218+ * {@code d_f( x ) = ( f( x + e ) - f( x ) )}
219+ * where {@code e} is the unit vector along that dimension
220+
221+ * @param source source image, has to provide valid data in the interval of
222+ * the gradient image plus a one pixel border in dimension.
223+ * @param result output image
224+ * @param dimension along which dimension the partial derivatives are computed
225+ */
226+ public static < T extends NumericType < T > > void gradientForwardDifference ( final RandomAccessible < T > source ,
227+ final RandomAccessibleInterval < T > result , final int dimension )
228+ {
229+ final RandomAccessibleInterval < T > back = Views .interval ( source , result );
230+ final RandomAccessibleInterval < T > front = Views .interval ( source , Intervals .translate ( result , 1 , dimension ) );
231+
232+ LoopBuilder .setImages ( result , back , front ).forEachPixel ( ( r , b , f ) -> {
233+ r .set ( f );
234+ r .sub ( b );
235+ } );
236236 }
237237}
0 commit comments