pub struct SegmentingWatershed<T = ()> { /* private fields */ }
Expand description
Implementation of the segmenting watershed algorithm.
See crate-level documentation for a general introduction to the algorithm.
The segmenting watershed algorithm forms lakes from pre-defined local minima by raising an imaginary water level. Once the water level increases past the height of a minimum, it starts filling neighbouring pixels that are also below the water level. These poodles grow larger as the water level rises.
When two lakes originating from different local minima meet, an infinitely high wall separating the two is created. This is wall-building is what makes this version of the watershed algorithm an image segmentation algorithm.
§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.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 SegmentingWatershed<T>
impl<T> Watershed<T> for SegmentingWatershed<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 SegmentingWatershed<T>
impl<T> WatershedUtils for SegmentingWatershed<T>
Source§fn pre_processor<T, D>(&self, img: ArrayView<'_, T, D>) -> Array<u8, D>
fn pre_processor<T, D>(&self, img: ArrayView<'_, T, D>) -> Array<u8, D>
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>
fn pre_processor_with_max<const MAX: u8, T, D>( &self, img: ArrayView<'_, T, D>, ) -> Array<u8, D>
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 find_local_minima(&self, img: ArrayView2<'_, u8>) -> Vec<(usize, usize)>
fn find_local_minima(&self, img: ArrayView2<'_, u8>) -> Vec<(usize, usize)>
Auto Trait Implementations§
impl<T> Freeze for SegmentingWatershed<T>
impl<T> RefUnwindSafe for SegmentingWatershed<T>
impl<T> Send for SegmentingWatershed<T>
impl<T> Sync for SegmentingWatershed<T>
impl<T> Unpin for SegmentingWatershed<T>
impl<T> UnwindSafe for SegmentingWatershed<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more