Struct rustronomy_watershed::MergingWatershed
source · pub struct MergingWatershed<T = ()> { /* private fields */ }
Expand description
Implementation of the merging watershed algorithm.
See crate-level documentation for a general introduction to the algorithm.
The merging watershed transform is a slight variation on the segmenting
algorithm (see docs of the SegmentingWatershed
struct). Instead of creating
a wall whenever two lakes meet, the merging watershed transform merges the
two lakes.
On a statistics level, the main difference between the merging and segmenting watershed transforms is that the number of distinct lakes in the merging watershed transform depends on the features in the image rather than the number of (somewhat arbitrarily chosen) lake-seeds. Therefore, one can do statistics with the number of lakes. In addition, the output of the merging transform does not depend strongly on the precise way the minima were chosen.
Memory usage
The watershed transform creates an Array2<usize>
of the same size as the
input array, which takes up a considerable amount of memory. In addition, it
allocates space for a colour-map (Vec<usize>
with a length equal to the
number of seeds) and some other intermediate, smaller vec’s. One can count on
the memory usage being about ~2.5x the size of the input array.
Memory usage of transform_history
The transform_history
method makes a copy of the Array2<usize>
image used
during the watershed transform to keep track of the intermediate images. As
such, it allocates a new Array2<usize>
for each water level, which increases
memory usage by a factor equal to the maximum water level as configured by
the TransformBuilder
.
Output
The three methods of the Watershed
trait each return a different set of
parameters based on the watershed transform of the input image:
transform
simply returns the watershed transform of the image. This is not very interesting in the case of the merging watershed transform, since its output is just an image with all pixels having the same colour.transform_to_list
returns a list of the areas of all the lakes at each water level. Its return type isVec<(u8, Vec<usize>)>
, where theu8
equals the water level and theVec<usize>
is the list of areas of all the lakes at each water level. TheVec<usize>
is the same length for each water level, but may contain zero-sided lakes. The water levels are returned in order.transform_history
returns a list of intermediate images of the watershed transform at every water level. Its return type isVec<(u8, ndarray::Array2<usize>)
, where theu8
holds the water level that eachArray2
snapshot was taken at. The water levels are returned in order.
Artifacts and peculiarities
Due to some implementation details, the 1px-wide edges of the input array are not accessible to the watershed transform. They will thus remain unfilled for the entire duration of the transform.
A workaround can be enabled by calling enable_edge_correction
on the
TransformBuilder
. Enabling this setting copies the input image into a
new array, 1px wider on all sides. This padded array is then used as the
actual input to the watershed transform. The final output of the transform is
a copy of this intermediate array with the padding removed. The padding also
does not show up in the output of intermediate plots.
Trait Implementations§
source§impl<T> Watershed<T> for MergingWatershed<T>
impl<T> Watershed<T> for MergingWatershed<T>
source§fn transform_with_hook(
&self,
input: ArrayView2<'_, u8>,
seeds: &[(usize, usize)]
) -> Vec<T>
fn transform_with_hook( &self, input: ArrayView2<'_, u8>, seeds: &[(usize, usize)] ) -> Vec<T>
TransformBuilder
(if there is one) each time the water level is raised.
The results from running the hook each time are collected into a vec and
returned by this function.source§fn transform(
&self,
input: ArrayView2<'_, u8>,
_seeds: &[(usize, usize)]
) -> Array2<usize>
fn transform( &self, input: ArrayView2<'_, u8>, _seeds: &[(usize, usize)] ) -> Array2<usize>
source§fn transform_history(
&self,
input: ArrayView2<'_, u8>,
seeds: &[(usize, usize)]
) -> Vec<(u8, Array2<usize>)>
fn transform_history( &self, input: ArrayView2<'_, u8>, seeds: &[(usize, usize)] ) -> Vec<(u8, Array2<usize>)>
source§fn transform_to_list(
&self,
input: ArrayView2<'_, u8>,
seeds: &[(usize, usize)]
) -> Vec<(u8, Vec<usize>)>
fn transform_to_list( &self, input: ArrayView2<'_, u8>, seeds: &[(usize, usize)] ) -> Vec<(u8, Vec<usize>)>
MergingWatershed
)source§impl<T> WatershedUtils for MergingWatershed<T>
impl<T> WatershedUtils for MergingWatershed<T>
source§fn pre_processor<T, D>(&self, img: ArrayView<'_, T, D>) -> Array<u8, D>where
T: Num + Copy + ToPrimitive + PartialOrd,
D: Dimension,
fn pre_processor<T, D>(&self, img: ArrayView<'_, T, D>) -> Array<u8, D>where T: Num + Copy + ToPrimitive + PartialOrd, D: Dimension,
pre_processor
function can convert an array of any numeric data-type
T
into an array of u8
. It converts special float values (if T
is a
float type) to u8
values that implementations of the watershed transform
in this crate know how to handle. Read moresource§fn pre_processor_with_max<const MAX: u8, T, D>(
&self,
img: ArrayView<'_, T, D>
) -> Array<u8, D>where
T: Num + Copy + ToPrimitive + PartialOrd,
D: Dimension,
fn pre_processor_with_max<const MAX: u8, T, D>( &self, img: ArrayView<'_, T, D> ) -> Array<u8, D>where T: Num + Copy + ToPrimitive + PartialOrd, D: Dimension,
T
into an array of u8
. It converts special float values (if T
is a
float type) to u8
values that implementations of the watershed transform
in this crate know how to handle. Read more