def test_use_case(self):
        with tempfile.TemporaryDirectory() as tempdir:
            img_ = nib.Nifti1Image(np.random.randint(0, 2, size=(20, 20, 20)),
                                   np.eye(4))
            seg_ = nib.Nifti1Image(np.random.randint(0, 2, size=(20, 20, 20)),
                                   np.eye(4))
            img_name, seg_name = os.path.join(tempdir,
                                              "img.nii.gz"), os.path.join(
                                                  tempdir, "seg.nii.gz")
            nib.save(img_, img_name)
            nib.save(seg_, seg_name)
            img_list, seg_list = [img_name], [seg_name]

            img_xform = _TestCompose([
                EnsureChannelFirst(),
                Spacing(pixdim=(1.5, 1.5, 3.0)),
                RandAdjustContrast()
            ])
            seg_xform = _TestCompose([
                EnsureChannelFirst(),
                Spacing(pixdim=(1.5, 1.5, 3.0), mode="nearest")
            ])
            img_dataset = ImageDataset(
                image_files=img_list,
                seg_files=seg_list,
                transform=img_xform,
                seg_transform=seg_xform,
                image_only=False,
                transform_with_metadata=True,
            )
            self.assertTupleEqual(img_dataset[0][0].shape, (1, 14, 14, 7))
            self.assertTupleEqual(img_dataset[0][1].shape, (1, 14, 14, 7))
Beispiel #2
0
    def test_spacing(self, in_type, init_param, img, data_param, expected_output):
        _img = in_type(img)
        output_data, _, new_affine = Spacing(**init_param)(_img, **data_param)
        if isinstance(_img, torch.Tensor):
            self.assertEqual(_img.device, output_data.device)
            output_data = output_data.cpu()

        np.testing.assert_allclose(output_data, expected_output, atol=1e-3, rtol=1e-3)
        sr = len(output_data.shape) - 1
        if isinstance(init_param["pixdim"], float):
            init_param["pixdim"] = [init_param["pixdim"]] * sr
        init_pixdim = ensure_tuple(init_param["pixdim"])
        init_pixdim = init_param["pixdim"][:sr]
        norm = np.sqrt(np.sum(np.square(new_affine), axis=0))[:sr]
        np.testing.assert_allclose(fall_back_tuple(init_pixdim, norm), norm)
Beispiel #3
0
 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)
Beispiel #4
0
 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)
Beispiel #5
0
    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)
Beispiel #6
0
    def __call__(
        self, data: Mapping[Union[Hashable, str], Dict[str, np.ndarray]]
    ) -> Dict[Union[Hashable, str], Union[np.ndarray, Dict[str, np.ndarray]]]:
        d = dict(data)
        for idx, key in enumerate(self.keys):
            meta_data = d[f"{key}_{self.meta_key_postfix}"]
            # set pixdim to original pixdim value where required
            current_pixdim = copy.deepcopy(self.pixdim)
            original_pixdim = meta_data["pixdim"]
            old_pixdim = original_pixdim[1:4]
            current_pixdim[self.dim_to_keep] = old_pixdim[self.dim_to_keep]

            # apply the transform
            spacing_transform = Spacing(current_pixdim, diagonal=self.diagonal)

            # resample array of each corresponding key
            # using affine fetched from d[affine_key]
            d[key], _, new_affine = spacing_transform(
                data_array=d[key],
                affine=meta_data["affine"],
                mode=self.mode[idx],
                padding_mode=self.padding_mode[idx],
                align_corners=self.align_corners[idx],
                dtype=self.dtype[idx],
            )

            # store the modified affine
            meta_data["affine"] = new_affine
        return d
Beispiel #7
0
 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)
Beispiel #8
0
 def test_spacing(self, init_param, img, data_param, expected_output):
     res = Spacing(**init_param)(img, **data_param)
     np.testing.assert_allclose(res[0], expected_output, atol=1e-6)
     sr = len(res[0].shape) - 1
     if isinstance(init_param["pixdim"], float):
         init_param["pixdim"] = [init_param["pixdim"]] * sr
     init_pixdim = ensure_tuple(init_param["pixdim"])
     init_pixdim = init_param["pixdim"][:sr]
     np.testing.assert_allclose(init_pixdim[:sr], np.sqrt(np.sum(np.square(res[2]), axis=0))[:sr])
Beispiel #9
0
 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 = Spacing(pixdim=[1.1, 1.2, 0.9])
     # check that image and affine have changed
     img = tr(img)
     self.assertNotEqual(img.shape, img_t.shape)
     l2_norm_affine = ((affine - img.affine)**2).sum()**0.5
     self.assertGreater(l2_norm_affine, 5e-2)
     # check that with inverse, image affine are back to how they were
     img = tr.inverse(img)
     self.assertEqual(img.applied_operations, [])
     self.assertEqual(img.shape, img_t.shape)
     l2_norm_affine = ((affine - img.affine)**2).sum()**0.5
     self.assertLess(l2_norm_affine, 5e-2)
Beispiel #10
0
 def test_spacing_torch(self, pixdim, img, track_meta: bool):
     set_track_meta(track_meta)
     tr = Spacing(pixdim=pixdim)
     res = tr(img)
     if track_meta:
         self.assertIsInstance(res, MetaTensor)
         new_spacing = affine_to_spacing(res.affine, 3)
         assert_allclose(new_spacing, pixdim, type_test=False)
         self.assertNotEqual(img.shape, res.shape)
     else:
         self.assertIsInstance(res, torch.Tensor)
         self.assertNotIsInstance(res, MetaTensor)
         self.assertNotEqual(img.shape, res.shape)
     set_track_meta(True)
Beispiel #11
0
    def test_spacing(self, init_param, img, affine, data_param,
                     expected_output, device):
        img = MetaTensor(img, affine=affine).to(device)
        res: MetaTensor = Spacing(**init_param)(img, **data_param)
        self.assertEqual(img.device, res.device)

        assert_allclose(res, expected_output, atol=1e-1, rtol=1e-1)
        sr = min(len(res.shape) - 1, 3)
        if isinstance(init_param["pixdim"], float):
            init_param["pixdim"] = [init_param["pixdim"]] * sr
        init_pixdim = ensure_tuple(init_param["pixdim"])
        init_pixdim = init_param["pixdim"][:sr]
        norm = affine_to_spacing(res.affine, sr).cpu().numpy()
        assert_allclose(fall_back_tuple(init_pixdim, norm),
                        norm,
                        type_test=False)
Beispiel #12
0
    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)
Beispiel #13
0
]


class TestCompose(Compose):
    def __call__(self, input_):
        img, metadata = self.transforms[0](input_)
        img = self.transforms[1](img)
        img, _, _ = self.transforms[2](img, metadata["affine"])
        return self.transforms[3](img), metadata


TEST_CASE_3 = [
    TestCompose([
        LoadNifti(image_only=False),
        AddChannel(),
        Spacing(pixdim=(2, 2, 4)),
        RandAdjustContrast(prob=1.0)
    ]),
    TestCompose([
        LoadNifti(image_only=False),
        AddChannel(),
        Spacing(pixdim=(2, 2, 4)),
        RandAdjustContrast(prob=1.0)
    ]),
    (0, 2),
    (1, 64, 64, 33),
]

TEST_CASE_4 = [
    Compose([
        LoadNifti(image_only=True),
Beispiel #14
0
    Compose([LoadNifti(image_only=True), AddChannel(), RandAdjustContrast(prob=1.0)]),
    (0, 1),
    (1, 128, 128, 128),
]


class TestCompose(Compose):
    def __call__(self, input_):
        img, metadata = self.transforms[0](input_)
        img = self.transforms[1](img)
        img, _, _ = self.transforms[2](img, metadata["affine"])
        return self.transforms[3](img), metadata


TEST_CASE_3 = [
    TestCompose([LoadNifti(image_only=False), AddChannel(), Spacing(pixdim=(2, 2, 4)), RandAdjustContrast(prob=1.0)]),
    TestCompose([LoadNifti(image_only=False), AddChannel(), Spacing(pixdim=(2, 2, 4)), RandAdjustContrast(prob=1.0)]),
    (0, 2),
    (1, 64, 64, 33),
]

TEST_CASE_4 = [
    Compose([LoadNifti(image_only=True), AddChannel(), RandGaussianNoise(prob=1.0)]),
    (1, 128, 128, 128),
]


class TestArrayDataset(unittest.TestCase):
    @parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_3])
    def test_shape(self, img_transform, label_transform, indexes, expected_shape):
        test_image = nib.Nifti1Image(np.random.randint(0, 2, size=(128, 128, 128)), np.eye(4))
Beispiel #15
0
from monai.utils import convert_data_type, optional_import
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],
Beispiel #16
0
 def test_ill_pixdim(self):
     with self.assertRaises(ValueError):
         Spacing(pixdim=(-1, 2.0))(np.zeros((1, 1)))