In training AI algorithms for e.g. CT scan segmentation, patches are often extracted due to the GPU memory constraints. Additionally, patches are augmented with transforms such as rotation and scaling.
Now I have implemented such procedure using sitk.Resample
, but it’s quite involved as you have to first calculate how big your patch should be such that the original patch size can be extracted from the transformed patch without having any padding values. It would be much simpler to use the patch origin and transformed spacing, and direction to sample from the original image. This can be done using for example scipy’s map_coordinates
,
def random_rotate_patch(self, patch, order=3, mode='nearest', cval=0.0):
from scipy.spatial.transform import Rotation as R
from scipy.ndimage import map_coordinates
si, sj, sk = patch.shape
patch_center = 0.5 * np.array([si,sj,sk])
coords = np.mgrid[0:si, 0:sj, 0:sk].T.reshape(-1,3) - patch_center
axis = self._random_axis()
angle = self.rng.random() * 0.08 * np.pi
rot = R.from_rotvec(angle * axis).as_matrix()
coords_rotated = coords @ rot.T
coords_rotated += patch_center
coords_rotated = coords_rotated.reshape((si,sj,sk,3))
coords_rotated = np.transpose(coords_rotated, (3, 0, 1, 2))
patch_rotated = map_coordinates(patch, coords_rotated, order=order, cval=cval, mode=mode)
return patch_rotated
but this is x10 slower than the SimpleITK implementation I mentioned above. Can I somehow achieve something similar to the above code using SimpleITK or ITK?