isotropic.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. """
  2. Binary morphological operations
  3. """
  4. import numpy as np
  5. from scipy import ndimage as ndi
  6. def isotropic_erosion(image, radius, out=None, spacing=None):
  7. """Return binary morphological erosion of an image.
  8. Compared to the more general :func:`skimage.morphology.erosion`, this
  9. function only supports binary inputs and circular footprints.
  10. However, it performs typically faster for large (circular) footprints.
  11. This works by applying a threshold to the exact Euclidean distance map
  12. of the image [1]_, [2]_.
  13. The implementation is based on: func:`scipy.ndimage.distance_transform_edt`.
  14. Parameters
  15. ----------
  16. image : ndarray
  17. Binary input image.
  18. radius : float
  19. The radius of the footprint used for the operation.
  20. out : ndarray of bool, optional
  21. The array to store the result of the morphology. If None,
  22. a new array will be allocated.
  23. spacing : float, or sequence of float, optional
  24. Spacing of elements along each dimension.
  25. If a sequence, must be of length equal to the input's dimension (number of axes).
  26. If a single number, this value is used for all axes.
  27. If not specified, a grid spacing of unity is implied.
  28. Returns
  29. -------
  30. eroded : ndarray of bool
  31. The result of the morphological erosion taking values in
  32. ``[False, True]``.
  33. References
  34. ----------
  35. .. [1] Cuisenaire, O. and Macq, B., "Fast Euclidean morphological operators
  36. using local distance transformation by propagation, and applications,"
  37. Image Processing And Its Applications, 1999. Seventh International
  38. Conference on (Conf. Publ. No. 465), 1999, pp. 856-860 vol.2.
  39. :DOI:`10.1049/cp:19990446`
  40. .. [2] Ingemar Ragnemalm, Fast erosion and dilation by contour processing
  41. and thresholding of distance maps, Pattern Recognition Letters,
  42. Volume 13, Issue 3, 1992, Pages 161-166.
  43. :DOI:`10.1016/0167-8655(92)90055-5`
  44. Examples
  45. --------
  46. Erosion shrinks bright regions
  47. >>> import numpy as np
  48. >>> import skimage as ski
  49. >>> image = np.array([[0, 0, 1, 0, 0],
  50. ... [0, 1, 1, 1, 0],
  51. ... [0, 1, 1, 1, 0],
  52. ... [0, 1, 1, 1, 0],
  53. ... [0, 0, 0, 0, 0]], dtype=bool)
  54. >>> result = ski.morphology.isotropic_erosion(image, radius=1)
  55. >>> result.view(np.uint8)
  56. array([[0, 0, 0, 0, 0],
  57. [0, 0, 1, 0, 0],
  58. [0, 0, 1, 0, 0],
  59. [0, 0, 0, 0, 0],
  60. [0, 0, 0, 0, 0]], dtype=uint8)
  61. """
  62. dist = ndi.distance_transform_edt(image, sampling=spacing)
  63. return np.greater(dist, radius, out=out)
  64. def isotropic_dilation(image, radius, out=None, spacing=None):
  65. """Return binary morphological dilation of an image.
  66. Compared to the more general :func:`skimage.morphology.dilation`, this
  67. function only supports binary inputs and circular footprints.
  68. However, it performs typically faster for large (circular) footprints.
  69. This works by applying a threshold to the exact Euclidean distance map
  70. of the inverted image [1]_, [2]_.
  71. The implementation is based on: func:`scipy.ndimage.distance_transform_edt`.
  72. Parameters
  73. ----------
  74. image : ndarray
  75. Binary input image.
  76. radius : float
  77. The radius of the footprint used for the operation.
  78. out : ndarray of bool, optional
  79. The array to store the result of the morphology. If None is
  80. passed, a new array will be allocated.
  81. spacing : float, or sequence of float, optional
  82. Spacing of elements along each dimension.
  83. If a sequence, must be of length equal to the input's dimension (number of axes).
  84. If a single number, this value is used for all axes.
  85. If not specified, a grid spacing of unity is implied.
  86. Returns
  87. -------
  88. dilated : ndarray of bool
  89. The result of the morphological dilation with values in
  90. ``[False, True]``.
  91. References
  92. ----------
  93. .. [1] Cuisenaire, O. and Macq, B., "Fast Euclidean morphological operators
  94. using local distance transformation by propagation, and applications,"
  95. Image Processing And Its Applications, 1999. Seventh International
  96. Conference on (Conf. Publ. No. 465), 1999, pp. 856-860 vol.2.
  97. :DOI:`10.1049/cp:19990446`
  98. .. [2] Ingemar Ragnemalm, Fast erosion and dilation by contour processing
  99. and thresholding of distance maps, Pattern Recognition Letters,
  100. Volume 13, Issue 3, 1992, Pages 161-166.
  101. :DOI:`10.1016/0167-8655(92)90055-5`
  102. Examples
  103. --------
  104. Dilation enlarges bright regions
  105. >>> import numpy as np
  106. >>> import skimage as ski
  107. >>> image = np.array([[0, 0, 0, 0, 0],
  108. ... [0, 0, 0, 0, 0],
  109. ... [0, 0, 1, 0, 0],
  110. ... [0, 0, 1, 1, 0],
  111. ... [0, 0, 0, 0, 0]], dtype=bool)
  112. >>> result = ski.morphology.isotropic_dilation(image, radius=1)
  113. >>> result.view(np.uint8)
  114. array([[0, 0, 0, 0, 0],
  115. [0, 0, 1, 0, 0],
  116. [0, 1, 1, 1, 0],
  117. [0, 1, 1, 1, 1],
  118. [0, 0, 1, 1, 0]], dtype=uint8)
  119. """
  120. dist = ndi.distance_transform_edt(np.logical_not(image), sampling=spacing)
  121. return np.less_equal(dist, radius, out=out)
  122. def isotropic_opening(image, radius, out=None, spacing=None):
  123. """Return binary morphological opening of an image.
  124. Compared to the more general :func:`skimage.morphology.opening`, this
  125. function only supports binary inputs and circular footprints.
  126. However, it performs typically faster for large (circular) footprints.
  127. This works by thresholding the exact Euclidean distance map [1]_, [2]_.
  128. The implementation is based on: func:`scipy.ndimage.distance_transform_edt`.
  129. Parameters
  130. ----------
  131. image : ndarray
  132. Binary input image.
  133. radius : float
  134. The radius of the footprint used for the operation.
  135. out : ndarray of bool, optional
  136. The array to store the result of the morphology. If None
  137. is passed, a new array will be allocated.
  138. spacing : float, or sequence of float, optional
  139. Spacing of elements along each dimension.
  140. If a sequence, must be of length equal to the input's dimension (number of axes).
  141. If a single number, this value is used for all axes.
  142. If not specified, a grid spacing of unity is implied.
  143. Returns
  144. -------
  145. opened : ndarray of bool
  146. The result of the morphological opening.
  147. References
  148. ----------
  149. .. [1] Cuisenaire, O. and Macq, B., "Fast Euclidean morphological operators
  150. using local distance transformation by propagation, and applications,"
  151. Image Processing And Its Applications, 1999. Seventh International
  152. Conference on (Conf. Publ. No. 465), 1999, pp. 856-860 vol.2.
  153. :DOI:`10.1049/cp:19990446`
  154. .. [2] Ingemar Ragnemalm, Fast erosion and dilation by contour processing
  155. and thresholding of distance maps, Pattern Recognition Letters,
  156. Volume 13, Issue 3, 1992, Pages 161-166.
  157. :DOI:`10.1016/0167-8655(92)90055-5`
  158. Examples
  159. --------
  160. Remove connection between two bright regions
  161. >>> import numpy as np
  162. >>> import skimage as ski
  163. >>> image = np.array([[1, 0, 0, 0, 1],
  164. ... [1, 1, 0, 1, 1],
  165. ... [1, 1, 1, 1, 1],
  166. ... [1, 1, 0, 1, 1],
  167. ... [1, 0, 0, 0, 1]], dtype=bool)
  168. >>> result = ski.morphology.isotropic_opening(image, radius=1)
  169. >>> result.view(np.uint8)
  170. array([[1, 0, 0, 0, 1],
  171. [1, 1, 0, 1, 1],
  172. [1, 1, 1, 1, 1],
  173. [1, 1, 0, 1, 1],
  174. [1, 0, 0, 0, 1]], dtype=uint8)
  175. """
  176. eroded = isotropic_erosion(image, radius, out=out, spacing=spacing)
  177. return isotropic_dilation(eroded, radius, out=out, spacing=spacing)
  178. def isotropic_closing(image, radius, out=None, spacing=None):
  179. """Return binary morphological closing of an image.
  180. Compared to the more general :func:`skimage.morphology.closing`, this
  181. function only supports binary inputs and circular footprints.
  182. However, it performs typically faster for large (circular) footprints.
  183. This works by thresholding the exact Euclidean distance map [1]_, [2]_.
  184. The implementation is based on: func:`scipy.ndimage.distance_transform_edt`.
  185. Parameters
  186. ----------
  187. image : ndarray
  188. Binary input image.
  189. radius : float
  190. The radius of the footprint used for the operation.
  191. out : ndarray of bool, optional
  192. The array to store the result of the morphology. If None,
  193. is passed, a new array will be allocated.
  194. spacing : float, or sequence of float, optional
  195. Spacing of elements along each dimension.
  196. If a sequence, must be of length equal to the input's dimension (number of axes).
  197. If a single number, this value is used for all axes.
  198. If not specified, a grid spacing of unity is implied.
  199. Returns
  200. -------
  201. closed : ndarray of bool
  202. The result of the morphological closing.
  203. References
  204. ----------
  205. .. [1] Cuisenaire, O. and Macq, B., "Fast Euclidean morphological operators
  206. using local distance transformation by propagation, and applications,"
  207. Image Processing And Its Applications, 1999. Seventh International
  208. Conference on (Conf. Publ. No. 465), 1999, pp. 856-860 vol.2.
  209. :DOI:`10.1049/cp:19990446`
  210. .. [2] Ingemar Ragnemalm, Fast erosion and dilation by contour processing
  211. and thresholding of distance maps, Pattern Recognition Letters,
  212. Volume 13, Issue 3, 1992, Pages 161-166.
  213. :DOI:`10.1016/0167-8655(92)90055-5`
  214. Examples
  215. --------
  216. Close gap between two bright lines
  217. >>> import numpy as np
  218. >>> import skimage as ski
  219. >>> image = np.array([[0, 0, 0, 0, 0],
  220. ... [0, 0, 0, 0, 0],
  221. ... [1, 1, 0, 1, 1],
  222. ... [0, 0, 0, 0, 0],
  223. ... [0, 0, 0, 0, 0]], dtype=bool)
  224. >>> result = ski.morphology.isotropic_closing(image, radius=1)
  225. >>> result.view(np.uint8)
  226. array([[0, 0, 0, 0, 0],
  227. [0, 0, 0, 0, 0],
  228. [1, 1, 0, 1, 1],
  229. [0, 0, 0, 0, 0],
  230. [0, 0, 0, 0, 0]], dtype=uint8)
  231. """
  232. dilated = isotropic_dilation(image, radius, out=out, spacing=spacing)
  233. return isotropic_erosion(dilated, radius, out=out, spacing=spacing)