//! Functions for computing [morphological operators].
//!
//! [morphological operators]: http://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm
use crate;
use GrayImage;
use u8;
/// Sets all pixels within distance `k` of a foreground pixel to white.
///
/// A pixel is treated as belonging to the foreground if it has non-zero intensity.
///
/// # Examples
/// ```
/// # extern crate image;
/// # #[macro_use]
/// # extern crate imageproc;
/// # fn main() {
/// use image::GrayImage;
/// use imageproc::morphology::dilate;
/// use imageproc::distance_transform::Norm;
///
/// let image = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 255, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// // L1 norm
/// let l1_dilated = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 0, 255, 0, 0;
/// 0, 255, 255, 255, 0;
/// 0, 0, 255, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(dilate(&image, Norm::L1, 1), l1_dilated);
///
/// // LInf norm
/// let linf_dilated = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 255, 255, 255, 0;
/// 0, 255, 255, 255, 0;
/// 0, 255, 255, 255, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(dilate(&image, Norm::LInf, 1), linf_dilated);
/// # }
/// ```
/// Sets all pixels within distance `k` of a foreground pixel to white.
///
/// A pixel is treated as belonging to the foreground if it has non-zero intensity.
///
/// See the [`dilate`](fn.dilate.html) documentation for examples.
/// Sets all pixels within distance `k` of a background pixel to black.
///
/// A pixel is treated as belonging to the foreground if it has non-zero intensity.
///
/// # Examples
/// ```
/// # extern crate image;
/// # #[macro_use]
/// # extern crate imageproc;
/// # fn main() {
/// use image::GrayImage;
/// use imageproc::morphology::erode;
/// use imageproc::distance_transform::Norm;
///
/// let image = gray_image!(
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 255, 255, 255, 0, 255, 255, 255, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 255, 255, 255, 255, 255, 255, 255, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0
/// );
///
/// // L1 norm - the outermost foreground pixels are eroded,
/// // as well as those horizontally and vertically adjacent
/// // to the centre background pixel.
/// let l1_eroded = gray_image!(
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 255, 255, 255, 255, 255, 0, 0;
/// 0, 0, 255, 255, 0, 255, 255, 0, 0;
/// 0, 0, 255, 0, 0, 0, 255, 0, 0;
/// 0, 0, 255, 255, 0, 255, 255, 0, 0;
/// 0, 0, 255, 255, 255, 255, 255, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(erode(&image, Norm::L1, 1), l1_eroded);
///
/// // LInf norm - all pixels eroded using the L1 norm are eroded,
/// // as well as the pixels diagonally adjacent to the centre pixel.
/// let linf_eroded = gray_image!(
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 255, 255, 255, 255, 255, 0, 0;
/// 0, 0, 255, 0, 0, 0, 255, 0, 0;
/// 0, 0, 255, 0, 0, 0, 255, 0, 0;
/// 0, 0, 255, 0, 0, 0, 255, 0, 0;
/// 0, 0, 255, 255, 255, 255, 255, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(erode(&image, Norm::LInf, 1), linf_eroded);
/// # }
/// ```
/// Sets all pixels within distance `k` of a background pixel to black.
///
/// A pixel is treated as belonging to the foreground if it has non-zero intensity.
///
/// See the [`erode`](fn.erode.html) documentation for examples.
/// Erosion followed by dilation.
///
/// See the [`erode`](fn.erode.html) and [`dilate`](fn.dilate.html)
/// documentation for definitions of dilation and erosion.
///
/// # Examples
/// ```
/// # extern crate image;
/// # #[macro_use]
/// # extern crate imageproc;
/// # fn main() {
/// use imageproc::morphology::open;
/// use imageproc::distance_transform::Norm;
///
/// // Isolated regions of foreground pixels are removed.
/// let cross = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 0, 255, 0, 0;
/// 0, 255, 255, 255, 0;
/// 0, 0, 255, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// let opened_cross = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(
/// open(&cross, Norm::LInf, 1),
/// opened_cross
/// );
///
/// // Large blocks survive unchanged.
/// let blob = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 255, 255, 255, 0;
/// 0, 255, 255, 255, 0;
/// 0, 255, 255, 255, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(
/// open(&blob, Norm::LInf, 1),
/// blob
/// );
/// # }
/// ```
/// Erosion followed by dilation.
///
/// See the [`open`](fn.open.html) documentation for examples,
/// and the [`erode`](fn.erode.html) and [`dilate`](fn.dilate.html)
/// documentation for definitions of dilation and erosion.
/// Dilation followed by erosion.
///
/// See the [`erode`](fn.erode.html) and [`dilate`](fn.dilate.html)
/// documentation for definitions of dilation and erosion.
///
/// # Examples
/// ```
/// # extern crate image;
/// # #[macro_use]
/// # extern crate imageproc;
/// # fn main() {
/// use imageproc::morphology::close;
/// use imageproc::distance_transform::Norm;
///
/// // Small holes are closed - hence the name.
/// let small_hole = gray_image!(
/// 255, 255, 255, 255;
/// 255, 0, 0, 255;
/// 255, 0, 0, 255;
/// 255, 255, 255, 255
/// );
///
/// let closed_small_hole = gray_image!(
/// 255, 255, 255, 255;
/// 255, 255, 255, 255;
/// 255, 255, 255, 255;
/// 255, 255, 255, 255
/// );
///
/// assert_pixels_eq!(
/// close(&small_hole, Norm::LInf, 1),
/// closed_small_hole
/// );
///
/// // Large holes survive unchanged.
/// let large_hole = gray_image!(
/// 255, 255, 255, 255, 255;
/// 255, 0, 0, 0, 255;
/// 255, 0, 0, 0, 255;
/// 255, 0, 0, 0, 255;
/// 255, 255, 255, 255, 255
/// );
///
/// assert_pixels_eq!(
/// close(&large_hole, Norm::LInf, 1),
/// large_hole
/// );
///
/// // A dot gains a layer of foreground pixels
/// // when dilated and loses them again when eroded,
/// // resulting in no change.
/// let dot = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 255, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(
/// close(&dot, Norm::LInf, 1),
/// dot
/// );
///
/// // A dot near the boundary gains pixels in the top-left
/// // of the image which are not within distance 1 of any
/// // background pixels, so are not removed by erosion.
/// let dot_near_boundary = gray_image!(
/// 0, 0, 0, 0, 0;
/// 0, 255, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// let closed_dot_near_boundary = gray_image!(
/// 255, 255, 0, 0, 0;
/// 255, 255, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0;
/// 0, 0, 0, 0, 0
/// );
///
/// assert_pixels_eq!(
/// close(&dot_near_boundary, Norm::LInf, 1),
/// closed_dot_near_boundary
/// );
/// # }
/// ```
/// Dilation followed by erosion.
///
/// See the [`close`](fn.close.html) documentation for examples,
/// and the [`erode`](fn.erode.html) and [`dilate`](fn.dilate.html)
/// documentation for definitions of dilation and erosion.