def test_resample_from_to(): # Test resampling from image to image / image space data = np.arange(24).reshape((2, 3, 4)) affine = np.diag([-4, 5, 6, 1]) img = Nifti1Image(data, affine) img.header['descrip'] = 'red shirt image' out = resample_from_to(img, img) assert_almost_equal(img.dataobj, out.dataobj) assert_array_equal(img.affine, out.affine) # Check resampling reverses effect of flipping axes # This will also test translations flip_ornt = np.array([[0, 1], [1, 1], [2, 1]]) for axis in (0, 1, 2): ax_flip_ornt = flip_ornt.copy() ax_flip_ornt[axis, 1] = -1 aff_flip_i = inv_ornt_aff(ax_flip_ornt, (2, 3, 4)) flipped_img = Nifti1Image(flip_axis(data, axis), np.dot(affine, aff_flip_i)) out = resample_from_to(flipped_img, ((2, 3, 4), affine)) assert_almost_equal(img.dataobj, out.dataobj) assert_array_equal(img.affine, out.affine) # A translation of one voxel on each axis trans_aff = from_matvec(np.diag([-4, 5, 6]), [4, -5, -6]) trans_img = Nifti1Image(data, trans_aff) out = resample_from_to(trans_img, img) exp_out = np.zeros_like(data) exp_out[:-1, :-1, :-1] = data[1:, 1:, 1:] assert_almost_equal(out.dataobj, exp_out) out = resample_from_to(img, trans_img) trans_exp_out = np.zeros_like(data) trans_exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1] assert_almost_equal(out.dataobj, trans_exp_out) # Test mode with translation of first axis only # Default 'constant' mode first trans1_aff = from_matvec(np.diag([-4, 5, 6]), [4, 0, 0]) trans1_img = Nifti1Image(data, trans1_aff) out = resample_from_to(img, trans1_img) exp_out = np.zeros_like(data) exp_out[1:, :, :] = data[:-1, :, :] assert_almost_equal(out.dataobj, exp_out) # Then 'nearest' mode out = resample_from_to(img, trans1_img, mode='nearest') exp_out[0, :, :] = exp_out[1, :, :] assert_almost_equal(out.dataobj, exp_out) # Test order trans_p_25_aff = from_matvec(np.diag([-4, 5, 6]), [1, 0, 0]) trans_p_25_img = Nifti1Image(data, trans_p_25_aff) # Suprising to me, but all points outside are set to 0, even with NN out = resample_from_to(img, trans_p_25_img, order=0) exp_out = np.zeros_like(data) exp_out[1:, :, :] = data[1, :, :] assert_almost_equal(out.dataobj, exp_out) out = resample_from_to(img, trans_p_25_img) exp_out = spnd.affine_transform(data, [1, 1, 1], [-0.25, 0, 0], order=3) assert_almost_equal(out.dataobj, exp_out) # Test cval out = resample_from_to(img, trans_img, cval=99) exp_out = np.zeros_like(data) + 99 exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1] assert_almost_equal(out.dataobj, exp_out) # Out class out = resample_from_to(img, trans_img) assert out.__class__ == Nifti1Image # By default, type of from_img makes no difference n1_img = Nifti2Image(data, affine) out = resample_from_to(n1_img, trans_img) assert out.__class__ == Nifti1Image # Passed as keyword arg out = resample_from_to(img, trans_img, out_class=Nifti2Image) assert out.__class__ == Nifti2Image # If keyword arg is None, use type of from_img out = resample_from_to(n1_img, trans_img, out_class=None) assert out.__class__ == Nifti2Image # to_img type irrelevant in all cases n1_trans_img = Nifti2Image(data, trans_aff) out = resample_from_to(img, n1_trans_img, out_class=None) assert out.__class__ == Nifti1Image # From 2D to 3D, error, the fixed affine is not invertible img_2d = Nifti1Image(data[:, :, 0], affine) with pytest.raises(AffineError): resample_from_to(img_2d, img) # 3D to 2D, we don't need to invert the fixed matrix out = resample_from_to(img, img_2d) assert_array_equal(out.dataobj, data[:, :, 0]) # Same for tuple as to_img imput out = resample_from_to(img, (img_2d.shape, img_2d.affine)) assert_array_equal(out.dataobj, data[:, :, 0]) # 4D input and output also OK data_4d = np.arange(24 * 5).reshape((2, 3, 4, 5)) img_4d = Nifti1Image(data_4d, affine) out = resample_from_to(img_4d, img_4d) assert_almost_equal(data_4d, out.dataobj) assert_array_equal(img_4d.affine, out.affine) # Errors trying to match 3D to 4D with pytest.raises(ValueError): resample_from_to(img_4d, img) with pytest.raises(ValueError): resample_from_to(img, img_4d)
def test_resample_from_to(): # Test resampling from image to image / image space data = np.arange(24).reshape((2, 3, 4)) affine = np.diag([-4, 5, 6, 1]) img = Nifti1Image(data, affine) img.header['descrip'] = 'red shirt image' out = resample_from_to(img, img) assert_almost_equal(img.dataobj, out.dataobj) assert_array_equal(img.affine, out.affine) # Check resampling reverses effect of flipping axes # This will also test translations flip_ornt = np.array([[0, 1], [1, 1], [2, 1]]) for axis in (0, 1, 2): ax_flip_ornt = flip_ornt.copy() ax_flip_ornt[axis, 1] = -1 aff_flip_i = inv_ornt_aff(ax_flip_ornt, (2, 3, 4)) flipped_img = Nifti1Image(flip_axis(data, axis), np.dot(affine, aff_flip_i)) out = resample_from_to(flipped_img, ((2, 3, 4), affine)) assert_almost_equal(img.dataobj, out.dataobj) assert_array_equal(img.affine, out.affine) # A translation of one voxel on each axis trans_aff = from_matvec(np.diag([-4, 5, 6]), [4, -5, -6]) trans_img = Nifti1Image(data, trans_aff) out = resample_from_to(trans_img, img) exp_out = np.zeros_like(data) exp_out[:-1, :-1, :-1] = data[1:, 1:, 1:] assert_almost_equal(out.dataobj, exp_out) out = resample_from_to(img, trans_img) trans_exp_out = np.zeros_like(data) trans_exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1] assert_almost_equal(out.dataobj, trans_exp_out) # Test mode with translation of first axis only # Default 'constant' mode first trans1_aff = from_matvec(np.diag([-4, 5, 6]), [4, 0, 0]) trans1_img = Nifti1Image(data, trans1_aff) out = resample_from_to(img, trans1_img) exp_out = np.zeros_like(data) exp_out[1:, :, :] = data[:-1, :, :] assert_almost_equal(out.dataobj, exp_out) # Then 'nearest' mode out = resample_from_to(img, trans1_img, mode='nearest') exp_out[0, :, :] = exp_out[1, :, :] assert_almost_equal(out.dataobj, exp_out) # Test order trans_p_25_aff = from_matvec(np.diag([-4, 5, 6]), [1, 0, 0]) trans_p_25_img = Nifti1Image(data, trans_p_25_aff) # Suprising to me, but all points outside are set to 0, even with NN out = resample_from_to(img, trans_p_25_img, order=0) exp_out = np.zeros_like(data) exp_out[1:, :, :] = data[1, :, :] assert_almost_equal(out.dataobj, exp_out) out = resample_from_to(img, trans_p_25_img) exp_out = spnd.affine_transform(data, [1, 1, 1], [-0.25, 0, 0], order=3) assert_almost_equal(out.dataobj, exp_out) # Test cval out = resample_from_to(img, trans_img, cval=99) exp_out = np.zeros_like(data) + 99 exp_out[1:, 1:, 1:] = data[:-1, :-1, :-1] assert_almost_equal(out.dataobj, exp_out) # Out class out = resample_from_to(img, trans_img) assert_equal(out.__class__, Nifti1Image) # By default, type of from_img makes no difference n1_img = Nifti2Image(data, affine) out = resample_from_to(n1_img, trans_img) assert_equal(out.__class__, Nifti1Image) # Passed as keyword arg out = resample_from_to(img, trans_img, out_class=Nifti2Image) assert_equal(out.__class__, Nifti2Image) # If keyword arg is None, use type of from_img out = resample_from_to(n1_img, trans_img, out_class=None) assert_equal(out.__class__, Nifti2Image) # to_img type irrelevant in all cases n1_trans_img = Nifti2Image(data, trans_aff) out = resample_from_to(img, n1_trans_img, out_class=None) assert_equal(out.__class__, Nifti1Image) # From 2D to 3D, error, the fixed affine is not invertible img_2d = Nifti1Image(data[:, :, 0], affine) assert_raises(AffineError, resample_from_to, img_2d, img) # 3D to 2D, we don't need to invert the fixed matrix out = resample_from_to(img, img_2d) assert_array_equal(out.dataobj, data[:, :, 0]) # Same for tuple as to_img imput out = resample_from_to(img, (img_2d.shape, img_2d.affine)) assert_array_equal(out.dataobj, data[:, :, 0]) # 4D input and output also OK data_4d = np.arange(24 * 5).reshape((2, 3, 4, 5)) img_4d = Nifti1Image(data_4d, affine) out = resample_from_to(img_4d, img_4d) assert_almost_equal(data_4d, out.dataobj) assert_array_equal(img_4d.affine, out.affine) # Errors trying to match 3D to 4D assert_raises(ValueError, resample_from_to, img_4d, img) assert_raises(ValueError, resample_from_to, img, img_4d)