Source code for pygorpho.flat

"""Mathematical morphology with flat (binary) structuring elements."""

import numpy as np
from . import _thin
from . import constants


[docs]def morph(vol, strel, op, block_size=[256, 256, 256]): """ Morphological operation with flat structuring element. Parameters ---------- vol Volume to apply operation to. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. op Operation to perform. Must be either ``DILATE``, ``ERODE``, ``OPEN``, ``CLOSE``, ``TOPHAT``, ``CLOSE`` from ``constants``. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of the operation. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple dilation with an 11 x 11 x 11 box structuring element >>> vol = np.zeros((100, 100, 100)) >>> vol[50, 50, 50] = 1 >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.morph(vol, strel, pg.DILATE) """ assert(op in [constants.DILATE, constants.ERODE, constants.OPEN, constants.CLOSE, constants.TOPHAT, constants.BOTHAT]) # Recast inputs to correct datatype vol = np.asarray(vol) old_shape = vol.shape vol = np.atleast_3d(vol) strel = np.atleast_3d(np.asarray(strel, dtype=np.bool_)) # Prepare output volume vol_size = vol.shape res = np.empty_like(vol) ret = _thin.flat_morph_op_impl( res.ctypes.data, vol.ctypes.data, strel, vol_size[2], vol_size[1], vol_size[0], strel.shape[2], strel.shape[1], strel.shape[0], vol.dtype.num, op, block_size[2], block_size[1], block_size[0]) _thin.raise_on_error(ret) return np.resize(res, old_shape)
[docs]def dilate(vol, strel, block_size=[256, 256, 256]): """ Dilation with flat structuring element. Parameters ---------- vol Volume to dilate/erode. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of dilation. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple dilation with an 11 x 11 x 11 box structuring element >>> vol = np.zeros((100, 100, 100)) >>> vol[50, 50, 50] = 1 >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.dilate(vol, strel) """ return morph(vol, strel, constants.DILATE, block_size)
[docs]def erode(vol, strel, block_size=[256, 256, 256]): """ Erosion with flat structuring element. Parameters ---------- vol Volume to dilate/erode. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of erosion. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple erosion with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[50, 50, 50] = 0 >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.erode(vol, strel) """ return morph(vol, strel, constants.ERODE, block_size)
[docs]def open(vol, strel, block_size=[256, 256, 256]): """ Opening with flat structuring element. Parameters ---------- vol Volume to open. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of opening. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple opening with an 11 x 11 x 11 box structuring element >>> vol = np.zeros((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 1 # Small box >>> vol[60:80,60:80,40:60] = 1 # Big box >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.open(vol, strel) """ return morph(vol, strel, constants.OPEN, block_size)
[docs]def close(vol, strel, block_size=[256, 256, 256]): """ Closing with flat structuring element. Parameters ---------- vol Volume to close. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of closing. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple closing with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 0 # Small box >>> vol[60:80,60:80,40:60] = 0 # Big box >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.close(vol, strel) """ return morph(vol, strel, constants.CLOSE, block_size)
[docs]def tophat(vol, strel, block_size=[256, 256, 256]): """ Top-hat transform with flat structuring element. Also known as a white top hat transform. It is given by ``tophat(x) = x - open(x)``. Parameters ---------- vol Volume to top-hat transform. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of the top-hat transform. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple top-hat with an 11 x 11 x 11 box structuring element >>> vol = np.zeros((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 1 # Small box >>> vol[60:80,60:80,40:60] = 1 # Big box >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.tophat(vol, strel) """ return morph(vol, strel, constants.TOPHAT, block_size)
[docs]def bothat(vol, strel, block_size=[256, 256, 256]): """ Bot-hat transform with flat structuring element. Also known as a black top-hat transform. It is given by ``bothat(x) = close(x) - x``. Parameters ---------- vol Volume to bot-hat transform. Must be convertible to numpy array of at most 3 dimensions. strel Structuring element. Must be convertible to numpy array of at most 3 dimensions. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of the bot-hat transform. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple bot-hat with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 0 # Small box >>> vol[60:80,60:80,40:60] = 0 # Big box >>> strel = np.ones((11, 11, 11)) >>> res = pg.flat.bothat(vol, strel) """ return morph(vol, strel, constants.BOTHAT, block_size)
[docs]def linear_morph(vol, line_steps, line_lens, op, block_size=[256, 256, 512]): """ Morphological operation with flat line segment structuring elements. Performs a morphological operation volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operation is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to apply operation to. Must be convertible to numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. op Operation to perform for all line segments. Must be either ``DILATE`` or ``ERODE`` from ``constants``. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of the operation. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple dilation with an 11 x 15 x 21 box structuring element >>> vol = np.zeros((100,100,100)) >>> vol[50, 50, 50] = 1 >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 15, 21] >>> res = pg.flat.linear_morph(vol, lineSteps, lineLens, pg.DILATE) References ---------- .. [H92] M. Van Herk, "A fast algorithm for local minimum and maximum filters on rectangular and octagonal kernels," Pattern Recognition Letters 13. (pp. 517-521). 1992. .. [GW93] J. Gil and M Werman, "Computing 2-D min, median, and max filters," IEEE Transactions on Pattern Analysis and Machine Intelligence 24. (pp. 504-507). 1993. """ assert (op == constants.DILATE or op == constants.ERODE) # Recast inputs to correct datatype vol = np.asarray(vol) old_shape = vol.shape vol = np.atleast_3d(vol) line_steps = np.atleast_2d( np.asarray(line_steps, dtype=np.int32, order='C')) line_lens = np.atleast_1d(np.asarray(line_lens, dtype=np.int32)) assert line_steps.ndim == 2 assert line_steps.shape[1] == 3 assert line_steps.shape[0] == line_lens.shape[0] line_steps = np.array(np.flip(line_steps, axis=1)) # Prepare output volume vol_size = vol.shape res = np.empty_like(vol) ret = _thin.flat_linear_dilate_erode_impl( res.ctypes.data, vol.ctypes.data, line_steps, line_lens, vol_size[2], vol_size[1], vol_size[0], line_lens.shape[0], vol.dtype.num, op, block_size[2], block_size[1], block_size[0]) _thin.raise_on_error(ret) return np.resize(res, old_shape)
[docs]def linear_dilate(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Dilation with flat line segment structuring elements. Erodes volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to dilate. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of dilation. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple dilation with an 11 x 15 x 21 box structuring element >>> vol = np.zeros((100,100,100)) >>> vol[50, 50, 50] = 1 >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 15, 21] >>> res = pg.flat.linear_dilate(vol, lineSteps, lineLens) """ return linear_morph(vol, line_steps, line_lens, constants.DILATE, block_size)
[docs]def linear_erode(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Erosion with flat line segment structuring elements. Erodes volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to erode. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of erosion. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple erosion with an 11 x 15 x 21 box structuring element >>> vol = np.ones((100,100,100)) >>> vol[50, 50, 50] = 0 >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 15, 21] >>> res = pg.flat.linear_erode(vol, lineSteps, lineLens) """ return linear_morph(vol, line_steps, line_lens, constants.ERODE, block_size)
[docs]def linear_open(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Opening with flat line segment structuring elements. Opens volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to open. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of opening. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple opening with an 11 x 11 x 11 box structuring element >>> vol = np.zeros((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 1 # Small box >>> vol[60:80,60:80,40:60] = 1 # Big box >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 11, 11] >>> res = pg.flat.linear_open(vol, lineSteps, lineLens) """ res = linear_erode(vol, line_steps, line_lens, block_size) return linear_dilate(res, line_steps, line_lens, block_size)
[docs]def linear_close(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Closing with flat line segment structuring elements. Closes volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to close. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of closing. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple closing with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 0 # Small box >>> vol[60:80,60:80,40:60] = 0 # Big box >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 11, 11] >>> res = pg.flat.linear_close(vol, lineSteps, lineLens) """ res = linear_dilate(vol, line_steps, line_lens, block_size) return linear_erode(res, line_steps, line_lens, block_size)
[docs]def linear_tophat(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Top-hat transform with flat line segment structuring elements. Top-hat transforms volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to top-hat transform. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of top-hat transform. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple top-hat with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 0 # Small box >>> vol[60:80,60:80,40:60] = 0 # Big box >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 11, 11] >>> res = pg.flat.linear_tophat(vol, lineSteps, lineLens) """ return vol - linear_open(vol, line_steps, line_lens, block_size)
[docs]def linear_bothat(vol, line_steps, line_lens, block_size=[256, 256, 512]): """ Bot-hat transform with flat line segment structuring elements. Bot-hat transforms volume with a sequence of flat line segments. Line segments are parameterized with a (integer) step vector and a length giving the number of steps. The operations is the same for all line segments. The operations are performed using the van Herk/Gil-Werman algorithm [H92]_ [GW93]_. Parameters ---------- vol Volume to bot-hat transform. Must be convertible to a numpy array of at most 3 dimensions. line_steps Step vector or sequence of step vectors. A step vector must have integer coordinates and control the direction of the line segment. line_lens Length or sequence of lengths. Controls the length of the line segments. A length of 0 leaves the volume unchanged. block_size Block size for GPU processing. Volume is sent to the GPU in blocks of this size. Returns ------- numpy.array Volume of same size as vol with the result of bot-hat transform. Example ------- .. code-block:: python :dedent: 4 >>> import numpy as np >>> import pygorpho as pg >>> # Simple bot-hat with an 11 x 11 x 11 box structuring element >>> vol = np.ones((100, 100, 100)) >>> vol[10:15,10:15,48:53] = 0 # Small box >>> vol[60:80,60:80,40:60] = 0 # Big box >>> lineSteps = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> lineLens = [11, 11, 11] >>> res = pg.flat.linear_tophat(vol, lineSteps, lineLens) """ return linear_close(vol, line_steps, line_lens, block_size) - vol