Source code for torchio.transforms.preprocessing.spatial.to_canonical

import nibabel as nib
import numpy as np
import torch

from ... import SpatialTransform
from ....data.subject import Subject


[docs] class ToCanonical(SpatialTransform): """Reorder the data to be closest to canonical (RAS+) orientation. This transform reorders the voxels and modifies the affine matrix so that the voxel orientations are nearest to: 1. First voxel axis goes from left to Right 2. Second voxel axis goes from posterior to Anterior 3. Third voxel axis goes from inferior to Superior See `NiBabel docs about image orientation`_ for more information. Args: **kwargs: See :class:`~torchio.transforms.Transform` for additional keyword arguments. .. note:: The reorientation is performed using :meth:`nibabel.as_closest_canonical`. .. _NiBabel docs about image orientation: https://nipy.org/nibabel/image_orientation.html """ # noqa: B950 def apply_transform(self, subject: Subject) -> Subject: for image in subject.get_images(intensity_only=False): affine = image.affine if nib.aff2axcodes(affine) == tuple('RAS'): continue array = image.numpy()[np.newaxis] # (1, C, W, H, D) # NIfTI images should have channels in 5th dimension array = array.transpose(2, 3, 4, 0, 1) # (W, H, D, 1, C) nii = nib.Nifti1Image(array, affine) reoriented = nib.as_closest_canonical(nii) # https://nipy.org/nibabel/reference/nibabel.dataobj_images.html#nibabel.dataobj_images.DataobjImage.get_data array = np.asanyarray(reoriented.dataobj) # https://github.com/facebookresearch/InferSent/issues/99#issuecomment-446175325 array = array.copy() array = array.transpose(3, 4, 0, 1, 2) # (1, C, W, H, D) image.set_data(torch.as_tensor(array[0])) image.affine = reoriented.affine return subject