def test_matrix_to_images(self):
        # def matrix_to_images(data_matrix, mask):
        for img in self.imgs:
            imgmask = img > img.mean()
            data = img[imgmask]
            dataflat = data.reshape(1, -1)
            mat = np.vstack([dataflat, dataflat]).astype('float32')
            imglist = ants.matrix_to_images(mat, imgmask)
            nptest.assert_allclose((img * imgmask).numpy(), imglist[0].numpy())
            nptest.assert_allclose((img * imgmask).numpy(), imglist[1].numpy())
            self.assertTrue(
                ants.image_physical_space_consistency(img, imglist[0]))
            self.assertTrue(
                ants.image_physical_space_consistency(img, imglist[1]))

            # go back to matrix
            mat2 = ants.images_to_matrix(imglist, imgmask)
            nptest.assert_allclose(mat, mat2)

            # test with matrix.ndim > 2
            img = img.clone()
            img.set_direction(img.direction * 2)
            imgmask = img > img.mean()
            arr = (img * imgmask).numpy()
            arr = arr[arr > 0.5]
            arr2 = arr.copy()
            mat = np.stack([arr, arr2])
            imglist = ants.matrix_to_images(mat, imgmask)
            for im in imglist:
                self.assertTrue(ants.allclose(im, imgmask * img))
                self.assertTrue(
                    ants.image_physical_space_consistency(im, imgmask))
    def test_image_read_write(self):
        # def image_read(filename, dimension=None, pixeltype='float'):
        # def image_write(image, filename):

        # test scalar images
        for img in self.imgs:
            img = (img - img.min()) / (img.max() - img.min())
            img = img * 255.
            img = img.clone('unsigned char')
            for ptype in self.pixeltypes:
                img = img.clone(ptype)
                tmpfile = mktemp(suffix='.nii.gz')
                ants.image_write(img, tmpfile)

                img2 = ants.image_read(tmpfile)
                self.assertTrue(ants.image_physical_space_consistency(img,img2))
                self.assertEqual(img2.components, img.components)
                nptest.assert_allclose(img.numpy(), img2.numpy())

            # unsupported ptype
            with self.assertRaises(Exception):
                ants.image_read(tmpfile, pixeltype='not-suppoted-ptype')

        # test vector images
        for img in self.vecimgs:
            img = (img - img.min()) / (img.max() - img.min())
            img = img * 255.
            img = img.clone('unsigned char')
            for ptype in self.pixeltypes:
                img = img.clone(ptype)
                tmpfile = mktemp(suffix='.nii.gz')
                ants.image_write(img, tmpfile)

                img2 = ants.image_read(tmpfile)
                self.assertTrue(ants.image_physical_space_consistency(img,img2))
                self.assertEqual(img2.components, img.components)
                nptest.assert_allclose(img.numpy(), img2.numpy())

        # test saving/loading as npy
        for img in self.imgs:
            tmpfile = mktemp(suffix='.npy')
            ants.image_write(img, tmpfile)
            img2 = ants.image_read(tmpfile)

            self.assertTrue(ants.image_physical_space_consistency(img,img2))
            self.assertEqual(img2.components, img.components)
            nptest.assert_allclose(img.numpy(), img2.numpy())

            # with no json header
            arr = img.numpy()
            tmpfile = mktemp(suffix='.npy')
            np.save(tmpfile, arr)
            img2 = ants.image_read(tmpfile)
            nptest.assert_allclose(img.numpy(), img2.numpy())

        # non-existant file
        with self.assertRaises(Exception):
            tmpfile = mktemp(suffix='.nii.gz')
            ants.image_read(tmpfile)
    def test_copy_image_info(self):
        for img in self.imgs:
            img2 = img.clone()
            img2.set_spacing([6.9]*img.dimension)
            img2.set_origin([6.9]*img.dimension)
            self.assertTrue(not ants.image_physical_space_consistency(img,img2))

            img3 = ants.copy_image_info(reference=img, target=img2)
            self.assertTrue(ants.image_physical_space_consistency(img,img3))
    def test_make_image(self):
        self.setUp()

        for arr in self.arrs:
            voxval = 6.
            img = ants.make_image(arr.shape, voxval=voxval)
            self.assertTrue(img.dimension, arr.ndim)
            self.assertTrue(img.shape, arr.shape)
            nptest.assert_allclose(img.mean(), voxval)

            new_origin = tuple([6.9] * arr.ndim)
            new_spacing = tuple([3.6] * arr.ndim)
            new_direction = np.eye(arr.ndim) * 9.6
            img2 = ants.make_image(arr.shape,
                                   voxval=voxval,
                                   origin=new_origin,
                                   spacing=new_spacing,
                                   direction=new_direction)

            self.assertTrue(img2.dimension, arr.ndim)
            self.assertTrue(img2.shape, arr.shape)
            nptest.assert_allclose(img2.mean(), voxval)
            self.assertEqual(img2.origin, new_origin)
            self.assertEqual(img2.spacing, new_spacing)
            nptest.assert_allclose(img2.direction, new_direction)

            for ptype in self.pixeltypes:
                img = ants.make_image(arr.shape, voxval=1., pixeltype=ptype)
                self.assertEqual(img.pixeltype, ptype)

        # test with components
        img = ants.make_image((69, 70, 4), has_components=True)
        self.assertEqual(img.components, 4)
        self.assertEqual(img.dimension, 2)
        nptest.assert_allclose(img.mean(), 0.)

        img = ants.make_image((69, 70, 71, 4), has_components=True)
        self.assertEqual(img.components, 4)
        self.assertEqual(img.dimension, 3)
        nptest.assert_allclose(img.mean(), 0.)

        # set from image
        for img in self.imgs:
            mask = img > img.mean()
            arr = img[mask]
            img2 = ants.make_image(mask, voxval=arr)
            nptest.assert_allclose(img2.numpy(), (img * mask).numpy())
            self.assertTrue(ants.image_physical_space_consistency(img2, mask))

            # set with arr.ndim > 1
            img2 = ants.make_image(mask, voxval=np.expand_dims(arr, -1))
            nptest.assert_allclose(img2.numpy(), (img * mask).numpy())
            self.assertTrue(ants.image_physical_space_consistency(img2, mask))
    def test_images_to_matrix(self):
        # def images_to_matrix(image_list, mask=None, sigma=None, epsilon=0):
        for img in self.imgs:
            mask = img > img.mean()
            imglist = [img.clone(), img.clone(), img.clone()]
            imgmat = ants.images_to_matrix(imglist, mask=mask)
            self.assertTrue(imgmat.shape[0] == len(imglist))
            self.assertTrue(imgmat.shape[1] == (mask > 0).sum())

            # go back to images
            imglist2 = ants.matrix_to_images(imgmat, mask)
            for i1, i2 in zip(imglist, imglist2):
                self.assertTrue(ants.image_physical_space_consistency(i1, i2))
                nptest.assert_allclose(i1.numpy() * mask.numpy(), i2.numpy())

            if img.dimension == 2:
                # with sigma
                mask = img > img.mean()
                imglist = [img.clone(), img.clone(), img.clone()]
                imgmat = ants.images_to_matrix(imglist, mask=mask, sigma=2.)

                # with no mask
                mask = img > img.mean()
                imglist = [img.clone(), img.clone(), img.clone()]
                imgmat = ants.images_to_matrix(imglist)

                # with mask of different shape
                s = [65] * img.dimension
                mask2 = ants.from_numpy(np.random.randn(*s))
                mask2 = mask2 > mask2.mean()
                imgmat = ants.images_to_matrix(imglist, mask=mask2)
    def test_new_image_like(self):
        #self.setUp()
        for img in self.imgs:
            myarray = img.numpy()
            myarray *= 6.9
            imgnew = img.new_image_like(myarray)
            # test physical space consistency
            self.assertTrue(ants.image_physical_space_consistency(img, imgnew))
            # test data
            nptest.assert_allclose(myarray, imgnew.numpy())
            nptest.assert_allclose(myarray, img.numpy()*6.9)

            # test exceptions
            with self.assertRaises(Exception):
                # not ndarray
                new_data = img.clone()
                img.new_image_like(new_data)
            with self.assertRaises(Exception):
                # wrong shape
                new_data = np.random.randn(69,12,21).astype('float32')
                img.new_image_like(new_data)

        with self.assertRaises(Exception):
            # wrong shape with components
            vecimg = ants.from_numpy(np.random.randn(69,12,3).astype('float32'), has_components=True)
            new_data = np.random.randn(69,12,4).astype('float32')
            vecimg.new_image_like(new_data)
Exemple #7
0
 def test_nibabel(self):
     fn = ants.get_ants_data('mni')
     ants_img = ants.image_read(fn)
     nii_mni = nib.load(fn)
     ants_mni = ants_img.to_nibabel()
     self.assertTrue((ants_mni.get_qform() == nii_mni.get_qform()).all())
     temp = ants.from_nibabel(nii_mni)
     self.assertTrue(ants.image_physical_space_consistency(ants_img, temp))
    def test__ne__(self):
        #self.setUp()
        for img in self.imgs:
            img2 = (img != 6.9)
            self.assertTrue(ants.image_physical_space_consistency(img, img2))
            nptest.assert_allclose(img2.numpy(), (img.numpy()!=6.9).astype('int'))

            # op on another image
            img2 = img != img.clone()
            self.assertTrue(ants.image_physical_space_consistency(img, img2))
            nptest.assert_allclose(img2.numpy(), img.numpy()!=img.numpy())

            with self.assertRaises(Exception):
                # different physical space
                img2 = img.clone()
                img2.set_spacing([2.31]*img.dimension)
                img3 = img != img2
    def test__pow__(self):
        #self.setUp()
        for img in self.imgs:
            # op on constant
            img2 = img ** 6.9
            self.assertTrue(ants.image_physical_space_consistency(img, img2))
            nptest.assert_allclose(img2.numpy(), img.numpy()**6.9)

            # op on another image
            img2 = img ** img.clone()
            self.assertTrue(ants.image_physical_space_consistency(img, img2))
            nptest.assert_allclose(img2.numpy(), img.numpy()**img.numpy())

            with self.assertRaises(Exception):
                # different physical space
                img2 = img.clone()
                img2.set_spacing([2.31]*img.dimension)
                img3 = img ** img2
Exemple #10
0
    def test_Rotate3D(self):
        for img in self.imgs_3d:
            imgclone = img.clone()
            tx = ants.contrib.Rotate3D((10, -5, 12))
            img_zoom = tx.transform(img)

            # physical space shouldnt change .. ?
            self.assertTrue(
                ants.image_physical_space_consistency(img, img_zoom))
            # assert no unintended changes to passed-in img
            self.assertTrue(
                ants.image_physical_space_consistency(img, imgclone))
            self.assertTrue(ants.allclose(img, imgclone))

            # apply to cloned image to ensure deterministic nature
            img_zoom2 = tx.transform(imgclone)
            self.assertTrue(
                ants.image_physical_space_consistency(img_zoom, img_zoom2))
            self.assertTrue(ants.allclose(img_zoom, img_zoom2))
    def test_image_clone(self):
        for img in self.imgs:
            img = ants.image_clone(img, 'unsigned char')
            orig_ptype = img.pixeltype
            for ptype in self.pixeltypes:
                imgcloned = ants.image_clone(img, ptype)
                self.assertTrue(ants.image_physical_space_consistency(img,imgcloned))
                nptest.assert_allclose(img.numpy(), imgcloned.numpy())
                self.assertEqual(imgcloned.pixeltype, ptype)
                self.assertEqual(img.pixeltype, orig_ptype)

        for img in self.vecimgs:
            img = img.clone('unsigned char')
            orig_ptype = img.pixeltype
            for ptype in self.pixeltypes:
                imgcloned = ants.image_clone(img, ptype)
                self.assertTrue(ants.image_physical_space_consistency(img,imgcloned))
                self.assertEqual(imgcloned.components, img.components)
                nptest.assert_allclose(img.numpy(), imgcloned.numpy())
                self.assertEqual(imgcloned.pixeltype, ptype)
                self.assertEqual(img.pixeltype, orig_ptype)
    def test_to_file(self):
        #self.setUp()
        for img in self.imgs:
            filename = mktemp(suffix='.nii.gz')
            img.to_file(filename)
            # test that file now exists
            self.assertTrue(os.path.exists(filename))
            img2 = ants.image_read(filename)
            # test physical space and data
            self.assertTrue(ants.image_physical_space_consistency(img, img2))
            nptest.assert_allclose(img.numpy(), img2.numpy())

            try:
                os.remove(filename)
            except:
                pass
    def test_clone(self):
        #self.setUp()
        for img in self.imgs:
            orig_ptype = img.pixeltype
            for ptype in self.pixeltypes:
                imgclone = img.clone(ptype)

                self.assertEqual(imgclone.pixeltype, ptype)
                self.assertEqual(img.pixeltype, orig_ptype)
                # test physical space consistency
                self.assertTrue(ants.image_physical_space_consistency(img, imgclone))
                if ptype == orig_ptype:
                    # test that they dont share image pointer
                    view1 = img.view()
                    view1 *= 6.9
                    nptest.assert_allclose(view1, imgclone.numpy()*6.9)
def randomly_transform_image_data(
        reference_image,
        input_image_list,
        segmentation_image_list=None,
        number_of_simulations=10,
        transform_type='affine',
        sd_affine=0.02,
        deformation_transform_type="bspline",
        number_of_random_points=1000,
        sd_noise=10.0,
        number_of_fitting_levels=4,
        mesh_size=1,
        sd_smoothing=4.0,
        input_image_interpolator='linear',
        segmentation_image_interpolator='nearestNeighbor'):
    """
    Randomly transform image data (optional: with corresponding segmentations).

    Apply rigid, affine and/or deformable maps to an input set of training
    images.  The reference image domain defines the space in which this 
    happens.

    Arguments
    ---------
    reference_image : ANTsImage
        Defines the spatial domain for all output images.  If the input images do 
        not match the spatial domain of the reference image, we internally 
        resample the target to the reference image.  This could have unexpected 
        consequences.  Resampling to the reference domain is performed by testing 
        using ants.image_physical_space_consistency then calling 
        ants.resample_image_to_target with failure.

    input_image_list : list of lists of ANTsImages
        List of lists of input images to warp.  The internal list sets contain one 
        or more images (per subject) which are assumed to be mutually aligned.  The 
        outer list contains multiple subject lists which are randomly sampled to 
        produce output image list.
        
    segmentation_image_list : list of ANTsImages
        List of segmentation images corresponding to the input image list (optional).

    number_of_simulations : integer
        Number of output images. 

    transform_type : string
        One of the following options: "translation", "rigid", "scaleShear", "affine",
        "deformation", "affineAndDeformation".

    sd_affine : float
        Parameter dictating deviation amount from identity for random linear 
        transformations.

    deformation_transform_type : string
        "bspline" or "exponential".

    number_of_random_points : integer
        Number of displacement points for the deformation field.

    sd_noise : float
        Standard deviation of the displacement field.

    number_of_fitting_levels : integer
        Number of fitting levels (bspline deformation only).    

    mesh_size : int or n-D tuple
        Determines fitting resolution (bspline deformation only).    

    sd_smoothing : float 
        Standard deviation of the Gaussian smoothing in mm (exponential field only).

    input_image_interpolator : string
        One of the following options "linear", "gaussian", "bspline".

    segmentation_image_interpolator : string
        One of the following options "nearestNeighbor" or "genericLabel".

    Returns
    -------
    list of lists of transformed images

    Example
    -------
    >>> import ants
    >>> image1_list = list()
    >>> image1_list.append(ants.image_read(ants.get_ants_data("r16")))
    >>> image2_list = list()
    >>> image2_list.append(ants.image_read(ants.get_ants_data("r64"))) 
    >>> input_segmentations = list()
    >>> input_segmentations.append(ants.threshold_image(image1, "Otsu", 3))
    >>> input_segmentations.append(ants.threshold_image(image2, "Otsu", 3))
    >>> input_images = list()
    >>> input_images.append(image1_list)
    >>> input_images.append(image2_list)
    >>> data = antspynet.randomly_transform_image_data(image1, 
    >>>     input_images, input_segmentations, sd_affine=0.02,
    >>>     transform_type = "affineAndDeformation" )
    """
    def polar_decomposition(X):
        U, d, V = np.linalg.svd(X, full_matrices=False)
        P = np.matmul(U, np.matmul(np.diag(d), np.transpose(U)))
        Z = np.matmul(U, np.transpose(V))
        if np.linalg.det(Z) < 0:
            Z = -Z
        return ({"P": P, "Z": Z, "Xtilde": np.matmul(P, Z)})

    def create_random_linear_transform(image,
                                       fixed_parameters,
                                       transform_type='affine',
                                       sd_affine=1.0):
        transform = ants.create_ants_transform(
            transform_type="AffineTransform",
            precision='float',
            dimension=image.dimension)
        ants.set_ants_transform_fixed_parameters(transform, fixed_parameters)
        identity_parameters = ants.get_ants_transform_parameters(transform)
        random_epsilon = np.random.normal(loc=0,
                                          scale=sd_affine,
                                          size=len(identity_parameters))

        if transform_type == 'translation':
            random_epsilon[:(len(identity_parameters) - image.dimension)] = 0

        random_parameters = identity_parameters + random_epsilon
        random_matrix = np.reshape(
            random_parameters[:(len(identity_parameters) - image.dimension)],
            newshape=(image.dimension, image.dimension))
        decomposition = polar_decomposition(random_matrix)

        if transform_type == "rigid":
            random_matrix = decomposition['Z']
        elif transform_type == "affine":
            random_matrix = decomposition['Xtilde']
        elif transform_type == "scaleShear":
            random_matrix = decomposition['P']

        random_parameters[:(len(identity_parameters) - image.dimension)] = \
            np.reshape(random_matrix, newshape=(len(identity_parameters) - image.dimension))
        ants.set_ants_transform_parameters(transform, random_parameters)
        return (transform)

    def create_random_displacement_field_transform(
            image,
            field_type="bspline",
            number_of_random_points=1000,
            sd_noise=10.0,
            number_of_fitting_levels=4,
            mesh_size=1,
            sd_smoothing=4.0):
        displacement_field = ants.simulate_displacement_field(
            image,
            field_type=field_type,
            number_of_random_points=number_of_random_points,
            sd_noise=sd_noise,
            enforce_stationary_boundary=True,
            number_of_fitting_levels=number_of_fitting_levels,
            mesh_size=mesh_size,
            sd_smoothing=sd_smoothing)
        return (ants.transform_from_displacement_field(displacement_field))

    admissible_transforms = ("translation", "rigid", "scaleShear", "affine",
                             "affineAndDeformation", "deformation")
    if not transform_type in admissible_transforms:
        raise ValueError(
            "The specified transform is not a possible option.  Please see help menu."
        )

    # Get the fixed parameters from the reference image.

    fixed_parameters = ants.get_center_of_mass(reference_image)
    number_of_subjects = len(input_image_list)

    random_indices = np.random.choice(number_of_subjects,
                                      size=number_of_simulations,
                                      replace=True)

    simulated_image_list = list()
    simulated_segmentation_image_list = list()
    simulated_transforms = list()

    for i in range(number_of_simulations):
        single_subject_image_list = input_image_list[random_indices[i]]
        single_subject_segmentation_image = None
        if segmentation_image_list is not None:
            single_subject_segmentation_image = segmentation_image_list[
                random_indices[i]]

        if ants.image_physical_space_consistency(
                reference_image, single_subject_image_list[0]) is False:
            for j in range(len(single_subject_image_list)):
                single_subject_image_list.append(
                    ants.resample_image_to_target(
                        single_subject_image_list[j],
                        reference_image,
                        interp_type=input_image_interpolator))
            if single_subject_segmentation_image is not None:
                single_subject_segmentation_image = \
                    ants.resample_image_to_target(single_subject_segmentation_image, reference_image,
                        interp_type=segmentation_image_interpolator)

        transforms = list()

        if transform_type == 'deformation':
            deformable_transform = create_random_displacement_field_transform(
                reference_image, deformation_transform_type,
                number_of_random_points, sd_noise, number_of_fitting_levels,
                mesh_size, sd_smoothing)
            transforms.append(deformable_transform)
        elif transform_type == 'affineAndDeformation':
            deformable_transform = create_random_displacement_field_transform(
                reference_image, deformation_transform_type,
                number_of_random_points, sd_noise, number_of_fitting_levels,
                mesh_size, sd_smoothing)
            linear_transform = create_random_linear_transform(
                reference_image, fixed_parameters, 'affine', sd_affine)
            transforms.append(deformable_transform)
            transforms.append(linear_transform)
        else:
            linear_transform = create_random_linear_transform(
                reference_image, fixed_parameters, transform_type, sd_affine)
            transforms.append(linear_transform)

        simulated_transforms.append(ants.compose_ants_transforms(transforms))

        single_subject_simulated_image_list = list()
        for j in range(len(single_subject_image_list)):
            single_subject_simulated_image_list.append(
                ants.apply_ants_transform_to_image(
                    simulated_transforms[i],
                    single_subject_image_list[j],
                    reference=reference_image))

        simulated_image_list.append(single_subject_simulated_image_list)

        if single_subject_segmentation_image is not None:
            simulated_segmentation_image_list.append(
                ants.apply_ants_transform_to_image(
                    simulated_transforms[i],
                    single_subject_segmentation_image,
                    reference=reference_image))

    if segmentation_image_list is None:
        return ({
            'simulated_images': simulated_image_list,
            'simulated_transforms': simulated_transforms
        })
    else:
        return ({
            'simulated_images': simulated_image_list,
            'simulated_segmentation_images': simulated_segmentation_image_list,
            'simulated_transforms': simulated_transforms
        })
    def test_image_physical_spacing_consistency(self):
        for img in self.imgs:
            self.assertTrue(ants.image_physical_space_consistency(img,img))
            self.assertTrue(ants.image_physical_space_consistency(img,img,datatype=True))
            clonetype = 'float' if img.pixeltype != 'float' else 'unsigned int'
            img2 = img.clone(clonetype)
            self.assertTrue(ants.image_physical_space_consistency(img,img2))
            self.assertTrue(not ants.image_physical_space_consistency(img,img2,datatype=True))

            # test incorrectness #
            # bad spacing
            img2 = img.clone()
            img2.set_spacing([6.96]*img.dimension)
            self.assertTrue(not ants.image_physical_space_consistency(img,img2))

            # bad origin
            img2 = img.clone()
            img2.set_origin([6.96]*img.dimension)
            self.assertTrue(not ants.image_physical_space_consistency(img,img2))

            # bad direction
            img2 = img.clone()
            img2.set_direction(img.direction*2)
            self.assertTrue(not ants.image_physical_space_consistency(img,img2))

            # bad dimension
            ndim = img.dimension
            img2 = ants.from_numpy(np.random.randn(*tuple([69]*(ndim+1))).astype('float32'))
            self.assertTrue(not ants.image_physical_space_consistency(img,img2))

            # only one image
            with self.assertRaises(Exception):
                ants.image_physical_space_consistency(img)
            # not an ANTsImage
            with self.assertRaises(Exception):
                ants.image_physical_space_consistency(img, 12)

        # false because of components
        vecimg = ants.from_numpy(np.random.randn(69,70,3), has_components=True)
        vecimg2 = ants.from_numpy(np.random.randn(69,70,4), has_components=True)
        self.assertTrue(not ants.image_physical_space_consistency(vecimg, vecimg2, datatype=True))
 def test_apply(self):
     #self.setUp()
     for img in self.imgs:
         img2 = img.apply(lambda x: x*6.9)
         self.assertTrue(ants.image_physical_space_consistency(img, img2))
         nptest.assert_allclose(img2.numpy(), img.numpy()*6.9)