def test_correct(self, affine, scale, expected): output = zoom_affine(affine, scale, diagonal=False) ornt_affine = nib.orientations.ornt2axcodes( nib.orientations.io_orientation(output)) ornt_output = nib.orientations.ornt2axcodes( nib.orientations.io_orientation(affine)) np.testing.assert_array_equal(ornt_affine, ornt_output) np.testing.assert_allclose(output, expected, rtol=1e-6, atol=1e-6)
def __call__(self, data_array, affine=None, interp_order=3): """ Args: data_array (ndarray): in shape (num_channels, H[, W, ...]). affine (matrix): (N+1)x(N+1) original affine matrix for spatially ND `data_array`. Defaults to identity. interp_order (int): The order of the spline interpolation, default is 3. The order has to be in the range 0-5. https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.zoom.html Returns: data_array (resampled into `self.pixdim`), original pixdim, current pixdim. """ sr = data_array.ndim - 1 if sr <= 0: raise ValueError( "the array should have at least one spatial dimension.") if affine is None: # default to identity affine = np.eye(sr + 1, dtype=np.float64) affine_ = np.eye(sr + 1, dtype=np.float64) else: affine_ = to_affine_nd(sr, affine) out_d = self.pixdim[:sr] if out_d.size < sr: out_d = np.append(out_d, [1.0] * (out_d.size - sr)) if np.any(out_d <= 0): raise ValueError(f"pixdim must be positive, got {out_d}") # compute output affine, shape and offset new_affine = zoom_affine(affine_, out_d, diagonal=self.diagonal) output_shape, offset = compute_shape_offset(data_array.shape[1:], affine_, new_affine) new_affine[:sr, -1] = offset[:sr] transform = np.linalg.inv(affine_) @ new_affine # adapt to the actual rank transform_ = to_affine_nd(sr, transform) # resample dtype = data_array.dtype if self.dtype is None else self.dtype output_data = [] for data in data_array: data_ = scipy.ndimage.affine_transform( data.astype(dtype), matrix=transform_, output_shape=output_shape, order=interp_order, mode=self.mode, cval=self.cval, ) output_data.append(data_) output_data = np.stack(output_data) new_affine = to_affine_nd(affine, new_affine) return output_data, affine, new_affine
def test_diagonal(self, affine, scale, expected): output = zoom_affine(affine, scale, diagonal=True) np.testing.assert_allclose(output, expected, rtol=1e-6, atol=1e-6)