use crate::DType;
use crate::signal::traits::nd_filters::{BoundaryMode, NdFilterAlgorithms};
use numr::error::Result;
use numr::ops::ScalarOps;
use numr::runtime::{Runtime, RuntimeClient};
use numr::tensor::Tensor;
pub fn grey_erosion_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + RuntimeClient<R>,
{
client.minimum_filter(input, size, BoundaryMode::Nearest)
}
pub fn grey_dilation_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + RuntimeClient<R>,
{
client.maximum_filter(input, size, BoundaryMode::Nearest)
}
pub fn grey_opening_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + RuntimeClient<R>,
{
let eroded = grey_erosion_impl(client, input, size)?;
grey_dilation_impl(client, &eroded, size)
}
pub fn grey_closing_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + RuntimeClient<R>,
{
let dilated = grey_dilation_impl(client, input, size)?;
grey_erosion_impl(client, &dilated, size)
}
pub fn morphological_gradient_impl<R, C>(
client: &C,
input: &Tensor<R>,
size: &[usize],
) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + ScalarOps<R> + RuntimeClient<R>,
{
let dilated = grey_dilation_impl(client, input, size)?;
let eroded = grey_erosion_impl(client, input, size)?;
client.sub(&dilated, &eroded)
}
pub fn white_tophat_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + ScalarOps<R> + RuntimeClient<R>,
{
let opened = grey_opening_impl(client, input, size)?;
client.sub(input, &opened)
}
pub fn black_tophat_impl<R, C>(client: &C, input: &Tensor<R>, size: &[usize]) -> Result<Tensor<R>>
where
R: Runtime<DType = DType>,
C: NdFilterAlgorithms<R> + ScalarOps<R> + RuntimeClient<R>,
{
let closed = grey_closing_impl(client, input, size)?;
client.sub(&closed, input)
}