Esempio n. 1
0
def test_transform_origins_3d():
    # Create arbitrary image-to-space transforms
    axis = np.array([.5, 2.0, 1.5])
    t = 0.15  # translation factor

    for theta in [-1 * np.pi / 6.0, 0.0, np.pi / 5.0]:  # rotation angle
        for s in [0.83, 1.3, 2.07]:  # scale
            m_shapes = [(256, 256, 128), (255, 255, 127), (64, 127, 142)]
            for shape_moving in m_shapes:
                s_shapes = [(256, 256, 128), (255, 255, 127), (64, 127, 142)]
                for shape_static in s_shapes:
                    moving = np.ndarray(shape=shape_moving)
                    static = np.ndarray(shape=shape_static)
                    trans = np.array([[1, 0, 0, -t * shape_static[0]],
                                      [0, 1, 0, -t * shape_static[1]],
                                      [0, 0, 1, -t * shape_static[2]],
                                      [0, 0, 0, 1]])
                    trans_inv = npl.inv(trans)
                    rot = np.zeros(shape=(4, 4))
                    rot[:3, :3] = geometry.rodrigues_axis_rotation(axis, theta)
                    rot[3, 3] = 1.0
                    scale = np.array([[1 * s, 0, 0, 0],
                                      [0, 1 * s, 0, 0],
                                      [0, 0, 1 * s, 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[:3, 3]
                    c_moving = moving_grid2world[:3, 3]
                    expected = np.eye(4)
                    expected[:3, 3] = c_moving - c_static

                    # Implementation under test
                    actual = imaffine.transform_origins(static,
                                                        static_grid2world,
                                                        moving,
                                                        moving_grid2world)
                    assert_array_almost_equal(actual.affine, expected)
Esempio n. 2
0
def test_transform_origins_3d():
    # Create arbitrary image-to-space transforms
    axis = np.array([.5, 2.0, 1.5])
    t = 0.15  # translation factor

    for theta in [-1 * np.pi / 6.0, 0.0, np.pi / 5.0]:  # rotation angle
        for s in [0.83, 1.3, 2.07]:  # scale
            m_shapes = [(256, 256, 128), (255, 255, 127), (64, 127, 142)]
            for shape_moving in m_shapes:
                s_shapes = [(256, 256, 128), (255, 255, 127), (64, 127, 142)]
                for shape_static in s_shapes:
                    moving = np.ndarray(shape=shape_moving)
                    static = np.ndarray(shape=shape_static)
                    trans = np.array([[1, 0, 0, -t * shape_static[0]],
                                      [0, 1, 0, -t * shape_static[1]],
                                      [0, 0, 1, -t * shape_static[2]],
                                      [0, 0, 0, 1]])
                    trans_inv = npl.inv(trans)
                    rot = np.zeros(shape=(4, 4))
                    rot[:3, :3] = geometry.rodrigues_axis_rotation(axis, theta)
                    rot[3, 3] = 1.0
                    scale = np.array([[1 * s, 0, 0, 0],
                                      [0, 1 * s, 0, 0],
                                      [0, 0, 1 * s, 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[:3, 3]
                    c_moving = moving_grid2world[:3, 3]
                    expected = np.eye(4)
                    expected[:3, 3] = c_moving - c_static

                    # Implementation under test
                    actual = imaffine.transform_origins(static,
                                                        static_grid2world,
                                                        moving,
                                                        moving_grid2world)
                    assert_array_almost_equal(actual.affine, expected)
Esempio n. 3
0
                                 transform_origins)
from dipy.align.transforms import (TranslationTransform3D, RigidTransform3D,
                                   AffineTransform3D)

static = np.asarray(img_t2_mni.dataobj)
static_affine = img_t2_mni.affine
moving = mean_b0_masked_stanford
moving_affine = hardi_img.affine
"""
We estimate an affine that maps the origin of the moving image to that of the
static image. We can then use this later to account for the offsets of each
image.

"""

affine_map = transform_origins(static, static_affine, moving, moving_affine)
"""
We specify the mismatch metric:

"""

nbins = 32
sampling_prop = None
metric = MutualInformationMetric(nbins, sampling_prop)
"""
As well as the optimization strategy:

"""

level_iters = [10, 10, 5]
sigmas = [3.0, 1.0, 0.0]
Esempio n. 4
0
def wm_syn(t1w_brain,
           ap_path,
           working_dir,
           fa_path=None,
           template_fa_path=None):
    """
    A function to perform SyN registration

    Parameters
    ----------
        t1w_brain  : str
            File path to the skull-stripped T1w brain Nifti1Image.
        ap_path : str
            File path to the AP moving image.
        working_dir : str
            Path to the working directory to perform SyN and save outputs.
        fa_path : str
            File path to the FA moving image.
        template_fa_path  : str
            File path to the T1w-connformed template FA reference image.
    """
    import uuid
    from time import strftime
    from dipy.align.imaffine import (
        MutualInformationMetric,
        AffineRegistration,
        transform_origins,
    )
    from dipy.align.transforms import (
        TranslationTransform3D,
        RigidTransform3D,
        AffineTransform3D,
    )
    from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
    from dipy.align.metrics import CCMetric

    # from dipy.viz import regtools
    # from nilearn.image import resample_to_img

    ap_img = nib.load(ap_path)
    t1w_brain_img = nib.load(t1w_brain)
    static = np.asarray(t1w_brain_img.dataobj, dtype=np.float32)
    static_affine = t1w_brain_img.affine
    moving = np.asarray(ap_img.dataobj, dtype=np.float32)
    moving_affine = ap_img.affine

    affine_map = transform_origins(static, static_affine, moving,
                                   moving_affine)

    nbins = 32
    sampling_prop = None
    metric = MutualInformationMetric(nbins, sampling_prop)

    level_iters = [10, 10, 5]
    sigmas = [3.0, 1.0, 0.0]
    factors = [4, 2, 1]
    affine_reg = AffineRegistration(metric=metric,
                                    level_iters=level_iters,
                                    sigmas=sigmas,
                                    factors=factors)
    transform = TranslationTransform3D()

    params0 = None
    translation = affine_reg.optimize(static, moving, transform, params0,
                                      static_affine, moving_affine)
    transform = RigidTransform3D()

    rigid_map = affine_reg.optimize(
        static,
        moving,
        transform,
        params0,
        static_affine,
        moving_affine,
        starting_affine=translation.affine,
    )
    transform = AffineTransform3D()

    # We bump up the iterations to get a more exact fit:
    affine_reg.level_iters = [1000, 1000, 100]
    affine_opt = affine_reg.optimize(
        static,
        moving,
        transform,
        params0,
        static_affine,
        moving_affine,
        starting_affine=rigid_map.affine,
    )

    # We now perform the non-rigid deformation using the Symmetric
    # Diffeomorphic Registration(SyN) Algorithm:
    metric = CCMetric(3)
    level_iters = [10, 10, 5]

    # Refine fit
    if template_fa_path is not None:
        from nilearn.image import resample_to_img
        fa_img = nib.load(fa_path)
        template_img = nib.load(template_fa_path)
        template_img_res = resample_to_img(template_img, t1w_brain_img)
        static = np.asarray(template_img_res.dataobj, dtype=np.float32)
        static_affine = template_img_res.affine
        moving = np.asarray(fa_img.dataobj, dtype=np.float32)
        moving_affine = fa_img.affine
    else:
        static = np.asarray(t1w_brain_img.dataobj, dtype=np.float32)
        static_affine = t1w_brain_img.affine
        moving = np.asarray(ap_img.dataobj, dtype=np.float32)
        moving_affine = ap_img.affine

    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, moving, static_affine, moving_affine,
                           affine_opt.affine)
    warped_moving = mapping.transform(moving)

    # Save warped FA image
    run_uuid = f"{strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4()}"
    warped_fa = f"{working_dir}/warped_fa_{run_uuid}.nii.gz"
    nib.save(nib.Nifti1Image(warped_moving, affine=static_affine), warped_fa)

    # # We show the registration result with:
    # regtools.overlay_slices(static, warped_moving, None, 0,
    # "Static", "Moving",
    #                         "%s%s%s%s" % (working_dir,
    #                         "/transformed_sagittal_", run_uuid, ".png"))
    # regtools.overlay_slices(static, warped_moving, None,
    # 1, "Static", "Moving",
    #                         "%s%s%s%s" % (working_dir,
    #                         "/transformed_coronal_", run_uuid, ".png"))
    # regtools.overlay_slices(static, warped_moving,
    # None, 2, "Static", "Moving",
    #                         "%s%s%s%s" % (working_dir,
    #                         "/transformed_axial_", run_uuid, ".png"))

    return mapping, affine_map, warped_fa
Esempio n. 5
0
def wm_syn(template_path, fa_path, working_dir):
    """
    A function to perform ANTS SyN registration

    Parameters
    ----------
        template_path  : str
            File path to the template reference image.
        fa_path : str
            File path to the FA moving image.
        working_dir : str
            Path to the working directory to perform SyN and save outputs.
    """
    import uuid
    from time import strftime
    from dipy.align.imaffine import MutualInformationMetric, AffineRegistration, transform_origins
    from dipy.align.transforms import TranslationTransform3D, RigidTransform3D, AffineTransform3D
    from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
    from dipy.align.metrics import CCMetric
    from dipy.viz import regtools

    fa_img = nib.load(fa_path)
    template_img = nib.load(template_path)

    static = np.asarray(template_img.dataobj)
    static_affine = template_img.affine
    moving = np.asarray(fa_img.dataobj).astype(np.float32)
    moving_affine = fa_img.affine

    affine_map = transform_origins(static, static_affine, moving,
                                   moving_affine)

    nbins = 32
    sampling_prop = None
    metric = MutualInformationMetric(nbins, sampling_prop)

    level_iters = [10, 10, 5]
    sigmas = [3.0, 1.0, 0.0]
    factors = [4, 2, 1]
    affine_reg = AffineRegistration(metric=metric,
                                    level_iters=level_iters,
                                    sigmas=sigmas,
                                    factors=factors)
    transform = TranslationTransform3D()

    params0 = None
    translation = affine_reg.optimize(static, moving, transform, params0,
                                      static_affine, moving_affine)
    transform = RigidTransform3D()

    rigid_map = affine_reg.optimize(static,
                                    moving,
                                    transform,
                                    params0,
                                    static_affine,
                                    moving_affine,
                                    starting_affine=translation.affine)
    transform = AffineTransform3D()

    # We bump up the iterations to get a more exact fit:
    affine_reg.level_iters = [1000, 1000, 100]
    affine_opt = affine_reg.optimize(static,
                                     moving,
                                     transform,
                                     params0,
                                     static_affine,
                                     moving_affine,
                                     starting_affine=rigid_map.affine)

    # We now perform the non-rigid deformation using the Symmetric Diffeomorphic Registration(SyN) Algorithm:
    metric = CCMetric(3)
    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, moving, static_affine, moving_affine,
                           affine_opt.affine)
    warped_moving = mapping.transform(moving)

    # Save warped FA image
    run_uuid = '%s_%s' % (strftime('%Y%m%d_%H%M%S'), uuid.uuid4())
    warped_fa = '{}/warped_fa_{}.nii.gz'.format(working_dir, run_uuid)
    nib.save(nib.Nifti1Image(warped_moving, affine=static_affine), warped_fa)

    # We show the registration result with:
    regtools.overlay_slices(
        static, warped_moving, None, 0, "Static", "Moving",
        "%s%s%s%s" % (working_dir, "/transformed_sagittal_", run_uuid, ".png"))
    regtools.overlay_slices(
        static, warped_moving, None, 1, "Static", "Moving",
        "%s%s%s%s" % (working_dir, "/transformed_coronal_", run_uuid, ".png"))
    regtools.overlay_slices(
        static, warped_moving, None, 2, "Static", "Moving",
        "%s%s%s%s" % (working_dir, "/transformed_axial_", run_uuid, ".png"))

    return mapping, affine_map, warped_fa
Esempio n. 6
0
def wm_syn(template_path, fa_path, working_dir):
    """A function to perform ANTS SyN registration using dipy functions

    Parameters
    ----------
    template_path  : str
        File path to the template reference FA image.
    fa_path : str
        File path to the FA moving image (image to be fitted to reference)
    working_dir : str
        Path to the working directory to perform SyN and save outputs.

    Returns
    -------
    DiffeomorphicMap
        An object that can be used to register images back and forth between static (template) and moving (FA) domains
    AffineMap
        An object used to transform the moving (FA) image towards the static image (template)
    """

    fa_img = nib.load(fa_path)
    template_img = nib.load(template_path)

    static = template_img.get_data()
    static_affine = template_img.affine
    moving = fa_img.get_data().astype(np.float32)
    moving_affine = fa_img.affine

    affine_map = transform_origins(static, static_affine, moving,
                                   moving_affine)

    nbins = 32
    sampling_prop = None
    metric = MutualInformationMetric(nbins, sampling_prop)

    level_iters = [10, 10, 5]
    sigmas = [3.0, 1.0, 0.0]
    factors = [4, 2, 1]
    affine_reg = AffineRegistration(metric=metric,
                                    level_iters=level_iters,
                                    sigmas=sigmas,
                                    factors=factors)
    transform = TranslationTransform3D()

    params0 = None
    translation = affine_reg.optimize(static, moving, transform, params0,
                                      static_affine, moving_affine)
    transform = RigidTransform3D()

    rigid_map = affine_reg.optimize(
        static,
        moving,
        transform,
        params0,
        static_affine,
        moving_affine,
        starting_affine=translation.affine,
    )
    transform = AffineTransform3D()

    # We bump up the iterations to get a more exact fit:
    affine_reg.level_iters = [1000, 1000, 100]
    affine_opt = affine_reg.optimize(
        static,
        moving,
        transform,
        params0,
        static_affine,
        moving_affine,
        starting_affine=rigid_map.affine,
    )

    # We now perform the non-rigid deformation using the Symmetric Diffeomorphic Registration(SyN) Algorithm:
    metric = CCMetric(3)
    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, moving, static_affine, moving_affine,
                           affine_opt.affine)
    warped_moving = mapping.transform(moving)

    # We show the registration result with:
    regtools.overlay_slices(
        static,
        warped_moving,
        None,
        0,
        "Static",
        "Moving",
        f"{working_dir}/transformed_sagittal.png",
    )
    regtools.overlay_slices(
        static,
        warped_moving,
        None,
        1,
        "Static",
        "Moving",
        f"{working_dir}/transformed_coronal.png",
    )
    regtools.overlay_slices(
        static,
        warped_moving,
        None,
        2,
        "Static",
        "Moving",
        f"{working_dir}/transformed_axial.png",
    )

    return mapping, affine_map