Esempio n. 1
0
def register_com(vol_a: Volume, vol_b: Volume) -> Tuple[Volume, Volume]:
    """
    Perform center-of-mass registration on two volumes

    :param vol_a: The fixed volume
    :param vol_b: The moving volume
    :return: The updated volumes
    """
    from dipy.align.imaffine import transform_centers_of_mass

    affine = transform_centers_of_mass(vol_a, vol_a.grid_to_world, vol_b,
                                       vol_b.grid_to_world)

    vol_b.world_transform[:] = np.array(affine.affine)
    return vol_a, vol_b
Esempio n. 2
0
def test_transform_centers_of_mass_3d():
    np.random.seed(1246592)
    shape = (64, 64, 64)
    rm = 8
    sp = vf.create_sphere(shape[0] // 2, shape[1] // 2, shape[2] // 2, rm)
    moving = np.zeros(shape)
    # The center of mass will be (16, 16, 16), in image coordinates
    moving[:shape[0] // 2, :shape[1] // 2, :shape[2] // 2] = sp[...]

    rs = 16
    # The center of mass will be (32, 32, 32), in image coordinates
    static = vf.create_sphere(shape[0], shape[1], shape[2], rs)

    # Create arbitrary image-to-space transforms
    axis = np.array([.5, 2.0, 1.5])
    t = 0.15  # translation factor
    trans = np.array([[1, 0, 0, -t * shape[0]],
                      [0, 1, 0, -t * shape[1]],
                      [0, 0, 1, -t * shape[2]],
                      [0, 0, 0, 1]])
    trans_inv = npl.inv(trans)

    for rotation_angle in [-1 * np.pi / 6.0, 0.0, np.pi / 5.0]:
        for scale_factor in [0.83, 1.3, 2.07]:  # scale
            rot = np.zeros(shape=(4, 4))
            rot[:3, :3] = geometry.rodrigues_axis_rotation(axis,
                                                           rotation_angle)
            rot[3, 3] = 1.0
            scale = np.array([[1 * scale_factor, 0, 0, 0],
                              [0, 1 * scale_factor, 0, 0],
                              [0, 0, 1 * scale_factor, 0],
                              [0, 0, 0, 1]])

            static_grid2world = trans_inv.dot(scale.dot(rot.dot(trans)))
            moving_grid2world = npl.inv(static_grid2world)

            # Expected translation
            c_static = static_grid2world.dot((32, 32, 32, 1))[:3]
            c_moving = moving_grid2world.dot((16, 16, 16, 1))[:3]
            expected = np.eye(4)
            expected[:3, 3] = c_moving - c_static

            # Implementation under test
            actual = imaffine.transform_centers_of_mass(static,
                                                        static_grid2world,
                                                        moving,
                                                        moving_grid2world)
            assert_array_almost_equal(actual.affine, expected)
Esempio n. 3
0
def mutualInfo_dipy(img1, img2):
    img1_grid2world = np.identity(3)
    img2_grid2world = np.identity(3)

    # compute center of mass
    c_of_mass = transform_centers_of_mass(img1, img1_grid2world, img2,
                                          img2_grid2world)

    x_shift = c_of_mass.affine[1, -1]
    y_shift = c_of_mass.affine[0, -1]

    # prepare affine registration
    nbins = 32
    sampling_prop = None
    metric = MutualInformationMetric(nbins, sampling_prop)
    level_iters = [10000, 1000, 100]
    sigmas = [3.0, 1.0, 0.0]
    factors = [4, 2, 1]
    affreg = AffineRegistration(metric=metric,
                                level_iters=level_iters,
                                sigmas=sigmas,
                                factors=factors)

    # translation
    translation = affreg.optimize(img1,
                                  img2,
                                  TranslationTransform2D(),
                                  None,
                                  img1_grid2world,
                                  img2_grid2world,
                                  starting_affine=c_of_mass.affine)

    # rotation
    # ~ rigid = affreg.optimize(im1, im2, RigidTransform2D(), None,
    # ~ im1_grid2world, im2_grid2world,
    # ~ starting_affine=translation.affine)
    # ~ transformed = rigid.transform(im2)

    # ~ # resize, shear
    # ~ affine = affreg.optimize(im1, im2, AffineTransform2D(), None,
    # ~ im1_grid2world, im2_grid2world,
    # ~ starting_affine=rigid.affine)

    x_shift = translation.affine[1, -1]
    y_shift = translation.affine[0, -1]

    return np.asarray([-x_shift, -y_shift])
Esempio n. 4
0
    def center_of_mass(self, static, static_grid2world,
                       moving, moving_grid2world):

        """ Function for the center of mass based image registration.

        Parameters
        ----------
        static : 2D or 3D array
            the image to be used as reference during optimization.

        static_grid2world : array, shape (dim+1, dim+1), optional
            the voxel-to-space transformation associated with the static
            image. The default is None, implying the transform is the
            identity.

        moving : 2D or 3D array
            the image to be used as "moving" during optimization. It is
            necessary to pre-align the moving image to ensure its domain
            lies inside the domain of the deformation fields. This is assumed
            to be accomplished by "pre-aligning" the moving image towards the
            static using an affine transformation given by the
            'starting_affine' matrix

        moving_grid2world : array, shape (dim+1, dim+1), optional
            the voxel-to-space transformation associated with the moving
            image. The default is None, implying the transform is the
            identity.

        """

        img_registration = transform_centers_of_mass(static,
                                                     static_grid2world,
                                                     moving,
                                                     moving_grid2world)

        transformed = img_registration.transform(moving)
        return transformed, img_registration.affine
Esempio n. 5
0
.. figure:: resampled_0.png
   :align: center
.. figure:: resampled_1.png
   :align: center
.. figure:: resampled_2.png
   :align: center

   Input images before alignment.
"""

"""
We can obtain a very rough (and fast) registration by just aligning the centers
of mass of the two images
"""

c_of_mass = transform_centers_of_mass(static, static_grid2world,
                                      moving, moving_grid2world)

"""
We can now transform the moving image and draw it on top of the static image,
registration is not likely to be good, but at least they will occupy roughly
the same space
"""

transformed = c_of_mass.transform(moving)
regtools.overlay_slices(static, transformed, None, 0,
                        "Static", "Transformed", "transformed_com_0.png")
regtools.overlay_slices(static, transformed, None, 1,
                        "Static", "Transformed", "transformed_com_1.png")
regtools.overlay_slices(static, transformed, None, 2,
                        "Static", "Transformed", "transformed_com_2.png")
Esempio n. 6
0
def _compute_morph_sdr(mri_from, mri_to, niter_affine=(100, 100, 10),
                       niter_sdr=(5, 5, 3), zooms=(5., 5., 5.)):
    """Get a matrix that morphs data from one subject to another."""
    _check_dep(nibabel='2.1.0', dipy='0.10.1')
    import nibabel as nib
    with np.testing.suppress_warnings():
        from dipy.align import imaffine, imwarp, metrics, transforms
    from dipy.align.reslice import reslice

    logger.info('Computing nonlinear Symmetric Diffeomorphic Registration...')

    # use voxel size of mri_from
    if zooms is None:
        zooms = mri_from.header.get_zooms()[:3]
    zooms = np.atleast_1d(zooms).astype(float)
    if zooms.shape == (1,):
        zooms = np.repeat(zooms, 3)
    if zooms.shape != (3,):
        raise ValueError('zooms must be None, a singleton, or have shape (3,),'
                         ' got shape %s' % (zooms.shape,))

    # reslice mri_from
    mri_from_res, mri_from_res_affine = reslice(
        mri_from.get_data(), mri_from.affine, mri_from.header.get_zooms()[:3],
        zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_from = nib.Nifti1Image(mri_from_res, mri_from_res_affine)

    # reslice mri_to
    mri_to_res, mri_to_res_affine = reslice(
        mri_to.get_data(), mri_to.affine, mri_to.header.get_zooms()[:3],
        zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_to = nib.Nifti1Image(mri_to_res, mri_to_res_affine)

    affine = mri_to.affine
    mri_to = np.array(mri_to.dataobj, float)  # to ndarray
    mri_to /= mri_to.max()
    mri_from_affine = mri_from.affine  # get mri_from to world transform
    mri_from = np.array(mri_from.dataobj, float)  # to ndarray
    mri_from /= mri_from.max()  # normalize

    # compute center of mass
    c_of_mass = imaffine.transform_centers_of_mass(
        mri_to, affine, mri_from, affine)

    # set up Affine Registration
    affreg = imaffine.AffineRegistration(
        metric=imaffine.MutualInformationMetric(nbins=32),
        level_iters=list(niter_affine),
        sigmas=[3.0, 1.0, 0.0],
        factors=[4, 2, 1])

    # translation
    translation = affreg.optimize(
        mri_to, mri_from, transforms.TranslationTransform3D(), None, affine,
        mri_from_affine, starting_affine=c_of_mass.affine)

    # rigid body transform (translation + rotation)
    rigid = affreg.optimize(
        mri_to, mri_from, transforms.RigidTransform3D(), None,
        affine, mri_from_affine, starting_affine=translation.affine)

    # affine transform (translation + rotation + scaling)
    pre_affine = affreg.optimize(
        mri_to, mri_from, transforms.AffineTransform3D(), None,
        affine, mri_from_affine, starting_affine=rigid.affine)

    # compute mapping
    sdr = imwarp.SymmetricDiffeomorphicRegistration(
        metrics.CCMetric(3), list(niter_sdr))
    sdr_morph = sdr.optimize(mri_to, pre_affine.transform(mri_from))
    shape = tuple(sdr_morph.domain_shape)  # should be tuple of int
    logger.info('done.')
    return shape, zooms, affine, pre_affine, sdr_morph
def quick_check():

    img1_fname = "/home/omar/data/DATA_NeoBrainS12/T1.nii.gz"
    img2_fname = "/home/omar/data/DATA_NeoBrainS12/set2_i1_t1.nii.gz"

    img1_nib = nib.load(img1_fname)
    img1 = img1_nib.get_data().squeeze()
    img1_affine = img1_nib.get_affine()

    img2_nib = nib.load(img2_fname)
    img2 = img2_nib.get_data().squeeze()
    img2_affine = img2_nib.get_affine()
    # nib.aff2axcodes(img1_affine)
    #aff = AffineMap(None, img1.shape, img1_affine, img2.shape, img2_affine)
    #aff = transform_centers_of_mass(img1, img1_affine, img2, img2_affine)
    aff = dipy_align(img1, img1_affine, img2, img2_affine, np.eye(4))

    img2_resampled = aff.transform(img2)
    rt.overlay_slices(img1, img2_resampled, slice_type=0)
    rt.overlay_slices(img1, img2_resampled, slice_type=1)
    rt.overlay_slices(img1, img2_resampled, slice_type=2)



    # Verify that original and RAS versions of neo1 describe the same object

    # Load original data
    neo1_fname = get_neobrain('train', 1, 'T1')
    neo1_old, neo1_old_affine, neo1_old_spacing, neo1_old_ori = load_from_raw(neo1_fname)

    # Load RAS version
    neo1_nib = nib.load(neo1_fname)
    neo1 = neo1_nib.get_data()
    neo1_affine = neo1_nib.get_affine()

    # Resample RAS on top of original
    aff = AffineMap(None, neo1_old.shape, neo1_old_affine, neo1.shape, neo1_affine)
    neo1_resampled = aff.transform(neo1)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=0)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=1)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=2)


    # Attempt to resample a test volume on top of training
    neo2_fname = get_neobrain('test', 1, 'i1_t1')
    neo2_nib = nib.load(neo2_fname)
    neo2 = neo2_nib.get_data()
    neo2_affine = neo2_nib.get_affine()
    aff = transform_centers_of_mass(neo1, neo1_affine, neo2, neo2_affine)
    #aff = dipy_align(neo1, neo1_affine, neo2, neo2_affine)
    neo2_resampled = aff.transform(neo2)

    rt.overlay_slices(neo1, neo2_resampled, slice_type=0)
    rt.overlay_slices(neo1, neo2_resampled, slice_type=1)
    rt.overlay_slices(neo1, neo2_resampled, slice_type=2)



    # Load atlas
    atlas_fname = get_neobrain('atlas', 'neo-withSkull', None)
    atlas_nib = nib.load(atlas_fname)
    atlas_affine = atlas_nib.get_affine()
    atlas = atlas_nib.get_data()
    rt.plot_slices(atlas)

    # Resample atlas on top of neo1
    aff = AffineMap(None, neo1.shape, neo1_affine, atlas.shape, atlas_affine)
    atlas_resampled = aff.transform(atlas)
    rt.overlay_slices(neo1, atlas_resampled)
Esempio n. 8
0
def c_of_mass(moving, static, static_affine, moving_affine,
              reg, starting_affine, params0=None):
    transform = transform_centers_of_mass(static, static_affine,
                                          moving, moving_affine)
    transformed = transform.transform(moving)
    return transformed, transform.affine
Esempio n. 9
0
brainweb_nib = nib.load(brainweb_name)
brainweb = brainweb_nib.get_data().squeeze()
brainweb_affine = brainweb_nib.get_affine()
brainweb = brainweb.transpose([0, 2, 1])[::-1, :, :]
rt.plot_slices(brainweb)
brainweb_affine = ibsr1_affine.copy()
brainweb_affine[brainweb_affine != 0] = 1
brainweb_affine[0, 0] = -1


# Reslice Brainweb on IBSR1
ibsr_to_bw = AffineMap(None, ibsr1.shape, ibsr1_affine, brainweb.shape, brainweb_affine)
bw_on_ibsr1 = ibsr_to_bw.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1)  # misaligned

c_of_mass = transform_centers_of_mass(ibsr1, ibsr1_affine, brainweb, brainweb_affine)
bw_on_ibsr1 = c_of_mass.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1)  # roughly aligned

# Start affine alignment
aff_name = "ibsr1_to_brainweb.p"
if os.path.isfile(aff_name):
    ibsr_bw_affmap = pickle.load(open(aff_name, "r"))
else:
    ibsr_bw_affmap = dipy_align(ibsr1, ibsr1_affine, brainweb, brainweb_affine)
    pickle.dump(ibsr_bw_affmap, open(aff_name, "w"))
bw_on_ibsr1 = ibsr_bw_affmap.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=0)  # aligned (sagital view)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=1)  # aligned (axial view)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=2)  # aligned (coronal view)
Esempio n. 10
0
brainweb_nib = nib.load(brainweb_name)
brainweb = brainweb_nib.get_data().squeeze()
brainweb_affine = brainweb_nib.get_affine()
brainweb = brainweb.transpose([0, 2, 1])[::-1, :, :]
rt.plot_slices(brainweb)
brainweb_affine = ibsr1_affine.copy()
brainweb_affine[brainweb_affine != 0] = 1
brainweb_affine[0, 0] = -1

# Reslice Brainweb on IBSR1
ibsr_to_bw = AffineMap(None, ibsr1.shape, ibsr1_affine, brainweb.shape,
                       brainweb_affine)
bw_on_ibsr1 = ibsr_to_bw.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1)  # misaligned

c_of_mass = transform_centers_of_mass(ibsr1, ibsr1_affine, brainweb,
                                      brainweb_affine)
bw_on_ibsr1 = c_of_mass.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1)  # roughly aligned

# Start affine alignment
aff_name = 'ibsr1_to_brainweb.p'
if os.path.isfile(aff_name):
    ibsr_bw_affmap = pickle.load(open(aff_name, 'r'))
else:
    ibsr_bw_affmap = dipy_align(ibsr1, ibsr1_affine, brainweb, brainweb_affine)
    pickle.dump(ibsr_bw_affmap, open(aff_name, 'w'))
bw_on_ibsr1 = ibsr_bw_affmap.transform(brainweb)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=0)  # aligned (sagital view)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=1)  # aligned (axial view)
rt.overlay_slices(ibsr1, bw_on_ibsr1, slice_type=2)  # aligned (coronal view)
def quick_check():

    img1_fname = "/home/omar/data/DATA_NeoBrainS12/T1.nii.gz"
    img2_fname = "/home/omar/data/DATA_NeoBrainS12/set2_i1_t1.nii.gz"

    img1_nib = nib.load(img1_fname)
    img1 = img1_nib.get_data().squeeze()
    img1_affine = img1_nib.get_affine()

    img2_nib = nib.load(img2_fname)
    img2 = img2_nib.get_data().squeeze()
    img2_affine = img2_nib.get_affine()
    # nib.aff2axcodes(img1_affine)
    #aff = AffineMap(None, img1.shape, img1_affine, img2.shape, img2_affine)
    #aff = transform_centers_of_mass(img1, img1_affine, img2, img2_affine)
    aff = dipy_align(img1, img1_affine, img2, img2_affine, np.eye(4))

    img2_resampled = aff.transform(img2)
    rt.overlay_slices(img1, img2_resampled, slice_type=0)
    rt.overlay_slices(img1, img2_resampled, slice_type=1)
    rt.overlay_slices(img1, img2_resampled, slice_type=2)

    # Verify that original and RAS versions of neo1 describe the same object

    # Load original data
    neo1_fname = get_neobrain('train', 1, 'T1')
    neo1_old, neo1_old_affine, neo1_old_spacing, neo1_old_ori = load_from_raw(
        neo1_fname)

    # Load RAS version
    neo1_nib = nib.load(neo1_fname)
    neo1 = neo1_nib.get_data()
    neo1_affine = neo1_nib.get_affine()

    # Resample RAS on top of original
    aff = AffineMap(None, neo1_old.shape, neo1_old_affine, neo1.shape,
                    neo1_affine)
    neo1_resampled = aff.transform(neo1)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=0)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=1)
    rt.overlay_slices(neo1_old, neo1_resampled, slice_type=2)

    # Attempt to resample a test volume on top of training
    neo2_fname = get_neobrain('test', 1, 'i1_t1')
    neo2_nib = nib.load(neo2_fname)
    neo2 = neo2_nib.get_data()
    neo2_affine = neo2_nib.get_affine()
    aff = transform_centers_of_mass(neo1, neo1_affine, neo2, neo2_affine)
    #aff = dipy_align(neo1, neo1_affine, neo2, neo2_affine)
    neo2_resampled = aff.transform(neo2)

    rt.overlay_slices(neo1, neo2_resampled, slice_type=0)
    rt.overlay_slices(neo1, neo2_resampled, slice_type=1)
    rt.overlay_slices(neo1, neo2_resampled, slice_type=2)

    # Load atlas
    atlas_fname = get_neobrain('atlas', 'neo-withSkull', None)
    atlas_nib = nib.load(atlas_fname)
    atlas_affine = atlas_nib.get_affine()
    atlas = atlas_nib.get_data()
    rt.plot_slices(atlas)

    # Resample atlas on top of neo1
    aff = AffineMap(None, neo1.shape, neo1_affine, atlas.shape, atlas_affine)
    atlas_resampled = aff.transform(atlas)
    rt.overlay_slices(neo1, atlas_resampled)
Esempio n. 12
0
def warp_syn_dipy(static_fname, moving_fname):
    import os
    import numpy as np
    import nibabel as nb
    from dipy.align.metrics import CCMetric
    from dipy.align.imaffine import (transform_centers_of_mass,
                                     AffineMap,
                                     MutualInformationMetric,
                                     AffineRegistration)
    from dipy.align.transforms import (TranslationTransform3D,
                                       RigidTransform3D,
                                       AffineTransform3D)
    from dipy.align.imwarp import (DiffeomorphicMap,
                                   SymmetricDiffeomorphicRegistration)

    from nipype.utils.filemanip import fname_presuffix

    static = nb.load(static_fname)
    moving = nb.load(moving_fname)
    
    c_of_mass = transform_centers_of_mass(static.get_data(), static.affine,
                                          moving.get_data(), moving.affine)
    nbins = 32
    sampling_prop = None
    metric = MutualInformationMetric(nbins, sampling_prop)
    level_iters = [10000, 1000, 100]
    sigmas = [3.0, 1.0, 0.0]
    factors = [4, 2, 1]
    affreg = AffineRegistration(metric=metric,
                                level_iters=level_iters,
                                sigmas=sigmas,
                                factors=factors)
    transform = TranslationTransform3D()
    params0 = None
    starting_affine = c_of_mass.affine
    translation = affreg.optimize(static.get_data(), moving.get_data(),
                                  transform, params0,
                                  static.affine, moving.affine,
                                  starting_affine=starting_affine)
    
    transform = RigidTransform3D()
    params0 = None
    starting_affine = translation.affine
    rigid = affreg.optimize(static.get_data(), moving.get_data(), transform, params0,
                            static.affine, moving.affine,
                            starting_affine=starting_affine)
    transform = AffineTransform3D()
    params0 = None
    starting_affine = rigid.affine
    affine = affreg.optimize(static.get_data(), moving.get_data(), transform, params0,
                             static.affine, moving.affine,
                             starting_affine=starting_affine)
    
    metric = CCMetric(3, sigma_diff=3.)
    level_iters = [25, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
    starting_affine = affine.affine
    mapping = sdr.optimize(
	static.get_data(), moving.get_data(),
	static.affine, moving.affine,
	starting_affine)

    warped_filename = os.path.abspath(fname_presuffix(moving_fname, newpath='./', suffix='_warped', use_ext=True))
    warped = nb.Nifti1Image(mapping.transform(moving.get_data()), static.affine)
    warped.to_filename(warped_filename)

    warp_filename = os.path.abspath(fname_presuffix(moving_fname, newpath='./', suffix='_warp.npz', use_ext=False))
    np.savez(warp_filename,prealign=mapping.prealign,forward=mapping.forward,backward=mapping.backward)

    return warp_filename, warped_filename