Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remaining greyscale morphology operations to cupyx.scipy.ndimage #3946

Merged
merged 4 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cupyx/scipy/ndimage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@
from cupyx.scipy.ndimage.morphology import grey_dilation # NOQA
from cupyx.scipy.ndimage.morphology import grey_closing # NOQA
from cupyx.scipy.ndimage.morphology import grey_opening # NOQA
from cupyx.scipy.ndimage.morphology import morphological_gradient # NOQA
from cupyx.scipy.ndimage.morphology import morphological_laplace # NOQA
from cupyx.scipy.ndimage.morphology import white_tophat # NOQA
from cupyx.scipy.ndimage.morphology import black_tophat # NOQA
241 changes: 239 additions & 2 deletions cupyx/scipy/ndimage/morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def grey_closing(input, size=None, footprint=None, structure=None,
.. seealso:: :func:`scipy.ndimage.grey_closing`
"""
if (size is not None) and (footprint is not None):
warnings.warn("ignoring size because footprint is set", UserWarning,
warnings.warn('ignoring size because footprint is set', UserWarning,
stacklevel=2)
tmp = grey_dilation(input, size, footprint, structure, None, mode, cval,
origin)
Expand Down Expand Up @@ -182,9 +182,246 @@ def grey_opening(input, size=None, footprint=None, structure=None,
.. seealso:: :func:`scipy.ndimage.grey_opening`
"""
if (size is not None) and (footprint is not None):
warnings.warn("ignoring size because footprint is set", UserWarning,
warnings.warn('ignoring size because footprint is set', UserWarning,
stacklevel=2)
tmp = grey_erosion(input, size, footprint, structure, None, mode, cval,
origin)
return grey_dilation(tmp, size, footprint, structure, output, mode, cval,
origin)


def morphological_gradient(
input,
size=None,
footprint=None,
structure=None,
output=None,
mode='reflect',
cval=0.0,
origin=0,
):
"""
Multidimensional morphological gradient.

The morphological gradient is calculated as the difference between a
dilation and an erosion of the input with a given structuring element.

Args:
input (cupy.ndarray): The input array.
size (tuple of ints): Shape of a flat and full structuring element used
for the morphological gradient. Optional if ``footprint`` or
``structure`` is provided.
footprint (array of ints): Positions of non-infinite elements of a flat
structuring element used for morphological gradient. Non-zero
values give the set of neighbors of the center over which opening
is chosen.
structure (array of ints): Structuring element used for the
morphological gradient. ``structure`` may be a non-flat
structuring element.
output (cupy.ndarray, dtype or None): The array in which to place the
output.
mode (str): The array borders are handled according to the given mode
(``'reflect'``, ``'constant'``, ``'nearest'``, ``'mirror'``,
``'wrap'``). Default is ``'reflect'``.
cval (scalar): Value to fill past edges of input if mode is
``constant``. Default is ``0.0``.
origin (scalar or tuple of scalar): The origin parameter controls the
placement of the filter, relative to the center of the current
element of the input. Default of 0 is equivalent to
``(0,)*input.ndim``.

Returns:
cupy.ndarray: The morphological gradient of the input.

.. seealso:: :func:`scipy.ndimage.morphological_gradient`
"""
tmp = grey_dilation(
input, size, footprint, structure, None, mode, cval, origin
)
if isinstance(output, cupy.ndarray):
grey_erosion(
input, size, footprint, structure, output, mode, cval, origin
)
return cupy.subtract(tmp, output, output)
else:
return tmp - grey_erosion(
input, size, footprint, structure, None, mode, cval, origin
)


def morphological_laplace(
input,
size=None,
footprint=None,
structure=None,
output=None,
mode='reflect',
cval=0.0,
origin=0,
):
"""
Multidimensional morphological laplace.

Args:
input (cupy.ndarray): The input array.
size (tuple of ints): Shape of a flat and full structuring element used
for the morphological laplace. Optional if ``footprint`` or
``structure`` is provided.
footprint (array of ints): Positions of non-infinite elements of a flat
structuring element used for morphological laplace. Non-zero
values give the set of neighbors of the center over which opening
is chosen.
structure (array of ints): Structuring element used for the
morphological laplace. ``structure`` may be a non-flat
structuring element.
output (cupy.ndarray, dtype or None): The array in which to place the
output.
mode (str): The array borders are handled according to the given mode
(``'reflect'``, ``'constant'``, ``'nearest'``, ``'mirror'``,
``'wrap'``). Default is ``'reflect'``.
cval (scalar): Value to fill past edges of input if mode is
``constant``. Default is ``0.0``.
origin (scalar or tuple of scalar): The origin parameter controls the
placement of the filter, relative to the center of the current
element of the input. Default of 0 is equivalent to
``(0,)*input.ndim``.

Returns:
cupy.ndarray: The morphological laplace of the input.

.. seealso:: :func:`scipy.ndimage.morphological_laplace`
"""
tmp1 = grey_dilation(
input, size, footprint, structure, None, mode, cval, origin
)
if isinstance(output, cupy.ndarray):
grey_erosion(
input, size, footprint, structure, output, mode, cval, origin
)
cupy.add(tmp1, output, output)
cupy.subtract(output, input, output)
return cupy.subtract(output, input, output)
else:
tmp2 = grey_erosion(
input, size, footprint, structure, None, mode, cval, origin
)
cupy.add(tmp1, tmp2, tmp2)
cupy.subtract(tmp2, input, tmp2)
cupy.subtract(tmp2, input, tmp2)
return tmp2


def white_tophat(
input,
size=None,
footprint=None,
structure=None,
output=None,
mode='reflect',
cval=0.0,
origin=0,
):
"""
Multidimensional white tophat filter.

Args:
input (cupy.ndarray): The input array.
size (tuple of ints): Shape of a flat and full structuring element used
for the white tophat. Optional if ``footprint`` or ``structure`` is
provided.
footprint (array of ints): Positions of non-infinite elements of a flat
structuring element used for the white tophat. Non-zero values
give the set of neighbors of the center over which opening is
chosen.
structure (array of ints): Structuring element used for the white
tophat. ``structure`` may be a non-flat structuring element.
output (cupy.ndarray, dtype or None): The array in which to place the
output.
mode (str): The array borders are handled according to the given mode
(``'reflect'``, ``'constant'``, ``'nearest'``, ``'mirror'``,
``'wrap'``). Default is ``'reflect'``.
cval (scalar): Value to fill past edges of input if mode is
``constant``. Default is ``0.0``.
origin (scalar or tuple of scalar): The origin parameter controls the
placement of the filter, relative to the center of the current
element of the input. Default of 0 is equivalent to
``(0,)*input.ndim``.

Returns:
cupy.ndarray: Result of the filter of ``input`` with ``structure``.

.. seealso:: :func:`scipy.ndimage.white_tophat`
"""
if (size is not None) and (footprint is not None):
warnings.warn(
'ignoring size because footprint is set', UserWarning, stacklevel=2
)
tmp = grey_erosion(
input, size, footprint, structure, None, mode, cval, origin
)
tmp = grey_dilation(
tmp, size, footprint, structure, output, mode, cval, origin
)
if input.dtype == numpy.bool_ and tmp.dtype == numpy.bool_:
cupy.bitwise_xor(input, tmp, out=tmp)
else:
cupy.subtract(input, tmp, out=tmp)
return tmp


def black_tophat(
input,
size=None,
footprint=None,
structure=None,
output=None,
mode='reflect',
cval=0.0,
origin=0,
):
"""
Multidimensional black tophat filter.

Args:
input (cupy.ndarray): The input array.
size (tuple of ints): Shape of a flat and full structuring element used
for the black tophat. Optional if ``footprint`` or ``structure`` is
provided.
footprint (array of ints): Positions of non-infinite elements of a flat
structuring element used for the black tophat. Non-zero values
give the set of neighbors of the center over which opening is
chosen.
structure (array of ints): Structuring element used for the black
tophat. ``structure`` may be a non-flat structuring element.
output (cupy.ndarray, dtype or None): The array in which to place the
output.
mode (str): The array borders are handled according to the given mode
(``'reflect'``, ``'constant'``, ``'nearest'``, ``'mirror'``,
``'wrap'``). Default is ``'reflect'``.
cval (scalar): Value to fill past edges of input if mode is
``constant``. Default is ``0.0``.
origin (scalar or tuple of scalar): The origin parameter controls the
placement of the filter, relative to the center of the current
element of the input. Default of 0 is equivalent to
``(0,)*input.ndim``.

Returns:
cupy.ndarry : Result of the filter of ``input`` with ``structure``.

.. seealso:: :func:`scipy.ndimage.black_tophat`
"""
if (size is not None) and (footprint is not None):
warnings.warn(
'ignoring size because footprint is set', UserWarning, stacklevel=2
)
tmp = grey_dilation(
input, size, footprint, structure, None, mode, cval, origin
)
tmp = grey_erosion(
tmp, size, footprint, structure, output, mode, cval, origin
)
if input.dtype == numpy.bool_ and tmp.dtype == numpy.bool_:
cupy.bitwise_xor(tmp, input, out=tmp)
else:
cupy.subtract(tmp, input, out=tmp)
return tmp
Loading