Skip to content
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
6 changes: 3 additions & 3 deletions monai/transforms/croppad/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def compute_pad_width(self, spatial_shape: Sequence[int]) -> List[Tuple[int, int

class Crop(InvertibleTransform):
"""
Perform crop operation on the input image.
Perform crop operations on the input image.

"""

Expand All @@ -378,7 +378,7 @@ def compute_slices(
roi_slices: Optional[Sequence[slice]] = None,
):
"""
Compute the crop slices based on specified `center & size` or `start & end`.
Compute the crop slices based on specified `center & size` or `start & end` or `slices`.

Args:
roi_center: voxel coordinates for center of the crop ROI.
Expand Down Expand Up @@ -471,7 +471,7 @@ class SpatialCrop(Crop):
It can support to crop ND spatial (channel-first) data.

The cropped region can be parameterised in various ways:
- a list of slices for each spatial dimension (allows for use of -ve indexing and `None`)
- a list of slices for each spatial dimension (allows for use of negative indexing and `None`)
- a spatial center and size
- the start and end coordinates of the ROI
"""
Expand Down
4 changes: 2 additions & 2 deletions monai/transforms/meta_utility/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class FromMetaTensord(MapTransform, InvertibleTransform):
have the form `{"a": torch.Tensor, "a_meta_dict": dict, "a_transforms": list, "b": ...}`.
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH, TransformBackends.NUMPY, TransformBackends.CUPY]

def __init__(
self, keys: KeysCollection, data_type: Union[Sequence[str], str] = "tensor", allow_missing_keys: bool = False
Expand Down Expand Up @@ -92,7 +92,7 @@ class ToMetaTensord(MapTransform, InvertibleTransform):
have the form `{"a": MetaTensor, "b": MetaTensor}`.
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH, TransformBackends.NUMPY, TransformBackends.CUPY]

def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]:
d = dict(data)
Expand Down
8 changes: 6 additions & 2 deletions monai/transforms/post/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class KeepLargestConnectedComponent(Transform):

"""

backend = [TransformBackends.NUMPY]
backend = [TransformBackends.NUMPY, TransformBackends.CUPY]

def __init__(
self,
Expand Down Expand Up @@ -354,6 +354,8 @@ class RemoveSmallObjects(Transform):
If false, the overall size islands made from all non-background voxels will be used.
"""

backend = [TransformBackends.NUMPY]

def __init__(self, min_size: int = 64, connectivity: int = 1, independent_channels: bool = True) -> None:
self.min_size = min_size
self.connectivity = connectivity
Expand Down Expand Up @@ -703,7 +705,7 @@ class ProbNMS(Transform):

"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.NUMPY]

def __init__(
self,
Expand Down Expand Up @@ -765,6 +767,8 @@ class Invert(Transform):
Utility transform to automatically invert the previously applied transforms.
"""

backend = [TransformBackends.TORCH]

def __init__(
self,
transform: Optional[InvertibleTransform] = None,
Expand Down
4 changes: 4 additions & 0 deletions monai/transforms/post/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ class RemoveSmallObjectsd(MapTransform):
If false, the overall size islands made from all non-background voxels will be used.
"""

backend = RemoveSmallObjects.backend

def __init__(
self,
keys: KeysCollection,
Expand Down Expand Up @@ -785,6 +787,8 @@ class SobelGradientsd(MapTransform):

"""

backend = SobelGradients.backend

def __init__(
self,
keys: KeysCollection,
Expand Down
6 changes: 4 additions & 2 deletions monai/transforms/smooth_field/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class SmoothField(Randomizable):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH]

def __init__(
self,
rand_size: Sequence[int],
Expand Down Expand Up @@ -160,7 +162,7 @@ class RandSmoothFieldAdjustContrast(RandomizableTransform):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(
self,
Expand Down Expand Up @@ -261,7 +263,7 @@ class RandSmoothFieldAdjustIntensity(RandomizableTransform):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(
self,
Expand Down
7 changes: 3 additions & 4 deletions monai/transforms/smooth_field/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
)
from monai.transforms.transform import MapTransform, RandomizableTransform
from monai.utils import GridSampleMode, GridSamplePadMode, InterpolateMode, convert_to_tensor, ensure_tuple_rep
from monai.utils.enums import TransformBackends

__all__ = [
"RandSmoothFieldAdjustContrastd",
Expand Down Expand Up @@ -60,7 +59,7 @@ class RandSmoothFieldAdjustContrastd(RandomizableTransform, MapTransform):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = RandSmoothFieldAdjustContrast.backend

def __init__(
self,
Expand Down Expand Up @@ -138,7 +137,7 @@ class RandSmoothFieldAdjustIntensityd(RandomizableTransform, MapTransform):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = RandSmoothFieldAdjustIntensity.backend

def __init__(
self,
Expand Down Expand Up @@ -219,7 +218,7 @@ class RandSmoothDeformd(RandomizableTransform, MapTransform):
device: Pytorch device to define field on
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = RandSmoothDeform.backend

def __init__(
self,
Expand Down
2 changes: 1 addition & 1 deletion monai/transforms/spatial/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class SpatialResample(InvertibleTransform):
by ``xform = linalg.solve(src_affine, dst_affine)``, and call ``monai.transforms.Affine`` with ``xform``.
"""

backend = [TransformBackends.TORCH]
backend = [TransformBackends.TORCH, TransformBackends.NUMPY, TransformBackends.CUPY]

def __init__(
self,
Expand Down
10 changes: 7 additions & 3 deletions monai/transforms/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,13 @@ class Transform(ABC):
:py:class:`monai.transforms.Compose`
"""

# Transforms should add data types to this list if they are capable of performing a transform without
# modifying the input type. For example, ["torch.Tensor", "np.ndarray"] means that no copies of the data
# are required if the input is either `torch.Tensor` or `np.ndarray`.
# Transforms should add `monai.transforms.utils.TransformBackends` to this list if they are performing
# the data processing using the corresponding backend APIs.
# Most of MONAI transform's inputs and outputs will be converted into torch.Tensor or monai.data.MetaTensor.
# This variable provides information about whether the input will be converted
# to other data types during the transformation. Note that not all `dtype` (such as float32, uint8) are supported
# by all the data types, the `dtype` during the conversion is determined automatically by each transform,
# please refer to the transform's docstring.
backend: List[TransformBackends] = []

@abstractmethod
Expand Down
16 changes: 8 additions & 8 deletions monai/transforms/utility/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class RepeatChannel(Transform):
repeats: the number of repetitions for each element.
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(self, repeats: int) -> None:
if repeats <= 0:
Expand Down Expand Up @@ -424,7 +424,7 @@ class ToTensor(Transform):

"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(
self,
Expand Down Expand Up @@ -519,7 +519,7 @@ class ToNumpy(Transform):

"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.NUMPY]

def __init__(self, dtype: DtypeLike = None, wrap_sequence: bool = True) -> None:
super().__init__()
Expand All @@ -546,7 +546,7 @@ class ToCupy(Transform):

"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.CUPY]

def __init__(self, dtype: Optional[np.dtype] = None, wrap_sequence: bool = True) -> None:
super().__init__()
Expand All @@ -565,7 +565,7 @@ class ToPIL(Transform):
Converts the input image (in the form of NumPy array or PyTorch Tensor) to PIL image
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.NUMPY]

def __call__(self, img):
"""
Expand All @@ -583,7 +583,7 @@ class Transpose(Transform):
Transposes the input image based on the given `indices` dimension ordering.
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(self, indices: Optional[Sequence[int]]) -> None:
self.indices = None if indices is None else tuple(indices)
Expand Down Expand Up @@ -1090,7 +1090,7 @@ class AddExtremePointsChannel(Randomizable, Transform):
ValueError: When label image is not single channel.
"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.TORCH]

def __init__(self, background: int = 0, pert: float = 0.0) -> None:
self._background = background
Expand Down Expand Up @@ -1422,7 +1422,7 @@ class AddCoordinateChannels(Transform):

"""

backend = [TransformBackends.TORCH, TransformBackends.NUMPY]
backend = [TransformBackends.NUMPY]

@deprecated_arg(
name="spatial_channels", new_name="spatial_dims", since="0.8", msg_suffix="please use `spatial_dims` instead."
Expand Down
3 changes: 3 additions & 0 deletions monai/transforms/utility/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N


class SplitDimd(MapTransform):

backend = SplitDim.backend

def __init__(
self,
keys: KeysCollection,
Expand Down
7 changes: 6 additions & 1 deletion monai/utils/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,16 @@ def transforms(key: Optional[str] = None):

class TransformBackends(StrEnum):
"""
Transform backends.
Transform backends. Most of `monai.transforms` components first converts the input data into ``torch.Tensor`` or
``monai.data.MetaTensor``. Internally, some transforms are made by converting the data into ``numpy.array`` or
``cupy.array`` and use the underlying transform backend API to achieve the actual output array and
converting back to ``Tensor``/``MetaTensor``. Transforms with more than one backend indicate the that they may
convert the input data types to accomodate the underlying API.
"""

TORCH = "torch"
NUMPY = "numpy"
CUPY = "cupy"


class JITMetadataKeys(StrEnum):
Expand Down