def test_inverse(self, device): img_t = torch.rand((1, 10, 9, 8), dtype=torch.float32, device=device) affine = torch.tensor( [[0, 0, -1, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]], dtype=torch.float32, device="cpu" ) meta = {"fname": "somewhere"} img = MetaTensor(img_t, affine=affine, meta=meta) tr = Orientation("LPS") # check that image and affine have changed img = tr(img) self.assertNotEqual(img.shape, img_t.shape) self.assertGreater((affine - img.affine).max(), 0.5) # check that with inverse, image affine are back to how they were img = tr.inverse(img) self.assertEqual(img.shape, img_t.shape) self.assertLess((affine - img.affine).max(), 1e-2)
def test_consistency(self): np.set_printoptions(suppress=True, precision=3) test_image = make_nifti_image( np.arange(64).reshape(1, 8, 8), np.diag([1.5, 1.5, 1.5, 1])) data, header = LoadImage(reader="NibabelReader", as_closest_canonical=False)(test_image) data, original_affine, new_affine = Spacing([0.8, 0.8, 0.8])(data[None], header["affine"], mode="nearest") data, _, new_affine = Orientation("ILP")(data, new_affine) if os.path.exists(test_image): os.remove(test_image) write_nifti(data[0], test_image, new_affine, original_affine, mode="nearest", padding_mode="border") saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image) write_nifti( data[0], test_image, new_affine, original_affine, mode="nearest", padding_mode="border", output_spatial_shape=(1, 8, 8), ) saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image) # test the case that only correct orientation but don't resample write_nifti(data[0], test_image, new_affine, original_affine, resample=False) saved = nib.load(test_image) # compute expected affine start_ornt = nib.orientations.io_orientation(new_affine) target_ornt = nib.orientations.io_orientation(original_affine) ornt_transform = nib.orientations.ornt_transform( start_ornt, target_ornt) data_shape = data[0].shape expected_affine = new_affine @ nib.orientations.inv_ornt_aff( ornt_transform, data_shape) np.testing.assert_allclose(saved.affine, expected_affine) if os.path.exists(test_image): os.remove(test_image)
def test_consistency(self): np.set_printoptions(suppress=True, precision=3) test_image = make_nifti_image(np.arange(64).reshape(1, 8, 8), np.diag([1.5, 1.5, 1.5, 1])) data, header = LoadNifti(as_closest_canonical=False)(test_image) data, original_affine, new_affine = Spacing([0.8, 0.8, 0.8])( data[None], header["affine"], interp_order="nearest" ) data, _, new_affine = Orientation("ILP")(data, new_affine) if os.path.exists(test_image): os.remove(test_image) write_nifti(data[0], test_image, new_affine, original_affine, interp_order="nearest", mode="border") saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image) write_nifti( data[0], test_image, new_affine, original_affine, interp_order="nearest", mode="border", output_shape=(1, 8, 8), ) saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image)
def test_inverse_array(self, use_compose, dtype, device): img: MetaTensor tr = Compose([ AddChannel(), Orientation("RAS"), Flip(1), Spacing([1.0, 1.2, 0.9], align_corners=False) ]) num_invertible = len( [i for i in tr.transforms if isinstance(i, InvertibleTransform)]) # forward img = tr(self.get_image(dtype, device)) self.assertEqual(len(img.applied_operations), num_invertible) # inverse with Compose if use_compose: img = tr.inverse(img) self.assertEqual(len(img.applied_operations), 0) # inverse individually else: _tr: InvertibleTransform num_to_inverse = num_invertible for _tr in tr.transforms[::-1]: if isinstance(_tr, InvertibleTransform): img = _tr.inverse(img) num_to_inverse -= 1 self.assertEqual(len(img.applied_operations), num_to_inverse)
def test_consistency(self): np.set_printoptions(suppress=True, precision=3) test_image = make_nifti_image( np.arange(64).reshape(1, 8, 8), np.diag([1.5, 1.5, 1.5, 1])) data, header = LoadImage(reader="NibabelReader", as_closest_canonical=False)(test_image) data, original_affine, new_affine = Spacing([0.8, 0.8, 0.8])(data[None], header["affine"], mode="nearest") data, _, new_affine = Orientation("ILP")(data, new_affine) if os.path.exists(test_image): os.remove(test_image) writer_obj = NibabelWriter() writer_obj.set_data_array(data[0], channel_dim=None) writer_obj.set_metadata(meta_dict={ "affine": new_affine, "original_affine": original_affine }, mode="nearest", padding_mode="border") writer_obj.write(test_image, verbose=True) saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image) writer_obj.set_data_array(data[0], channel_dim=None) writer_obj.set_metadata( meta_dict={ "affine": new_affine, "original_affine": original_affine, "spatial_shape": (1, 8, 8) }, mode="nearest", padding_mode="border", ) writer_obj.write(test_image, verbose=True) saved = nib.load(test_image) saved_data = saved.get_fdata() np.testing.assert_allclose(saved_data, np.arange(64).reshape(1, 8, 8), atol=1e-7) if os.path.exists(test_image): os.remove(test_image) # test the case no resample writer_obj.set_data_array(data[0], channel_dim=None) writer_obj.set_metadata(meta_dict={ "affine": new_affine, "original_affine": original_affine }, resample=False) writer_obj.write(test_image, verbose=True) saved = nib.load(test_image) np.testing.assert_allclose(saved.affine, new_affine) if os.path.exists(test_image): os.remove(test_image)
def test_ornt(self, init_param, img, data_param, expected_data, expected_code): ornt = Orientation(**init_param) res = ornt(img, **data_param) np.testing.assert_allclose(res[0], expected_data) original_affine = data_param['affine'] np.testing.assert_allclose(original_affine, res[1]) new_code = nib.orientations.aff2axcodes(res[2], labels=ornt.labels) self.assertEqual(''.join(new_code), expected_code)
def test_ornt(self, init_param, img, data_param, expected_data, expected_code): ornt = Orientation(**init_param) res = ornt(img, **data_param) if not isinstance(res, tuple): np.testing.assert_allclose(res, expected_data) return np.testing.assert_allclose(res[0], expected_data) original_affine = data_param["affine"] np.testing.assert_allclose(original_affine, res[1]) new_code = nib.orientations.aff2axcodes(res[2], labels=ornt.labels) self.assertEqual("".join(new_code), expected_code)
def test_ornt_meta( self, init_param, img: torch.Tensor, affine: torch.Tensor, expected_data: torch.Tensor, expected_code: str, device, ): img = MetaTensor(img, affine=affine).to(device) ornt = Orientation(**init_param) res: MetaTensor = ornt(img) assert_allclose(res, expected_data.to(device)) new_code = nib.orientations.aff2axcodes(res.affine.cpu(), labels=ornt.labels) self.assertEqual("".join(new_code), expected_code)
def test_invert(self): set_determinism(seed=0) im_fname = make_nifti_image(create_test_image_3d(101, 100, 107, noise_max=100)[1]) # label image, discrete data = [im_fname for _ in range(12)] transform = Compose( [ LoadImage(image_only=True), EnsureChannelFirst(), Orientation("RPS"), Spacing(pixdim=(1.2, 1.01, 0.9), mode="bilinear", dtype=np.float32), RandFlip(prob=0.5, spatial_axis=[1, 2]), RandAxisFlip(prob=0.5), RandRotate90(prob=0, spatial_axes=(1, 2)), RandZoom(prob=0.5, min_zoom=0.5, max_zoom=1.1, keep_size=True), RandRotate(prob=0.5, range_x=np.pi, mode="bilinear", align_corners=True, dtype=np.float64), RandAffine(prob=0.5, rotate_range=np.pi, mode="nearest"), ResizeWithPadOrCrop(100), CastToType(dtype=torch.uint8), ] ) # num workers = 0 for mac or gpu transforms num_workers = 0 if sys.platform != "linux" or torch.cuda.is_available() else 2 dataset = Dataset(data, transform=transform) self.assertIsInstance(transform.inverse(dataset[0]), MetaTensor) loader = DataLoader(dataset, num_workers=num_workers, batch_size=1) inverter = Invert(transform=transform, nearest_interp=True, device="cpu") for d in loader: d = decollate_batch(d) for item in d: orig = deepcopy(item) i = inverter(item) self.assertTupleEqual(orig.shape[1:], (100, 100, 100)) # check the nearest interpolation mode torch.testing.assert_allclose(i.to(torch.uint8).to(torch.float), i.to(torch.float)) self.assertTupleEqual(i.shape[1:], (100, 101, 107)) # check labels match reverted = i.detach().cpu().numpy().astype(np.int32) original = LoadImage(image_only=True)(data[-1]) n_good = np.sum(np.isclose(reverted, original.numpy(), atol=1e-3)) reverted_name = i.meta["filename_or_obj"] original_name = original.meta["filename_or_obj"] self.assertEqual(reverted_name, original_name) print("invert diff", reverted.size - n_good) self.assertTrue((reverted.size - n_good) < 300000, f"diff. {reverted.size - n_good}") set_determinism(seed=None)
def test_ornt_torch(self, init_param, img: torch.Tensor, track_meta: bool, device): set_track_meta(track_meta) ornt = Orientation(**init_param) img = img.to(device) expected_data = img.clone() expected_code = ornt.axcodes res = ornt(img) assert_allclose(res, expected_data) if track_meta: self.assertIsInstance(res, MetaTensor) new_code = nib.orientations.aff2axcodes(res.affine.cpu(), labels=ornt.labels) self.assertEqual("".join(new_code), expected_code) else: self.assertIsInstance(res, torch.Tensor) self.assertNotIsInstance(res, MetaTensor)
def test_bad_params(self, init_param, img, data_param): with self.assertRaises(ValueError): Orientation(**init_param)(img, **data_param)
from tests.utils import assert_allclose, download_url_or_skip_test, testing_data_config itk, has_itk = optional_import("itk") TINY_DIFF = 1e-4 keys = ("img1", "img2") key, key_1 = "ref_avg152T1_LR", "ref_avg152T1_RL" FILE_PATH = os.path.join(os.path.dirname(__file__), "testing_data", f"{key}.nii.gz") FILE_PATH_1 = os.path.join(os.path.dirname(__file__), "testing_data", f"{key_1}.nii.gz") TEST_CASES_ARRAY = [ [ Compose([Spacing(pixdim=(1.0, 1.1, 1.2)), Orientation(axcodes="RAS")]), {}, TINY_DIFF ], [ Compose([Orientation(axcodes="RAS"), Spacing(pixdim=(1.0, 1.1, 1.2))]), {}, TINY_DIFF ], ["CropForeground", { "k_divisible": 3 }, TINY_DIFF], ["BorderPad", { "spatial_border": (2, 3, 4) }, TINY_DIFF], ["CenterScaleCrop", { "roi_scale": (0.6, 0.7, 0.8) }, TINY_DIFF], ["CenterSpatialCrop", {
def test_bad_params(self, init_param, img: torch.Tensor, affine: torch.Tensor): img = MetaTensor(img, affine=affine) with self.assertRaises(ValueError): Orientation(**init_param)(img)