From 4811d0778739454f926c3f2e04811811a8e8f4e0 Mon Sep 17 00:00:00 2001
From: Gabriel Selzer
+ * Creates an appropriate temporary image and calls
+ * {@link #DoG(double[], double[], RandomAccessible, RandomAccessible, RandomAccessibleInterval, ExecutorService)}
+ * .
+ *
* Note: The input image type must be a signed type! Otherwise gradient * computation will not work. - * + * + * @implNote op name='edge.subpixelEdgels', type=Function * @param input * input image * @param factory diff --git a/src/main/java/net/imglib2/algorithm/fill/FloodFill.java b/src/main/java/net/imglib2/algorithm/fill/FloodFill.java index 44a578d77..330ca2127 100644 --- a/src/main/java/net/imglib2/algorithm/fill/FloodFill.java +++ b/src/main/java/net/imglib2/algorithm/fill/FloodFill.java @@ -105,6 +105,53 @@ public static < T extends Type< T >, U extends Type< U > > void fill( fill( source, target, seed, fillLabel, shape, filter ); } + /** + * Iterative n-dimensional flood fill for arbitrary neighborhoods: Starting + * at seed location, write fillLabel into target at current location and + * continue for each pixel in neighborhood defined by shape if neighborhood + * pixel is in the same connected component and fillLabel has not been + * written into that location yet. + * + * Convenience call to + * {@link #fill(RandomAccessible, RandomAccessible, Localizable, Type, Shape, BiPredicate)}. + * seedLabel is extracted from source at seed location. + *
+ * This method differs from + * {@link #fill(RandomAccessible, RandomAccessible, Localizable, Type, Shape)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='fill.flood', type=Computer + * @param source + * input + * @param seed + * Start flood fill at this location. + * @param fillLabel + * Immutable. Value to be written into valid flood fill + * locations. + * @param shape + * Defines neighborhood that is considered for connected + * components, e.g. + * {@link net.imglib2.algorithm.neighborhood.DiamondShape} + * @param target + * {@link RandomAccessible} to be written into. May be the same + * as input. + * @param+ * This method differs from + * {@link #fill(RandomAccessible, RandomAccessible, Localizable, Type, Shape, BiPredicate)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='fill.flood', type=Computer + * @param source + * input + * @param seed + * Start flood fill at this location. + * @param fillLabel + * Immutable. Value to be written into valid flood fill + * locations. + * @param shape + * Defines neighborhood that is considered for connected + * components, e.g. + * {@link net.imglib2.algorithm.neighborhood.DiamondShape} + * @param filter + * Returns true if pixel has not been visited yet and should be + * written into. Returns false if target pixel has been visited + * or source pixel is not part of the same connected component. + * @param target + * {@link RandomAccessible} to be written into. May be the same + * as input. + * @param+ * This method differs from + * {@link #fill(RandomAccessible, RandomAccessible, Localizable, Shape, BiPredicate, Consumer)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='fill.flood', type=Computer + * @param source + * input + * @param seed + * Start flood fill at this location. + * @param shape + * Defines neighborhood that is considered for connected + * components, e.g. + * {@link net.imglib2.algorithm.neighborhood.DiamondShape} + * @param filter + * Returns true if pixel has not been visited yet and should be + * written into. Returns false if target pixel has been visited + * or source pixel is not part of the same connected component. + * @param writer + * Defines how fill label is written into target at current + * location. + * @param target + * {@link RandomAccessible} to be written into. May be the same + * as input. + * @param+ * This method differs from + * {@link #gradientCentralDifference2(RandomAccessible, RandomAccessibleInterval, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.gradientCentralDifference2', type=Computer + * @param source + * source image, has to provide valid data in the interval of the + * gradient image plus a one pixel border in dimension. + * @param dimension + * along which dimension the partial derivatives are computed + * @param gradient + * output image + */ + public static < T extends NumericType< T > > void gradientCentralDifference2( final RandomAccessible< T > source, final int dimension, final RandomAccessibleInterval< T > gradient) + { + gradientCentralDifference2( source, gradient, dimension ); + } + // parallel version... /** * Compute the partial derivative (central difference approximation) of source @@ -163,6 +189,42 @@ public static < T extends NumericType< T > > void gradientCentralDifferenceParal f.get(); } + /** + * Compute the partial derivative (central difference approximation) of source + * in a particular dimension: + * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2}, + * where {@code e} is the unit vector along that dimension. + *+ * This method differs from + * {@link #gradientCentralDifferenceParallel(RandomAccessible, RandomAccessibleInterval, int, int, ExecutorService)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.gradientCentralDifferenceParallel', type=Computer + * @param source + * source image, has to provide valid data in the interval of the + * gradient image plus a one pixel border in dimension. + * @param dimension + * along which dimension the partial derivatives are computed + * @param nTasks + * Number of tasks for gradient computation. + * @param es + * {@link ExecutorService} providing workers for gradient + * computation. Service is managed (created, shutdown) by caller. + * @param gradient + * output image + */ + public static < T extends NumericType< T > > void gradientCentralDifferenceParallel( + final RandomAccessible< T > source, + final int dimension, + final int nTasks, + final ExecutorService es, + final RandomAccessibleInterval< T > gradient ) throws InterruptedException, ExecutionException + { + gradientCentralDifferenceParallel( source, gradient, dimension, nTasks, es ); + } + // fast version /** * Compute the partial derivative (central difference approximation) of source @@ -191,6 +253,33 @@ public static < T extends NumericType< T > > void gradientCentralDifference( fin } ); } + /** + * Compute the partial derivative (central difference approximation) of source + * in a particular dimension: + * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2}, + * where {@code e} is the unit vector along that dimension. + *+ * This method differs from + * {@link #gradientCentralDifference(RandomAccessible, RandomAccessibleInterval, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.gradientCentralDifference', type=Computer + * @param source + * source image, has to provide valid data in the interval of the + * gradient image plus a one pixel border in dimension. + * @param dimension + * along which dimension the partial derivatives are computed + * @param result + * output image + */ + public static < T extends NumericType< T > > void gradientCentralDifference( final RandomAccessible< T > source, + final int dimension, final RandomAccessibleInterval< T > result) + { + gradientCentralDifference( source, result, dimension ); + } + /** * Compute the backward difference of source in a particular dimension: * {@code d_f( x ) = ( f( x ) - f( x - e ) )} @@ -213,6 +302,29 @@ public static < T extends NumericType< T > > void gradientBackwardDifference( fi } ); } + /** + * Compute the backward difference of source in a particular dimension: + * {@code d_f( x ) = ( f( x ) - f( x - e ) )} + * where {@code e} is the unit vector along that dimension + *+ * This method differs from + * {@link #gradientBackwardDifference(RandomAccessible, RandomAccessibleInterval, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.gradientBackwardDifference', type=Computer + * @param source source image, has to provide valid data in the interval of + * the gradient image plus a one pixel border in dimension. + * @param dimension along which dimension the partial derivatives are computed + * @param result output image + */ + public static < T extends NumericType< T > > void gradientBackwardDifference( final RandomAccessible< T > source, + final int dimension, final RandomAccessibleInterval< T > result) + { + gradientBackwardDifference( source, result, dimension ); + } + /** * Compute the forward difference of source in a particular dimension: * {@code d_f( x ) = ( f( x + e ) - f( x ) )} @@ -234,4 +346,27 @@ public static < T extends NumericType< T > > void gradientForwardDifference( fin r.sub( b ); } ); } + + /** + * Compute the forward difference of source in a particular dimension: + * {@code d_f( x ) = ( f( x + e ) - f( x ) )} + * where {@code e} is the unit vector along that dimension + *+ * This method differs from + * {@link #gradientForwardDifference(RandomAccessible, RandomAccessibleInterval, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.gradientForwardDifference', type=Computer + * @param source source image, has to provide valid data in the interval of + * the gradient image plus a one pixel border in dimension. + * @param dimension along which dimension the partial derivatives are computed + * @param result output image + */ + public static < T extends NumericType< T > > void gradientForwardDifference( final RandomAccessible< T > source, + final int dimension, final RandomAccessibleInterval< T > result) + { + gradientForwardDifference( source, result, dimension ); + } } diff --git a/src/main/java/net/imglib2/algorithm/hough/HoughTransforms.java b/src/main/java/net/imglib2/algorithm/hough/HoughTransforms.java index 524ee9c69..17343e344 100644 --- a/src/main/java/net/imglib2/algorithm/hough/HoughTransforms.java +++ b/src/main/java/net/imglib2/algorithm/hough/HoughTransforms.java @@ -105,6 +105,7 @@ private static int defaultRho( final Dimensions dimensions ) * Returns the size of the vote space output image given an input * {@link RandomAccessibleInterval}. * + * @implNote op names='filter.hough.getVotespaceSize', type=Function * @param dimensions * - the {@link Dimensions} over which the Hough Line Transform * will be run @@ -119,6 +120,7 @@ public static long[] getVotespaceSize( final Dimensions dimensions ) * Returns the size of the vote space output image given an input * {@link RandomAccessibleInterval}. * + * @implNote op names='filter.hough.getVotespaceSize', type=Function * @param dimensions * - the {@link Dimensions} over which the Hough Line Transform * will be run @@ -135,6 +137,7 @@ public static long[] getVotespaceSize( final Dimensions dimensions, final int nT * Returns the size of the voteSpace output image given desired {@code nRho} * and {@code nTheta} values. * + * @implNote op names='filter.hough.getVotespaceSize', type=Function * @param nRho * - the number of bins for rho resolution * @param nTheta @@ -149,6 +152,7 @@ public static long[] getVotespaceSize( final int nRho, final int nTheta ) /** * Pick vote space peaks with a {@link LocalExtrema}. * + * @implNote op names='filter.hough.pickLinePeaks', type=Function * @param voteSpace * - the {@link RandomAccessibleInterval} containing the output * of a Hough Transform vote @@ -170,6 +174,7 @@ public static < T extends IntegerType< T > > List< Point > pickLinePeaks( /** * Pick vote space peaks with a {@link LocalExtrema}. * + * @implNote op names='filter.hough.pickLinePeaks', type=Function * @param voteSpace * - the {@link RandomAccessibleInterval} containing the output * of a Hough Transform vote @@ -201,6 +206,8 @@ public static < T extends Comparable< T > > List< Point > pickLinePeaks( * Runs a Hough Line Tranform on an image and populates the vote space * parameter with the results. * + * @implNote op names='filter.hough.voteLines', + * type=Computer * @param input * - the {@link RandomAccessibleInterval} to run the Hough Line * Transform over @@ -236,6 +243,34 @@ public static < T extends Comparable< T >, U extends IntegerType< U > > void vot voteLines( input, votespace, nTheta, defaultRho( input ), Util.getTypeFromInterval( input ) ); } + /** + * Runs a Hough Line Tranform on an image and populates the vote space + * parameter with the results. + *+ * This method differs from + * {@link #voteLines(RandomAccessibleInterval, RandomAccessibleInterval, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.hough.voteLines', type=Computer + * @param input + * - the {@link RandomAccessibleInterval} to run the Hough Line + * Transform over + * @param nTheta + * - the number of bins for theta resolution + * @param votespace + * - the {@link RandomAccessibleInterval} in which the results + * are stored + */ + public static < T extends Comparable< T >, U extends IntegerType< U > > void voteLines( + final RandomAccessibleInterval< T > input, + final int nTheta, + final RandomAccessibleInterval< U > votespace) + { + voteLines( input, votespace, nTheta); + } + /** * Runs a Hough Line Tranform on an image and populates the vote space * parameter with the results. @@ -260,6 +295,37 @@ public static < T extends Comparable< T >, U extends IntegerType< U > > void vot voteLines( input, votespace, nTheta, nRho, Util.getTypeFromInterval( input ) ); } + /** + * Runs a Hough Line Tranform on an image and populates the vote space + * parameter with the results. + *+ * This method differs from + * {@link #voteLines(RandomAccessibleInterval, RandomAccessibleInterval, int, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op names='filter.hough.voteLines', type=Computer + * @param input + * - the {@link RandomAccessibleInterval} to run the Hough Line + * Transform over + * @param votespace + * - the {@link RandomAccessibleInterval} in which the results + * are stored + * @param nTheta + * - the number of bins for theta resolution + * @param nRho + * - the number of bins for rho resolution + */ + public static < T extends Comparable< T >, U extends IntegerType< U > > void voteLines( + final RandomAccessibleInterval< T > input, + final int nTheta, + final int nRho, + final RandomAccessibleInterval< U > votespace) + { + voteLines(input, votespace, nTheta, nRho); + } + /** * Runs a Hough Line Tranform on an image and populates the vote space * parameter with the results. @@ -290,6 +356,42 @@ public static < T extends Comparable< T >, U extends IntegerType< U > > void vot voteLines( input, votespace, nTheta, nRho, p ); } + /** + * Runs a Hough Line Tranform on an image and populates the vote space + * parameter with the results. + *+ * This method differs from + * {@link #voteLines(RandomAccessibleInterval, RandomAccessibleInterval, int, int, Comparable)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.hough.voteLines', type=Computer + * @param input + * - the {@link RandomAccessibleInterval} to run the Hough Line + * Transform over + * @param nTheta + * - the number of bins for theta resolution + * @param nRho + * - the number of bins for rho resolution + * @param threshold + * - the minimum value allowed by the populator. Any input less + * than this value will be disregarded by the populator. + * @param votespace + * - the {@link RandomAccessibleInterval} in which the results + * are stored + */ + public static < T extends Comparable< T >, U extends IntegerType< U > > void voteLines( + final RandomAccessibleInterval< T > input, + final int nTheta, + final int nRho, + final T threshold, + final RandomAccessibleInterval< U > votespace) + + { + voteLines(input, votespace, nTheta, nRho, threshold); + } + /** * * Runs a Hough Line Tranform on an image and populates the vote space @@ -403,12 +505,85 @@ public static < T, U extends IntegerType< U > > void voteLines( } } + /** + * + * Runs a Hough Line Tranform on an image and populates the vote space + * parameter with the results. + *+ * Vote space here has two dimensions: {@code rho} and {@code theta}. + * {@code theta} is measured in radians {@code [-pi/2 pi/2)}, {@code rho} is + * measured in {@code [-rhoMax, rhoMax)}. + *
+ *+ * Lines are modeled as + *
+ * + *+ * l(t) = | x | = rho * | cos(theta) | + t * | sin(theta) | + * | y | | -sin(theta) | | cos(theta) | + *+ *
+ * In other words, {@code rho} represents the signed minimum distance from + * the image origin to the line, and {@code theta} indicates the angle + * between the row-axis and the minimum offset vector. + *
+ *+ * For a given point, then, votes are placed along the curve + *
+ * + *+ * rho = y * sin( theta ) + x * cos( theta ) + *+ *
+ * It is important to note that the interval of the first dimension of the + * vote space image is NOT {@code [-maxRho, maxRho)} but instead + * {@code [0, maxRho * 2)}; the same applies to the second dimension of the + * vote space as well. Thus if {@link HoughTransforms#pickLinePeaks} is not + * used to retrieve the maxima from the vote space, the vote space will have + * to be translated by {@code -maxRho} in dimension 0 to get the correct + * {@code rho} and {@code theta} values from the vote space. + *
+ *+ * This method differs from + * {@link #voteLines(RandomAccessibleInterval, RandomAccessibleInterval, int, int, Predicate)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='filter.hough.voteLines', type=Computer + * @param input + * - the {@link RandomAccessibleInterval} to run the Hough Line + * Transform over + * @param nTheta + * - the number of bins for theta resolution + * @param nRho + * - the number of bins for rho resolution + * @param filter + * - a {@link Predicate} judging whether or not the a value is + * above the minimum value allowed by the populator. Any input + * less than or equal to this value will be disregarded by the + * populator. + * @param votespace + * - the {@link RandomAccessibleInterval} in which the results + * are stored + */ + public static < T, U extends IntegerType< U > > void voteLines( + final RandomAccessibleInterval< T > input, + final int nTheta, + final int nRho, + final Predicate< T > filter, + final RandomAccessibleInterval< U > votespace) + { + voteLines(input, votespace, nTheta, nRho, filter); + } + /** * Method used to convert the {rho, theta} output of the * {@link HoughTransforms#voteLines} algorithm into a more useful * y-intercept value. Used with {@link HoughTransforms#getSlope} to create * line equations. * + * @implNote op name='filter.hough.getIntercept', type=Function * @param rho * - the {@code rho} of the line * @param theta @@ -427,6 +602,7 @@ public static double getIntercept( final long rho, final long theta ) * value. Used with {@link HoughTransforms#getIntercept} to create line * equations. * + * @implNote op name='filter.hough.getSlope', type=Function * @param theta * - the {@code theta} of the line * @return {@code double} - the y-intercept of the line diff --git a/src/main/java/net/imglib2/algorithm/kdtree/ConvexPolytope.java b/src/main/java/net/imglib2/algorithm/kdtree/ConvexPolytope.java index 11cbb1c98..bc7a45a36 100644 --- a/src/main/java/net/imglib2/algorithm/kdtree/ConvexPolytope.java +++ b/src/main/java/net/imglib2/algorithm/kdtree/ConvexPolytope.java @@ -65,6 +65,7 @@ public ConvexPolytope( final HyperPlane... hyperplanes ) /** * Apply an {@link AffineGet affine transformation} to a {@link HyperPlane}. * + * @implNote op name='transform.affine', type=Function * @param polytope * a polytope. * @param transform diff --git a/src/main/java/net/imglib2/algorithm/kdtree/HyperPlane.java b/src/main/java/net/imglib2/algorithm/kdtree/HyperPlane.java index d8b9a6290..76d38fbb0 100644 --- a/src/main/java/net/imglib2/algorithm/kdtree/HyperPlane.java +++ b/src/main/java/net/imglib2/algorithm/kdtree/HyperPlane.java @@ -74,6 +74,7 @@ public double getDistance() /** * Apply an {@link AffineGet affine transformation} to a {@link HyperPlane}. * + * @implNote op name='transform.affine', type=Function * @param plane * a plane. * @param transform diff --git a/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponentAnalysis.java b/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponentAnalysis.java index fe9b88f4a..f4e72ce29 100644 --- a/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponentAnalysis.java +++ b/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponentAnalysis.java @@ -117,6 +117,7 @@ public static < T > ToLongBiFunction< Localizable, T > idFromIntervalIndexer( fi * generalization for higher dimenions over a binary mask. {@code mask} and * {@code labeling} are expected to have equal min and max. * + * @implNote op name='labeling.connectedComponents', type=Computer * @param mask * Boolean mask to distinguish foreground ({@code true}) from * background ({@code false}). @@ -170,6 +171,44 @@ public static < B extends BooleanType< B >, L extends IntegerType< L > > void co new StartAtOneIdForNextSet() ); } + /** + * + * Implementation of connected component analysis that uses + * {@link IntArrayRankedUnionFind} to find sets of pixels that are connected + * with respect to a neighborhood ({@code shape}) over a binary mask. + * {@code mask} + * and {@code labeling} are expected to have equal min and max. + *+ * This method differs from + * {@link #connectedComponents(RandomAccessibleInterval, RandomAccessibleInterval, Shape)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='labeling.connectedComponents', type=Computer + * @param mask + * Boolean mask to distinguish foreground ({@code true}) from + * background ({@code false}). + * @param shape + * Connectivity of connected components, e.g. 4-neighborhood + * ({@link DiamondShape}), 8-neighborhood + * ({@link RectangleNeighborhood}) and their generalisations for + * higher dimensions. + * @param labeling + * Output parameter to store labeling: background pixels are + * labeled zero, foreground pixels are greater than zero: 1, 2, + * ..., N. Note that initially all pixels are expected to be zero + * as background values will not be written. + */ + public static < B extends BooleanType< B >, L extends IntegerType< L > > void connectedComponents( + final RandomAccessibleInterval< B > mask, + final Shape shape, + final RandomAccessibleInterval< L > labeling) + { + connectedComponents(mask, labeling, shape); + } + + /** * * Implementation of connected component analysis that uses @@ -216,6 +255,55 @@ public static < B extends BooleanType< B >, L extends IntegerType< L > > void co UnionFind.relabel( mask, labeling, uf, idForPixel, idForSet ); } + /** + * + * Implementation of connected component analysis that uses + * {@link UnionFind} to find sets of pixels that are connected with respect + * to a neighborhood ({@code shape}) over a binary mask. {@code mask} and + * {@code labeling} are expected to have equal min and max. + *+ * This method differs from + * {@link #connectedComponents(RandomAccessibleInterval, RandomAccessibleInterval, Shape, LongFunction, ToLongBiFunction, LongUnaryOperator)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='labeling.connectedComponents', type=Computer + * @param mask + * Boolean mask to distinguish foreground ({@code true}) from + * background ({@code false}). + * @param shape + * Connectivity of connected components, e.g. 4-neighborhood + * ({@link DiamondShape}), 8-neighborhood + * ({@link RectangleNeighborhood}) and their generalisations for + * higher dimensions. + * @param unionFindFactory + * Creates appropriate {@link UnionFind} data structure for size + * of {@code labeling}, e.g. {@link IntArrayRankedUnionFind} of + * appropriate size. + * @param idForPixel + * Create id from pixel location and value. Multiple calls with + * the same argument should always return the same result. + * @param idForSet + * Create id for a set from the root id of a set. Multiple calls + * with the same argument should always return the same result. + * @param labeling + * Output parameter to store labeling: background pixels are + * labeled zero, foreground pixels are greater than zero: 1, 2, + * ..., N. Note that this is expected to be zero as background + * values will not be written. + */ + public static < B extends BooleanType< B >, L extends IntegerType< L > > void connectedComponents( + final RandomAccessibleInterval< B > mask, + final Shape shape, + final LongFunction< UnionFind > unionFindFactory, + final ToLongBiFunction< Localizable, L > idForPixel, + final LongUnaryOperator idForSet, + final RandomAccessibleInterval< L > labeling) + { + connectedComponents( mask, labeling, shape, unionFindFactory, idForPixel, idForSet ); + } + private static < B extends BooleanType< B >, L extends IntegerType< L > > UnionFind makeUnion( final RandomAccessibleInterval< B > mask, final RandomAccessibleInterval< L > labeling, diff --git a/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponents.java b/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponents.java index db92a5b05..c5c9658a0 100644 --- a/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponents.java +++ b/src/main/java/net/imglib2/algorithm/labeling/ConnectedComponents.java @@ -112,6 +112,41 @@ public static < T extends IntegerType< T >, L, I extends IntegerType< I > > void service.shutdown(); } + /** + * Label all connected components in the given input image. In the output + * image, all background pixels will be labeled to {} and foreground + * components labeled as {1}, {2}, {3}, etc. where 1, 2, 3 are labels + * returned by {@code labelGenerator.next()}. {@code labelGenerator.next()} + * is called exactly n times if the input contains + * n connected components. + *+ * This method differs from + * {@link #labelAllConnectedComponents(RandomAccessible, ImgLabeling, Iterator, StructuringElement)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='labeling.connectedComponents', type=Computer + * @param input + * input image with pixels != 0 belonging to foreground. + * @param labelGenerator + * produces labels for the connected components. + * @param se + * structuring element to use. 8-connected or 4-connected + * (respectively n-dimensional analog) + * @param labeling + * output labeling in which the connected components will be + * labeled. + */ + public static < T extends IntegerType< T >, L, I extends IntegerType< I > > void labelAllConnectedComponents( + final RandomAccessible< T > input, + final Iterator< L > labelGenerator, + final StructuringElement se, + final ImgLabeling< L, I > labeling) + { + labelAllConnectedComponents( input, labeling, labelGenerator, se ); + } + /** * Label all connected components in the given input image. In the output * image, all background pixels will be labeled to {} and foreground @@ -154,6 +189,44 @@ public static < T extends IntegerType< T >, L, I extends IntegerType< I > > void labeling.getMapping().setLabelSets( labelSets ); } + /** + * Label all connected components in the given input image. In the output + * image, all background pixels will be labeled to {} and foreground + * components labeled as {1}, {2}, {3}, etc. where 1, 2, 3 are labels + * returned by {@code labelGenerator.next()}. {@code labelGenerator.next()} + * is called exactly n times if the input contains + * n connected components. + *+ * This method differs from + * {@link #labelAllConnectedComponents(RandomAccessible, ImgLabeling, Iterator, StructuringElement, ExecutorService)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='labeling.connectedComponents', type=Computer + * @param input + * input image with pixels != 0 belonging to foreground. + * @param labelGenerator + * produces labels for the connected components. + * @param se + * structuring element to use. 8-connected or 4-connected + * (respectively n-dimensional analog) + * @param service + * service providing threads for multi-threading + * @param labeling + * output labeling in which the connected components will be + * labeled. + */ + public static < T extends IntegerType< T >, L, I extends IntegerType< I > > void labelAllConnectedComponents( + final RandomAccessible< T > input, + final Iterator< L > labelGenerator, + final StructuringElement se, + final ExecutorService service, + final ImgLabeling< L, I > labeling) + { + labelAllConnectedComponents( input, labeling, labelGenerator, se, service ); + } + /** * "Label" all connected components in the given input image. In the output * image, all background pixels will be set to 0 and foreground components diff --git a/src/main/java/net/imglib2/algorithm/lazy/Lazy.java b/src/main/java/net/imglib2/algorithm/lazy/Lazy.java index e98f007df..f34714625 100644 --- a/src/main/java/net/imglib2/algorithm/lazy/Lazy.java +++ b/src/main/java/net/imglib2/algorithm/lazy/Lazy.java @@ -81,6 +81,7 @@ private Lazy() /** * Create a memory {@link CachedCellImg} with a cell {@link Cache}. * + * @implNote op names='create.cellImg, create', type=Function * @param grid * @param cache * @param type @@ -126,6 +127,7 @@ else if ( DoubleType.class.isInstance( type ) ) /** * Create a memory {@link CachedCellImg} with a {@link CellLoader}. * + * @implNote op name='create.cellImg,create', type=Function * @param targetInterval * @param blockSize * @param type @@ -157,6 +159,7 @@ else if ( DoubleType.class.isInstance( type ) ) * Create a memory {@link CachedCellImg} with a cell generator * {@link Consumer}. * + * @implNote op name='create.cellImg, create', type=Function * @param targetInterval * @param blockSize * @param type diff --git a/src/main/java/net/imglib2/algorithm/localextrema/LocalExtrema.java b/src/main/java/net/imglib2/algorithm/localextrema/LocalExtrema.java index d8c70acbc..04e25b70c 100644 --- a/src/main/java/net/imglib2/algorithm/localextrema/LocalExtrema.java +++ b/src/main/java/net/imglib2/algorithm/localextrema/LocalExtrema.java @@ -167,6 +167,7 @@ public static < P, T > ArrayList< P > findLocalExtrema( final RandomAccessibleIn * {@code source} accordingly. The returned coordinate list is valid * for the original {@code source}. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this * {@link RandomAccessibleInterval} @@ -208,6 +209,7 @@ public static < P, T > List< P > findLocalExtrema( * {@code source} accordingly. The returned coordinate list is valid * for the original {@code source}. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this * {@link RandomAccessibleInterval} @@ -248,6 +250,7 @@ public static < P, T > List< P > findLocalExtrema( * The task is parallelized along the longest dimension of * {@code interval} * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema of the function defined by this * {@link RandomAccessible} @@ -287,6 +290,7 @@ public static < P, T > List< P > findLocalExtrema( * test for being an extremum can be specified as an implementation of the * {@link LocalNeighborhoodCheck} interface. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema of the function defined by this * {@link RandomAccessible} @@ -367,6 +371,7 @@ public static < P, T > List< P > findLocalExtrema( * expand {@code source} accordingly. The returned coordinate list is * valid for the original {@code source}. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this * {@link RandomAccessibleInterval} @@ -393,6 +398,7 @@ public static < P, T > List< P > findLocalExtrema( * {@code source} accordingly. The returned coordinate list is valid * for the original {@code source}. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this * {@link RandomAccessibleInterval} @@ -427,6 +433,7 @@ public static < P, T > List< P > findLocalExtrema( * * The local neighborhood is defined as {@link RectangleShape} with span 1. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this {@link RandomAccessible} * @param interval @@ -451,6 +458,7 @@ public static < P, T > List< P > findLocalExtrema( * test for being an extremum can be specified as an implementation of the * {@link LocalNeighborhoodCheck} interface. * + * @implNote op name='image.localExtrema', type=Function * @param source * Find local extrema within this {@link RandomAccessible} * @param interval @@ -495,6 +503,7 @@ public static < P, T > List< P > findLocalExtrema( * determining by how much a {@link RandomAccessibleInterval} should be * expanded to include min and max positions in the local extrema search. * + * @implNote op name='geom.borderSize', type=Function * @param shape * Defines the local neighborhood * @param nDim @@ -523,6 +532,7 @@ public static long[] getRequiredBorderSize( final Shape shape, final int nDim ) * Shrink a {@link RandomAccessibleInterval} symmetrically, i.e. the margin * is applied both to min and max. * + * @implNote op name='image.shrink', type=Function * @param source * @param margin * @return @@ -538,6 +548,7 @@ public static < T > IntervalView< T > shrink( final RandomAccessibleInterval< T /** * + * @implNote op name='image.biggestDimension', type=Function * @param interval * @return The biggest dimension of interval. */ diff --git a/src/main/java/net/imglib2/algorithm/math/ImgMath.java b/src/main/java/net/imglib2/algorithm/math/ImgMath.java index 9196d381c..6d86d6362 100644 --- a/src/main/java/net/imglib2/algorithm/math/ImgMath.java +++ b/src/main/java/net/imglib2/algorithm/math/ImgMath.java @@ -114,21 +114,33 @@ */ public class ImgMath { + /** + * @implNote op name='math.compute', type=Function + */ static public final Compute compute( final IFunction operation ) { return new Compute( operation ); } - + + /** + * @implNote op name='math.compute', type=Function + */ static public final < I extends RealType< I > > Compute compute( final RandomAccessibleInterval< I > src ) { return compute( img( src ) ); } - + + /** + * @implNote op name='math.computeIntoFloats', type=Function + */ static public final RandomAccessibleInterval< FloatType > computeIntoFloats( final IFunction operation ) { return new Compute( operation ).into( new ArrayImgFactory< FloatType >( new FloatType() ).create( Util.findImg( operation ).iterator().next() ) ); } - + + /** + * @implNote op name='math.computeInto', type=Function + */ static public final < O extends RealType< O > > RandomAccessibleInterval< O > computeInto( final IFunction operation, final RandomAccessibleInterval< O > target ) @@ -136,6 +148,9 @@ static public final < O extends RealType< O > > RandomAccessibleInterval< O > co return new Compute( operation ).into( target ); } + /** + * @implNote op name='math.computeInto', type=Function + */ static public final < O extends RealType< O > > RandomAccessibleInterval< O > computeInto( final IFunction operation, final RandomAccessibleInterval< O > target, @@ -143,12 +158,18 @@ static public final < O extends RealType< O > > RandomAccessibleInterval< O > co { return new Compute( operation ).into( target, converter ); } - + + /** + * @implNote op name='math.computeIntoImg', type=Function + */ static public final < O extends NativeType< O > & RealType< O > > RandomAccessibleInterval< O > computeIntoImg( final IFunction operation ) { return compute( operation ).intoImg(); } - + + /** + * @implNote op name='math.computeIntoArrayImg', type=Function + */ static public final < O extends NativeType< O > & RealType< O > > RandomAccessibleInterval< O > computeIntoArrayImg( final IFunction operation ) { return compute( operation ).intoArrayImg(); @@ -156,7 +177,8 @@ static public final < O extends NativeType< O > & RealType< O > > RandomAccessib /** * Almost all {@code IFunction} are also {@code ViewableFunction}. - * + * + * @implNote op name='math.view', type=Function * @param operation * @return */ @@ -167,7 +189,8 @@ static public final < O extends RealType< O > > RandomAccessibleInterval< O > vi /** * Almost all {@code IFunction} are also {@code ViewableFunction}. - * + * + * @implNote op name='math.viewFloats', type=Function * @param operation * @return */ @@ -175,268 +198,427 @@ static public final RandomAccessibleInterval< FloatType > viewFloats( final View { return operation.view( new FloatType() ); } - + + /** + * @implNote op name='math.add', type=Function + */ static public final Add add( final Object o1, final Object o2 ) { return new Add( o1, o2 ); } - + + /** + * @implNote op name='math.add', type=Function + */ static public final Add add( final Object... obs ) { return new Add( obs ); } - + + /** + * @implNote op name='math.sub', type=Function + */ static public final Sub sub( final Object o1, final Object o2 ) { return new Sub( o1, o2 ); } - + + /** + * @implNote op name='math.sub', type=Function + */ static public final Sub sub( final Object... obs ) { return new Sub( obs ); } - + + /** + * @implNote op name='math.minus', type=Function + */ static public final Minus minus( final Object o1 ) { return new Minus( o1 ); } - + + /** + * @implNote op name='math.mul', type=Function + */ static public final Mul mul( final Object o1, final Object o2 ) { return new Mul( o1, o2 ); } - + + /** + * @implNote op name='math.mul', type=Function + */ static public final Mul mul( final Object... obs ) { return new Mul( obs ); } - + + /** + * @implNote op name='math.div', type=Function + */ static public final Div div( final Object o1, final Object o2 ) { return new Div( o1, o2 ); } - + + /** + * @implNote op name='math.div', type=Function + */ static public final Div div( final Object... obs ) { return new Div( obs ); } - + + /** + * @implNote op name='math.pow', type=Function + */ static public final Pow pow( final Object o1, final Object o2 ) { return new Pow( o1, o2 ); } - + + /** + * @implNote op name='math.power', type=Function + */ static public final Pow power( final Object o1, final Object o2 ) { return new Pow( o1, o2 ); } + /** + * @implNote op name='math.max', type=Function + */ static public final Max max( final Object o1, final Object o2 ) { return new Max( o1, o2 ); } - + + /** + * @implNote op name='math.max', type=Function + */ static public final Max max( final Object... obs ) { return new Max( obs ); } - + + /** + * @implNote op name='math.maximum', type=Function + */ static public final Max maximum( final Object o1, final Object o2 ) { return new Max( o1, o2 ); } - + + /** + * @implNote op name='math.maximum', type=Function + */ static public final Max maximum( final Object... obs ) { return new Max( obs ); } - + + /** + * @implNote op name='math.min', type=Function + */ static public final Min min( final Object o1, final Object o2 ) { return new Min( o1, o2 ); } - + + /** + * @implNote op name='math.min', type=Function + */ static public final Min min( final Object... obs ) { return new Min( obs ); } - + + /** + * @implNote op name='math.minimum', type=Function + */ static public final Min minimum( final Object o1, final Object o2 ) { return new Min( o1, o2 ); } - + + /** + * @implNote op name='math.minimum', type=Function + */ static public final Min minimum( final Object... obs ) { return new Min( obs ); } - + + /** + * @implNote op name='math.log', type=Function + */ static public final Log log( final Object o1 ) { return new Log( o1 ); } - + + /** + * @implNote op name='math.logarithm', type=Function + */ static public final Log logarithm( final Object o1 ) { return new Log( o1 ); } - + + /** + * @implNote op name='math.exp', type=Function + */ static public final Exp exp( final Object o1 ) { return new Exp( o1 ); } - + + /** + * @implNote op name='math.let', type=Function + */ static public final Let let( final String varName, final Object varValue, final Object body ) { return new Let( varName, varValue, body ); } - + + /** + * @implNote op name='math.let', type=Function + */ static public final Let let( final Object[] pairs, final Object body ) { return new Let( pairs, body ); } - + + /** + * @implNote op name='math.let', type=Function + */ static public final Let let( final Object... obs ) { return new Let( obs ); } - + + /** + * @implNote op name='math.var', type=Function + */ static public final Var var( final String name ) { return new Var( name ); } - + + /** + * @implNote op name='math.eq', type=Function + */ static public final Equal EQ( final Object o1, final Object o2 ) { return new Equal( o1, o2 ); } - + + /** + * @implNote op name='math.equal', type=Function + */ static public final Equal equal( final Object o1, final Object o2 ) { return new Equal( o1, o2 ); } - + + /** + * @implNote op name='math.neq', type=Function + */ static public final NotEqual NEQ( final Object o1, final Object o2 ) { return new NotEqual( o1, o2 ); } - + + /** + * @implNote op name='math.notEqual', type=Function + */ static public final NotEqual notEqual( final Object o1, final Object o2 ) { return new NotEqual( o1, o2 ); } - + + /** + * @implNote op name='math.lt', type=Function + */ static public final LessThan LT( final Object o1, final Object o2 ) { return new LessThan( o1, o2 ); } - + + /** + * @implNote op name='math.lessThan', type=Function + */ static public final LessThan lessThan( final Object o1, final Object o2 ) { return new LessThan( o1, o2 ); } - + + /** + * @implNote op name='math.gt', type=Function + */ static public final GreaterThan GT( final Object o1, final Object o2 ) { return new GreaterThan( o1, o2 ); } - + + /** + * @implNote op name='math.greaterThan', type=Function + */ static public final GreaterThan greaterThan( final Object o1, final Object o2 ) { return new GreaterThan( o1, o2 ); } - + + /** + * @implNote op name='math.if', type=Function + */ static public final If IF( final Object o1, final Object o2, final Object o3 ) { return new If( o1, o2, o3 ); } - + + /** + * @implNote op name='math.then', type=Function + */ static public final Then THEN( final Object o ) { return new Then( o ); } - + + /** + * @implNote op name='math.else', type=Function + */ static public final Else ELSE( final Object o ) { return new Else( o ); } - + + /** + * @implNote op name='math.and', type=Function + */ static public final AndLogical AND( final Object o1, final Object o2 ) { return new AndLogical( o1, o2 ); } - + + /** + * @implNote op name='math.and', type=Function + */ static public final AndLogical AND( final Object... o ) { return new AndLogical( o ); } - + + /** + * @implNote op name='math.or', type=Function + */ static public final OrLogical OR( final Object o1, final Object o2 ) { return new OrLogical( o1, o2 ); } - + + /** + * @implNote op name='math.or', type=Function + */ static public final OrLogical OR( final Object... o ) { return new OrLogical( o ); } - + + /** + * @implNote op name='math.xor', type=Function + */ static public final XorLogical XOR( final Object o1, final Object o2 ) { return new XorLogical( o1, o2 ); } - + + /** + * @implNote op name='math.xor', type=Function + */ static public final XorLogical XOR( final Object... o ) { return new XorLogical( o ); } - + + /** + * @implNote op name='math.not', type=Function + */ static public final NotLogical NOT( final Object o ) { return new NotLogical( o ); } - + + /** + * @implNote op name='math.img', type=Function + */ static public final < T extends RealType< T > > ImgSource< T > img( final RandomAccessibleInterval< T > rai ) { return new ImgSource< T >( rai ); } - /** Synonym of {@code img(RandomAccessibleInterval)}, given that {@code img} is a widely used variable name. */ + /** + * Synonym of {@code img(RandomAccessibleInterval)}, given that {@code img} is a widely used variable name. + * @implNote op name='math.intervalSource', type=Function + */ static public final < T extends RealType< T > > ImgSource< T > intervalSource( final RandomAccessibleInterval< T > rai ) { return new ImgSource< T >( rai ); } - + + /** + * @implNote op name='math.number', type=Function + */ static public final NumberSource number( final Number number ) { return new NumberSource( number ); } - + + /** + * @implNote op name='math.block', type=Function + */ static public final < T extends RealType< T > > BlockReadSource< T > block( final RandomAccessible< T > src, final long[] radius ) { return new BlockReadSource< T >( src, radius ); } - + + /** + * @implNote op name='math.block', type=Function + */ static public final < T extends RealType< T > > BlockReadSource< T > block( final RandomAccessible< T > src, final long radius ) { return new BlockReadSource< T >( src, radius ); } - + + /** + * @implNote op name='math.block', type=Function + */ static public final < T extends RealType< T > > BlockReadSource< T > block( final RandomAccessible< T > src, final long[][] corners ) { return new BlockReadSource< T >( src, corners ); } - + + /** + * @implNote op name='math.offset', type=Function + */ static public final < T extends RealType< T > > RandomAccessibleSource< T > offset( final RandomAccessible< T > src, final long[] offset ) { return new RandomAccessibleSource< T >( src, offset ); } - + + /** + * @implNote op name='math.offset', type=Function + */ static public final < T extends RealType< T > > OffsetSource< T > offset( final IFunction f, final long[] offset ) { return new OffsetSource< T >( f, offset ); } - + + /** + * @implNote op name='math.source', type=Function + */ static public final < T extends RealType< T > > IFunction source( final RandomAccessible< T > src ) { if ( src instanceof RandomAccessibleInterval< ? > ) @@ -444,46 +626,73 @@ static public final < T extends RealType< T > > IFunction source( final RandomAc return new RandomAccessibleSource< T >( src ); } + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final T value, final double radius ) { return new KDTreeSource< T >( positions, value, radius ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final T value, final double radius, final Object outside ) { return new KDTreeSource< T >( positions, value, radius, outside ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final T value, final double radius, final Object outside, final Interval interval ) { return new KDTreeSource< T >( positions, value, radius, outside, interval ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final List< T > values, final double radius ) { return new KDTreeSource< T >( positions, values, radius ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final List< T > values, final double radius, final Object outside ) { return new KDTreeSource< T >( positions, values, radius, outside ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final List< Point > positions, final List< T > values, final double radius, final Object outside, final Interval interval ) { return new KDTreeSource< T >( positions, values, radius, outside, interval ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final KDTree< T > kdtree, final double radius ) { return new KDTreeSource< T >( kdtree, radius ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final KDTree< T > kdtree, final double radius, final Object outside ) { return new KDTreeSource< T >( kdtree, radius, outside ); } - + + /** + * @implNote op name='math.gen', type=Function + */ static public final < T extends RealType< T > > KDTreeSource< T > gen( final KDTree< T > kdtree, final double radius, final Object outside, final Interval interval ) { return new KDTreeSource< T >( kdtree, radius, outside, interval ); diff --git a/src/main/java/net/imglib2/algorithm/morphology/BlackTopHat.java b/src/main/java/net/imglib2/algorithm/morphology/BlackTopHat.java index 2aff5b509..466a43f5a 100644 --- a/src/main/java/net/imglib2/algorithm/morphology/BlackTopHat.java +++ b/src/main/java/net/imglib2/algorithm/morphology/BlackTopHat.java @@ -77,7 +77,8 @@ public class BlackTopHat * allow for performance optimization through structuring element * decomposition. Each shape is processed in order as given in the list. If * the list is empty, the source image is returned. - * + * + * @implNote op name='morphology.blackTopHat', type='org.scijava.function.Function.Arity3' * @param source * the source image. * @param strels @@ -120,7 +121,8 @@ public static < T extends RealType< T >> Img< T > blackTopHat( final Img< T > so * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Type}. - * + * + * @implNote op name='morphology.blackTopHat', type='org.scijava.function.Function.Arity5' * @param source * the source image. * @param strels @@ -159,7 +161,8 @@ public static < T extends Type< T > & Comparable< T > & Sub< T > > Img< T > blac * limited to flat structuring elements, only having {@code on/off} pixels, * contrary to grayscale structuring elements. This allows to simply use a * {@link Shape} as a type for these structuring elements. - * + * + * @implNote op name='morphology.blackTopHat', type='org.scijava.function.Function.Arity3' * @param source * the source image. * @param strel @@ -196,7 +199,8 @@ public static < T extends RealType< T >> Img< T > blackTopHat( final Img< T > so * (against {@link Comparable}) than any of the value found in the source * image, and the converse for the max value. These normally unseen * parameters are required to operate on {@code T extends Comparable & Sub}. - * + * + * @implNote op name='morphology.blackTopHat', type='org.scijava.function.Function.Arity5' * @param source * the source image. * @param strel @@ -268,6 +272,57 @@ public static < T extends RealType< T > > void blackTopHat( final RandomAccessib MorphologyUtils.subAAB2( target, source, numThreads ); } + /** + * Performs the black top-hat (or bottom-hat) morphological operation on a + * {@link RealType} source {@link RandomAccessible}, using a list of + * {@link Shape}s as a structuring element, and writes the result on a + * specified target which must be an {@link IterableInterval}. + * + * See Top-hat + * transform. + *+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target receives a copy of the source. + *
+ * This method differs from + * {@link #blackTopHat(RandomAccessible, IterableInterval, List, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.blackTopHat', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the list of {@link Shape}s that serves as a structuring + * element. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param* The closing operation is simply a dilation followed by an erosion. - * + * + * @implNote op name='morphology.close', type=Function * @param source * the {@link Img} to operate on. * @param strel @@ -174,7 +177,8 @@ public static final < T extends RealType< T >> Img< T > close( final Img< T > so * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Type}. - * + * + * @implNote op name='morphology.close', type=Function * @param source * the {@link Img} to operate on. * @param strel @@ -248,6 +252,57 @@ public static < T extends RealType< T > > void close( final RandomAccessible< T close( source, target, strels, minVal, maxVal, numThreads ); } + /** + * Performs the morphological closing operation on a {@link RealType} source + * {@link RandomAccessible}, using a list of {@link Shape}s as a structuring + * element, and writes the result on a specified target which must be an + * {@link IterableInterval}. See Closing_(morphology). + *
+ * The closing operation is simply a dilation followed by an erosion. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method differs from + * {@link #close(RandomAccessible, IterableInterval, List, int) + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.close', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The closing operation is simply a dilation followed by an erosion. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform closing, it is sufficient that the specified max value is larger + * (against {@link Comparable}) than any of the value found in the source + * image, and conversely for the min value. These normally unseen parameters + * are required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #close(RandomAccessible, IterableInterval, Shape, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.close', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}. + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The closing operation is simply a dilation followed by an erosion. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method differs from + * {@link #close(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.close', type='org.scijava.function.Computer.Arity3' + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The closing operation is simply a dilation followed by an erosion. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform closing, it is sufficient that the specified max value is larger + * (against {@link Comparable}) than any of the value found in the source + * image, and conversely for the min value. These normally unseen parameters + * are required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #close(RandomAccessible, IterableInterval, Shape, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.close', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}. + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method differs from + * {@link #dilate(RandomAccessible, IterableInterval, List, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.dilate', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + */ + public static < T extends RealType< T >> void dilate( final RandomAccessible< T > source, final List< ? extends Shape > strels, final int numThreads, final IterableInterval< T > target ) + { + dilate( source, target, strels, numThreads ); + } + /** * Performs the dilation morphological operation, using a * {@link RandomAccessible} as a source and writing results in an @@ -365,6 +416,68 @@ public static < T extends Type< T > & Comparable< T > > void dilate( final Rando MorphologyUtils.copy2( Views.translate( temp, offset ), target, numThreads ); } + /** + * Performs the dilation morphological operation, using a + * {@link RandomAccessible} as a source and writing results in an + * {@link IterableInterval}. + * + * See + * Dilation_(morphology). + *+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method relies on a specified minimal value to start comparing to + * other pixels in the neighborhood. For this code to properly perform + * dilation, it is sufficient that the specified min value is smaller + * (against {@link Comparable}) than any of the value found in the source + * image. This normally unseen parameter is required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #dilate(RandomAccessible, IterableInterval, List, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.dilate', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}. This is required to + * perform a proper mathematical dilation. Because we operate on + * a generic {@link Type}, it has to be provided manually. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method differs from + * {@link #dilate(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.dilate', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strel + * the structuring element, as a {@link Shape}. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + */ + public static < T extends RealType< T >> void dilate( final RandomAccessible< T > source, final Shape strel, final int numThreads, final IterableInterval< T > target ) + { + dilate( source, target, strel, numThreads ); + } + /** * Performs the dilation morphological operation, using a * {@link RandomAccessible} as a source and writing results in an @@ -567,6 +722,63 @@ public void run() SimpleMultiThreading.startAndJoin( threads ); } + /** + * Performs the dilation morphological operation, using a + * {@link RandomAccessible} as a source and writing results in an + * {@link IterableInterval}. + * + * See + * Dilation_(morphology). + *+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method relies on a specified minimal value to start comparing to + * other pixels in the neighborhood. For this code to properly perform + * dilation, it is sufficient that the specified min value is smaller + * (against {@link Comparable}) than any of the value found in the source + * image. This normally unseen parameter is required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #dilate(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.dilate', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strel + * the structuring element, as a {@link Shape}. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}. This is required to + * perform a proper mathematical dilation. Because we operate on + * a generic {@link Type}, it has to be provided manually. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + * @param* + * @implNote op name='morphology.dilate', type=Inplace1 * @param source * the source image. * @param interval @@ -965,6 +1184,7 @@ public static < T extends RealType< T > > void dilateInPlace( final RandomAccess * image. This normally unseen parameter is required to operate on * {@code T extends Comparable & Type}. * + * @implNote op name='morphology.dilate', type=Inplace1 * @param source * the source image. * @param interval diff --git a/src/main/java/net/imglib2/algorithm/morphology/Erosion.java b/src/main/java/net/imglib2/algorithm/morphology/Erosion.java index a4a2eb4f6..597c20a98 100644 --- a/src/main/java/net/imglib2/algorithm/morphology/Erosion.java +++ b/src/main/java/net/imglib2/algorithm/morphology/Erosion.java @@ -76,6 +76,7 @@ public class Erosion * pixels, contrary to grayscale structuring elements. This allows to simply * use a {@link Shape} as a type for these structuring elements. * + * @implNote op name='morphology.erode', type=Function * @param source * the source image. * @param strels @@ -121,6 +122,7 @@ public static < T extends RealType< T > > Img< T > erode( final Img< T > source, * normally unseen parameter is required to operate on * {@code T extends Comparable & Type}. * + * @implNote op name='morphology.erode', type=Function * @param source * the source image. * @param strels @@ -160,6 +162,7 @@ public static < T extends Type< T > & Comparable< T > > Img< T > erode( final Im * pixels, contrary to grayscale structuring elements. This allows to simply * use a {@link Shape} as a type for these structuring elements. * + * @implNote op name='morphology.erode', type=Function * @param source * the source image. * @param strel @@ -200,6 +203,7 @@ public static < T extends RealType< T >> Img< T > erode( final Img< T > source, * normally unseen parameter is required to operate on * {@code T extends Comparable & Type}. * + * @implNote op name='morphology.erode', type=Function * @param source * the source image. * @param strel @@ -267,6 +271,52 @@ public static < T extends RealType< T >> void erode( final RandomAccessible< T > erode( source, target, strels, maxVal, numThreads ); } + /** + * Performs the erosion morphological operation, on a {@link RealType} + * {@link RandomAccessible} as a source and writing results in an + * {@link IterableInterval}. + * + * See + * Erosion_(morphology). + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method differs from + * {@link #erode(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param target + * the target image. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param numThreads + * the number of threads to use for the calculation. + */ + public static < T extends RealType< T >> void erode( final RandomAccessible< T > source, final List< ? extends Shape > strels, final int numThreads, final IterableInterval< T > target ){ + erode(source, target, strels, numThreads); + } + /** * Performs the erosion morphological operation, using a * {@link RandomAccessible} as a source and writing results in an @@ -365,6 +415,67 @@ public static < T extends Type< T > & Comparable< T > > void erode( final Random MorphologyUtils.copy2( Views.translate( temp, offset ), target, numThreads ); } + /** + * Performs the erosion morphological operation, using a + * {@link RandomAccessible} as a source and writing results in an + * {@link IterableInterval}. + * + * See + * Erosion_(morphology). + *+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method relies on a specified maximal value to start comparing to + * other pixels in the neighborhood. For this code to properly perform + * erosion, it is sufficient that the specified max value is larger (against + * {@link Comparable}) than any of the value found in the source image. This + * normally unseen parameter is required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #erode(RandomAccessible, IterableInterval, List, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}. This is required to + * perform a proper mathematical erosion. Because we operate on a + * generic {@link Type}, it has to be provided manually. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method differs from + * {@link #erode(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strel + * the structuring element, as a {@link Shape}. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + */ + public static < T extends RealType< T >> void erode( final RandomAccessible< T > source, final Shape strel, final int numThreads, final IterableInterval< T > target ){ + erode(source, target, strel, numThreads); + } + /** * Performs the erosion morphological operation, using a * {@link RandomAccessible} as a source and writing results in an @@ -567,6 +719,62 @@ public void run() SimpleMultiThreading.startAndJoin( threads ); } + /** + * Performs the erosion morphological operation, using a + * {@link RandomAccessible} as a source and writing results in an + * {@link IterableInterval}. + * + * See + * Erosion_(morphology). + *+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method relies on a specified maximal value to start comparing to + * other pixels in the neighborhood. For this code to properly perform + * erosion, it is sufficient that the specified max value is larger (against + * {@link Comparable}) than any of the value found in the source image. This + * normally unseen parameter is required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #erode(RandomAccessible, IterableInterval, Shape, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the source {@link RandomAccessible}, must be sufficiently + * padded. + * @param strel + * the structuring element, as a {@link Shape}. + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}. This is required to + * perform a proper mathematical erosion. Because we operate on a + * generic {@link Type}, it has to be provided manually. + * @param numThreads + * the number of threads to use for the calculation. + * @param target + * the target image. + * @param* + * @implNote op name='morphology.erode', type='org.scijava.function.Inplace.Arity4_1' * @param source * the source image. * @param interval @@ -962,6 +1177,7 @@ public static < T extends RealType< T > > void erodeInPlace( final RandomAccessi * normally unseen parameter is required to operate on * {@code T extends Comparable & Type}. * + * @implNote op name='morphology.erode', type='org.scijava.function.Inplace.Arity5_1' * @param source * the source image. * @param interval diff --git a/src/main/java/net/imglib2/algorithm/morphology/Opening.java b/src/main/java/net/imglib2/algorithm/morphology/Opening.java index 79c3a1a68..620612ce5 100644 --- a/src/main/java/net/imglib2/algorithm/morphology/Opening.java +++ b/src/main/java/net/imglib2/algorithm/morphology/Opening.java @@ -70,7 +70,8 @@ public class Opening * allow for performance optimization through structuring element * decomposition. Each shape is processed in order as given in the list. If * the list is empty, the source image is returned. - * + * + * @implNote op name='morphology.open', type='org.scijava.function.Function.Arity3' * @param source * the {@link Img} to operate on. * @param strels @@ -111,7 +112,8 @@ public static final < T extends RealType< T >> Img< T > open( final Img< T > sou * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Type}. - * + * + * @implNote op name='morphology.open', type=Function * @param source * the {@link Img} to operate on. * @param strels @@ -145,7 +147,8 @@ public static final < T extends Type< T > & Comparable< T > > Img< T > open( fin * >Opening_(morphology). *
* The opening operation is simply an erosion followed by a dilation. - * + * + * @implNote op name='morphology.open', type=Function * @param source * the {@link Img} to operate on. * @param strel @@ -181,7 +184,8 @@ public static final < T extends RealType< T >> Img< T > open( final Img< T > sou * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Type}. - * + * + * @implNote op name='morphology.open', type=Function * @param source * the {@link Img} to operate on. * @param strel @@ -255,6 +259,56 @@ public static < T extends RealType< T > > void open( final RandomAccessible< T > open( source, target, strels, minVal, maxVal, numThreads ); } + /** + * Performs the morphological opening operation on a {@link RealType} source + * {@link RandomAccessible}, using a list of {@link Shape}s as a structuring + * element, and writes the result on a specified target which must be an + * {@link IterableInterval}. See Opening_(morphology). + *
+ * The opening operation is simply an erosion followed by a dilation. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method differs from + * {@link #open(RandomAccessible, IterableInterval, List, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The opening operation is simply an erosion followed by a dilation. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target is left untouched. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform opening, it is sufficient that the specified max value is larger + * (against {@link Comparable}) than any of the value found in the source + * image, and conversely for the min value. These normally unseen parameters + * are required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #open(RandomAccessible, IterableInterval, List, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the structuring element, as a list of {@link Shape}s. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}). + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}). + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The opening operation is simply an erosion followed by a dilation. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method differs from + * {@link #open(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.open', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * The opening operation is simply an erosion followed by a dilation. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform opening, it is sufficient that the specified max value is larger + * (against {@link Comparable}) than any of the value found in the source + * image, and conversely for the min value. These normally unseen parameters + * are required to operate on + * {@code T extends Comparable & Type}. + *
+ * This method differs from + * {@link #open(RandomAccessible, IterableInterval, Shape, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.erode', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}). + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}). + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param- * + * + * @implNote op names='topHat, whiteTopHat', type=Function * @param source * the source image. * @param strels @@ -122,7 +123,8 @@ public static < T extends RealType< T >> Img< T > topHat( final Img< T > source, * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Type}. - * + * + * @implNote op names='topHat, whiteTopHat', type=Function * @param source * the source image. * @param strels @@ -161,7 +163,8 @@ public static < T extends Type< T > & Comparable< T > & Sub< T > > Img< T > topH * limited to flat structuring elements, only having {@code on/off} * pixels, contrary to grayscale structuring elements. This allows to simply * use a {@link Shape} as a type for these structuring elements. - * + * + * @implNote op names='topHat, whiteTopHat', type=Function * @param source * the source image. * @param strel @@ -199,7 +202,8 @@ public static < T extends RealType< T >> Img< T > topHat( final Img< T > source, * image, and the converse for the max value. These normally unseen * parameters are required to operate on * {@code T extends Comparable & Sub}. - * + * + * @implNote op names='topHat, whiteTopHat', type=Function * @param source * the source image. * @param strel @@ -271,6 +275,56 @@ public static < T extends RealType< T >> void topHat( final RandomAccessible< T MorphologyUtils.subBAB( source, target, numThreads ); } + /** + * Performs the top-hat (white top-hat) morphological operation on a + * {@link RealType} source {@link RandomAccessible}, using a list of + * {@link Shape}s as a structuring element, and writes the result on a + * specified target which must be an {@link IterableInterval}. + * + * See Top-hat + * transform. + *
+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target receives a copy of the source. + *
+ * This method differs from + * {@link #topHat(RandomAccessible, IterableInterval, List, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.topHat, morphology.whiteTopHat', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the list of {@link Shape}s that serves as a structuring + * element. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * The structuring element is specified through a list of {@link Shape}s, to + * allow for performance optimization through structuring element + * decomposition. Each shape is processed in order as given in the list. If + * the list is empty, the target receives a copy of the source. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform, it is sufficient that the specified max value is larger (against + * {@link Comparable}) than any of the value found in the source image, and + * conversely for the min value. These normally unseen parameters are + * required to operate on + * {@code T extends Comparable & Sub}. + *
+ * This method differs from + * {@link #topHat(RandomAccessible, IterableInterval, List, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.topHat, morphology.whiteTopHat', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strels + * the list of {@link Shape}s that serves as a structuring + * element. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}). + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}). + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method differs from + * {@link #topHat(RandomAccessible, IterableInterval, Shape, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.topHat, morphology.whiteTopHat', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * Careful: Target must point to a different structure than source. + * In place operation will not work but will not generate an error. + *
+ * It is the caller responsibility to ensure that the source is sufficiently + * padded to properly cover the target range plus the shape size. See + * e.g. {@link Views#extendValue(RandomAccessibleInterval, Type)} + *
+ * It is limited to flat structuring elements, only having + * {@code on/off} pixels, contrary to grayscale structuring elements. + * This allows to simply use a {@link Shape} as a type for these structuring + * elements. + *
+ * This method relies on specified minimal and maximal values to start + * comparing to other pixels in the neighborhood. For this code to properly + * perform, it is sufficient that the specified max value is larger (against + * {@link Comparable}) than any of the value found in the source image, and + * conversely for the min value. These normally unseen parameters are + * required to operate on + * {@code T extends Comparable & Sub}. + *
+ * This method differs from + * {@link #topHat(RandomAccessible, IterableInterval, Shape, Type, Type, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='morphology.topHat, morphology.whiteTopHat', type=Computer + * @param source + * the {@link RandomAccessible} to operate on. + * @param strel + * the {@link Shape} that serves as a structuring element. + * @param minVal + * a T containing set to a value smaller than any of the values + * in the source (against {@link Comparable}). + * @param maxVal + * a T containing set to a value larger than any of the values in + * the source (against {@link Comparable}). + * @param numThreads + * the number of threads to use for calculation. + * @param target + * the {@link IterableInterval} to write the results on. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, DISTANCE_TYPE, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.distanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Intermediate and final results of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, DISTANCE_TYPE, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.distanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, DISTANCE_TYPE, ExecutorService, int, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, Distance)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @param source + * Input function on which distance transform should be computed. + * @param d + * {@link Distance} between two points. + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, Distance, ExecutorService, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.distanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param d + * {@link Distance} between two points. + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, Distance)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.distanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param d + * {@link Distance} between two points. + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #transform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, Distance, ExecutorService, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param d + * {@link Distance} between two points. + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param target + * Final result of distance transform. + * @param+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, DISTANCE_TYPE, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Intermediate and final results of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + */ + public static < B extends BooleanType< B >, U extends RealType< U > > void binaryTransform( + final RandomAccessible< B > source, + final DISTANCE_TYPE distanceType, + final double[] weights, + final RandomAccessibleInterval< U > target ) + { + binaryTransform( source, target, distanceType, weights ); + } + /** * Create binary distance transform on {@code source} using squared * Euclidian (L2) or L1 distance. Intermediate results will be stored in @@ -700,6 +1100,57 @@ public static < B extends BooleanType< B >, U extends RealType< U > > void binar binaryTransform( source, target, target, distanceType, es, nTasks, weights ); } + /** + * Create binary distance transform on {@code source} using squared + * Euclidian (L2) or L1 distance. Intermediate results will be stored in + * {@code target} ({@link DoubleType} recommended). The distance can be + * weighted (individually for each dimension, if desired) against the image + * values via the weights parameter. + *+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, DISTANCE_TYPE, ExecutorService, int, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Intermediate and final results of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @throws InterruptedException + * if interrupted while waiting, in which case unfinished tasks + * are cancelled (distance transform may be computed only + * partially) + * @throws ExecutionException + * if the computation threw an exception (distance transform may + * be computed only partially) + */ + public static < B extends BooleanType< B >, U extends RealType< U > > void binaryTransform( + final RandomAccessible< B > source, + final DISTANCE_TYPE distanceType, + final ExecutorService es, + final int nTasks, + final double[] weights, + final RandomAccessibleInterval< U > target ) throws InterruptedException, ExecutionException + { + binaryTransform( source, target, distanceType, es, nTasks, weights ); + } + /** * Create binary distance transform on {@code source} using squared * Euclidian (L2) or L1 distance. Intermediate results will be stored in @@ -742,6 +1193,50 @@ public static < B extends BooleanType< B >, U extends RealType< U >, V extends R transform( converted, tmp, target, distanceType, weights ); } + /** + * Create binary distance transform on {@code source} using squared + * Euclidian (L2) or L1 distance. Intermediate results will be stored in + * {@code tmp} ({@link DoubleType} recommended). The output will be written + * into {@code target}. The distance can be weighted (individually for each + * dimension, if desired) against the image values via the weights + * parameter. + *+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, DISTANCE_TYPE, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Final result of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @param+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, DISTANCE_TYPE, ExecutorService, int, double...)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param distanceType + * Defines distance to be used: squared Euclidian or L1 + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param weights + * Individual weights for each dimension, balancing image values + * and distance (when using squared Euclidian distance, weights + * should be squared, too). + * @param target + * Final result of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @param+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, Distance) + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param d + * {@link Distance} between two points. + * @param target + * Final result of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + */ + public static < B extends BooleanType< B >, U extends RealType< U > > void binaryTransform( + final RandomAccessible< B > source, + final Distance d, + final RandomAccessibleInterval< U > target ) + { + binaryTransform( source, target, d ); + } + /** * Create binary distance transform on {@code source} using arbitrary * {@link Distance} d. Intermediate and final results will be stored in @@ -889,6 +1473,50 @@ public static < B extends BooleanType< B >, U extends RealType< U > > void binar binaryTransform( source, target, target, d, es, nTasks ); } + /** + * Create binary distance transform on {@code source} using arbitrary + * {@link Distance} d. Intermediate and final results will be stored in + * {@code target} ({@link DoubleType} recommended). + *+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, Distance, ExecutorService, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param target + * Final result of distance transform. + * @param d + * {@link Distance} between two points. + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @throws InterruptedException + * if interrupted while waiting, in which case unfinished tasks + * are cancelled (distance transform may be computed only + * partially) + * @throws ExecutionException + * if the computation threw an exception (distance transform may + * be computed only partially) + */ + public static < B extends BooleanType< B >, U extends RealType< U > > void binaryTransform( + final RandomAccessible< B > source, + final Distance d, + final ExecutorService es, + final int nTasks, + final RandomAccessibleInterval< U > target) throws InterruptedException, ExecutionException + { + binaryTransform( source, target, d, es, nTasks ); + } + /** * Create binary distance transform on {@code source} using arbitrary * {@link Distance} d. Intermediate results will be stored in {@code tmp} @@ -923,6 +1551,43 @@ public static < B extends BooleanType< B >, U extends RealType< U >, V extends R transform( converted, tmp, target, d ); } + /** + * Create binary distance transform on {@code source} using arbitrary + * {@link Distance} d. Intermediate results will be stored in {@code tmp} + * ({@link DoubleType} recommended). The output will be written into + * {@code target}. + *+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, Distance)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param target + * Final result of distance transform. + * @param d + * {@link Distance} between two points. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @param+ * This method differs from + * {@link #binaryTransform(RandomAccessible, RandomAccessibleInterval, RandomAccessibleInterval, Distance, ExecutorService, int)} + * only in that its parameter order is tailored to an Op. The output comes + * last, and the primary input (the input image) comes first. + *
+ * + * @implNote op name='image.binaryDistanceTransform', type=Computer + * @param source + * Input function on which distance transform should be computed. + * @param tmp + * Storage for intermediate results. + * @param d + * {@link Distance} between two points. + * @param es + * {@link ExecutorService} for parallel execution. + * @param nTasks + * Number of tasks/parallelism + * @param target + * Final result of distance transform. + * @param + * {@link BooleanType} binary mask input + * @param + * {@link RealType} intermediate results + * @param