Bases: SpatialTransform
Swap the first and last spatial dimensions.
Transforms an image of shape \((C, I, J, K)\) into \((C, K, J, I)\).
The affine matrix is updated to reflect the reordering so that
world coordinates remain consistent.
This is the v2 equivalent of v1's Transpose, which reversed
the orientation string. The transform is its own inverse.
Parameters:
| Name |
Type |
Description |
Default |
**kwargs
|
Any
|
|
{}
|
Examples:
>>> import torchio as tio
>>> transform = tio.Transpose()
Source code in src/torchio/transforms/spatial/transpose.py
| class Transpose(SpatialTransform):
r"""Swap the first and last spatial dimensions.
Transforms an image of shape $(C, I, J, K)$ into $(C, K, J, I)$.
The affine matrix is updated to reflect the reordering so that
world coordinates remain consistent.
This is the v2 equivalent of v1's `Transpose`, which reversed
the orientation string. The transform is its own inverse.
Args:
**kwargs: See [`Transform`][torchio.Transform].
Examples:
>>> import torchio as tio
>>> transform = tio.Transpose()
"""
def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
def make_params(self, batch: SubjectsBatch) -> dict[str, Any]:
"""No random parameters."""
return {}
def apply_transform(
self,
batch: SubjectsBatch,
params: dict[str, Any],
) -> SubjectsBatch:
"""Swap first and last spatial axes for all images."""
for _name, img_batch in batch.images.items():
# Swap axes 2 (I) and 4 (K) in the (B, C, I, J, K) tensor.
img_batch.data = img_batch.data.permute(0, 1, 4, 3, 2).contiguous()
# Update affines: swap columns 0 and 2 (I↔K).
for affine in img_batch.affines:
m = affine._matrix.clone()
affine._matrix[:, 0] = m[:, 2]
affine._matrix[:, 2] = m[:, 0]
return batch
@property
def invertible(self) -> bool:
"""Transpose is its own inverse."""
return True
def inverse(self, params: dict[str, Any]) -> Transpose:
"""Transposing twice is identity."""
return Transpose(copy=False)
|
invertible
property
Transpose is its own inverse.
forward(data)
forward(data: Subject) -> Subject
forward(data: Image) -> Image
forward(data: Tensor) -> Tensor
forward(data: np.ndarray) -> np.ndarray
forward(data: sitk.Image) -> sitk.Image
forward(data: nib.Nifti1Image) -> nib.Nifti1Image
forward(data: dict) -> dict
forward(data: ImagesBatch) -> ImagesBatch
forward(data: SubjectsBatch) -> SubjectsBatch
Apply the transform.
The output type always matches the input type.
Parameters:
| Name |
Type |
Description |
Default |
data
|
Any
|
|
required
|
Source code in src/torchio/transforms/transform.py
| def forward(self, data: Any) -> Any:
"""Apply the transform.
The output type always matches the input type.
Args:
data: Input data to transform.
"""
if self.copy:
data = _copy.deepcopy(data)
batch, unwrap = self._wrap(data)
if torch.rand(1).item() > self.p:
return unwrap(batch)
params = self.make_params(batch)
batch = self.apply_transform(batch, params)
# Record history on the batch
trace = AppliedTransform(name=type(self).__name__, params=params)
if not hasattr(batch, "applied_transforms"):
batch.applied_transforms = []
batch.applied_transforms.append(trace)
result = unwrap(batch)
# Propagate history to outputs that can carry it
if (
hasattr(batch, "applied_transforms")
and not isinstance(result, (SubjectsBatch, Tensor, np.ndarray))
and not isinstance(result, dict)
):
with contextlib.suppress(AttributeError):
result.applied_transforms = list(batch.applied_transforms)
return result
|
to_hydra()
Export as a Hydra-compatible config dict.
Returns a dict with _target_ set to the fully qualified
class name and only non-default field values included.
Returns:
| Type |
Description |
dict[str, Any]
|
Dict suitable for hydra.utils.instantiate().
|
Source code in src/torchio/transforms/transform.py
| def to_hydra(self) -> dict[str, Any]:
"""Export as a Hydra-compatible config dict.
Returns a dict with `_target_` set to the fully qualified
class name and only non-default field values included.
Returns:
Dict suitable for `hydra.utils.instantiate()`.
"""
from .parameter_range import _ParameterRange
cls = type(self)
target = f"torchio.{cls.__qualname__}"
cfg: dict[str, Any] = {"_target_": target}
for name, default in _collect_init_params(cls).items():
value = getattr(self, name, default)
if isinstance(value, _ParameterRange):
if value._original == default:
continue
value = _hydra_value(value._original)
elif value == default:
continue
else:
value = _hydra_value(value)
cfg[name] = value
return cfg
|
make_params(batch)
No random parameters.
Source code in src/torchio/transforms/spatial/transpose.py
| def make_params(self, batch: SubjectsBatch) -> dict[str, Any]:
"""No random parameters."""
return {}
|
Swap first and last spatial axes for all images.
Source code in src/torchio/transforms/spatial/transpose.py
| def apply_transform(
self,
batch: SubjectsBatch,
params: dict[str, Any],
) -> SubjectsBatch:
"""Swap first and last spatial axes for all images."""
for _name, img_batch in batch.images.items():
# Swap axes 2 (I) and 4 (K) in the (B, C, I, J, K) tensor.
img_batch.data = img_batch.data.permute(0, 1, 4, 3, 2).contiguous()
# Update affines: swap columns 0 and 2 (I↔K).
for affine in img_batch.affines:
m = affine._matrix.clone()
affine._matrix[:, 0] = m[:, 2]
affine._matrix[:, 2] = m[:, 0]
return batch
|
inverse(params)
Transposing twice is identity.
Source code in src/torchio/transforms/spatial/transpose.py
| def inverse(self, params: dict[str, Any]) -> Transpose:
"""Transposing twice is identity."""
return Transpose(copy=False)
|