_slice_along_axes.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. __all__ = ['slice_along_axes']
  2. def slice_along_axes(image, slices, axes=None, copy=False):
  3. """Slice an image along given axes.
  4. Parameters
  5. ----------
  6. image : ndarray
  7. Input image.
  8. slices : list of 2-tuple (a, b) where a < b.
  9. For each axis in `axes`, a corresponding 2-tuple
  10. ``(min_val, max_val)`` to slice with (as with Python slices,
  11. ``max_val`` is non-inclusive).
  12. axes : int or tuple, optional
  13. Axes corresponding to the limits given in `slices`. If None,
  14. axes are in ascending order, up to the length of `slices`.
  15. copy : bool, optional
  16. If True, ensure that the output is not a view of `image`.
  17. Returns
  18. -------
  19. out : ndarray
  20. The region of `image` corresponding to the given slices and axes.
  21. Examples
  22. --------
  23. >>> from skimage import data
  24. >>> img = data.camera()
  25. >>> img.shape
  26. (512, 512)
  27. >>> cropped_img = slice_along_axes(img, [(0, 100)])
  28. >>> cropped_img.shape
  29. (100, 512)
  30. >>> cropped_img = slice_along_axes(img, [(0, 100), (0, 100)])
  31. >>> cropped_img.shape
  32. (100, 100)
  33. >>> cropped_img = slice_along_axes(img, [(0, 100), (0, 75)], axes=[1, 0])
  34. >>> cropped_img.shape
  35. (75, 100)
  36. """
  37. # empty length of bounding box detected on None
  38. if not slices:
  39. return image
  40. if axes is None:
  41. axes = list(range(image.ndim))
  42. if len(axes) < len(slices):
  43. raise ValueError("More `slices` than available axes")
  44. elif len(axes) != len(slices):
  45. raise ValueError("`axes` and `slices` must have equal length")
  46. if len(axes) != len(set(axes)):
  47. raise ValueError("`axes` must be unique")
  48. if not all(a >= 0 and a < image.ndim for a in axes):
  49. raise ValueError(
  50. f"axes {axes} out of range; image has only " f"{image.ndim} dimensions"
  51. )
  52. _slices = [
  53. slice(None),
  54. ] * image.ndim
  55. for (a, b), ax in zip(slices, axes):
  56. if a < 0:
  57. a %= image.shape[ax]
  58. if b < 0:
  59. b %= image.shape[ax]
  60. if a > b:
  61. raise ValueError(
  62. f"Invalid slice ({a}, {b}): must be ordered `(min_val, max_val)`"
  63. )
  64. if a < 0 or b > image.shape[ax]:
  65. raise ValueError(
  66. f"Invalid slice ({a}, {b}) for image with dimensions {image.shape}"
  67. )
  68. _slices[ax] = slice(a, b)
  69. image_slice = image[tuple(_slices)]
  70. if copy and image_slice.base is not None:
  71. image_slice = image_slice.copy()
  72. return image_slice