Exemplo n.º 1
0
def alignImage(static, moving, level_iters):
    """The Symmetric Normalization algorithm uses a multi-resolution approach by building a Gaussian Pyramid.
    The static image is used a reference; a transformation that transforms the moving image into the
    static image is found and applied to the static image.  Returns overlay images, error image, and transformation matrix. 
    Uses CrossCorrelation metric which makes sense for aligning AFM topography. 
    
    INPUT: static and moving are both 2d arrays of the same dimension.
    Level_iters is a list (typically 4 entries) defines
    the number of iterations a user wants at each level of the pyramid, with the 0th entry referring to the 
    finest resolution.
    
    OUTPUT: overlayimages: an image with the static, moving, and overlay images
            errorimage: the difference between the warped_moving image and the static reference. THe flatter 
            the better.
            transformmatrix: the matrix corresponding to the forward transformation of a matrix."""
    
    from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
    from dipy.align.metrics import SSDMetric, CCMetric, EMMetric
    from dipy.viz import regtools

    dim = static.ndim
    metric = CCMetric(dim)
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, inv_iter = 50)
    mapping = sdr.optimize(static, moving)
    warped_moving = mapping.transform(moving, 'linear')
    overlayimages = regtools.overlay_images(static, warped_moving, 'Static','Overlay','Warped moving',
   'direct_warp_result.png')
    errorimage = plt.matshow(warped_moving-static, cmap='viridis')
    transformmatrix=mapping.forward
    
    
    return overlayimages, errorimage, transformmatrix
Exemplo n.º 2
0
def register_diffeo(t_masked, m_masked, start_affine, registration=None):
    """ Run non-linear registration between `t_masked` and `m_masked`

    Parameters
    ----------
    t_masked : image
        Template image object, with image data masked to set out-of-brain
        voxels to zero.
    m_masked : image
        Moving (individual) image object, with image data masked to set
        out-of-brain voxels to zero.
    start_affine : shape (4, 4) ndarray
        Affine mapping from voxels in `t_masked` to voxels in `m_masked`.
    registration : None or SymmetricDiffeoMorphicRegistration instance
        Registration instance we will use to register `t_masked` and
        `m_masked`.  If None, make a default registration object.

    Returns
    -------
    mapping : mapping instance
        Instance giving affine + non-linear mapping between voxels in
        `t_masked` and voxels in `m_masked`.
    """
    if registration is None:
        registration = SymmetricDiffeomorphicRegistration(
            metric=CCMetric(3), level_iters=[10, 10, 5])
    return registration.optimize(t_masked.get_data().astype(float),
                                 m_masked.get_data().astype(float),
                                 t_masked.affine, m_masked.affine,
                                 start_affine)
Exemplo n.º 3
0
def syn_registration(static_data, static_affine, moving_data, moving_affine):
    
    # Terminology for comments:
    #   1. Static image = Reference image
    #   2. Moving image = Image that will be registered to the static image

    # Prealignment has been done using FLIRT, so the identity matrix is used since
    # no further transformation is necessary
    pre_align = np.array([[1, 0, 0, 0],
                          [0, 1, 0, 0],
                          [0, 0, 1, 0],
                          [0, 0, 0, 1]])    
    
    # We want to find an invertible map that transforms the moving image into the
    # static image. We will use the Cross Correlation metric. 
    metric = CCMetric(3)

    # Now we define an instance of the registration class. The SyN algorithm uses
    # a multi-resolution approach by building a Gaussian Pyramid. We instruct the
    # registration object to perform at most [n_0, n_1, ..., n_k] iterations at
    # each level of the pyramid. The 0-th level corresponds to the finest resolution. 
    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    # Execute the optimization, which returns a DiffeomorphicMap object,
    # that can be used to register images back and forth between the static and
    # moving domains. We provide the pre-aligning matrix that brings the moving
    # image closer to the static image    
    mapping = sdr.optimize(static_data, moving_data, 
                            static_affine, moving_affine, pre_align)

    # Warp the moving image and see if it gets similar to the static image
    warped_moving = mapping.transform(moving_data)

    return warped_moving, mapping
Exemplo n.º 4
0
def test_plot_2d_diffeomorphic_map():
    # Test the regtools plotting interface (lightly).
    mv_shape = (11, 12)
    moving = np.random.rand(*mv_shape)
    st_shape = (13, 14)
    static = np.random.rand(*st_shape)
    dim = static.ndim
    metric = SSDMetric(dim)
    level_iters = [200, 100, 50, 25]
    sdr = SymmetricDiffeomorphicRegistration(metric,
                                             level_iters,
                                             inv_iter=50)
    mapping = sdr.optimize(static, moving)
    # Smoke testing of plots
    ff = regtools.plot_2d_diffeomorphic_map(mapping, 10)
    # Defualt shape is static shape, moving shape
    npt.assert_equal(ff[0].shape, st_shape)
    npt.assert_equal(ff[1].shape, mv_shape)
    # Can specify shape
    ff = regtools.plot_2d_diffeomorphic_map(mapping,
                                            delta = 10,
                                            direct_grid_shape=(7, 8),
                                            inverse_grid_shape=(9, 10))
    npt.assert_equal(ff[0].shape, (7, 8))
    npt.assert_equal(ff[1].shape, (9, 10))
Exemplo n.º 5
0
def syn_registration(moving,
                     static,
                     moving_affine=None,
                     static_affine=None,
                     step_length=0.25,
                     metric='CC',
                     dim=3,
                     level_iters=[10, 10, 5],
                     sigma_diff=2.0,
                     prealign=None):
    """Register a source image (moving) to a target image (static).

    Parameters
    ----------
    moving : ndarray
        The source image data to be registered
    moving_affine : array, shape (4,4)
        The affine matrix associated with the moving (source) data.
    static : ndarray
        The target image data for registration
    static_affine : array, shape (4,4)
        The affine matrix associated with the static (target) data
    metric : string, optional
        The metric to be optimized. One of `CC`, `EM`, `SSD`,
        Default: CCMetric.
    dim: int (either 2 or 3), optional
       The dimensions of the image domain. Default: 3
    level_iters : list of int, optional
        the number of iterations at each level of the Gaussian Pyramid (the
        length of the list defines the number of pyramid levels to be
        used).

    Returns
    -------
    warped_moving : ndarray
        The data in `moving`, warped towards the `static` data.
    forward : ndarray (..., 3)
        The vector field describing the forward warping from the source to the
        target.
    backward : ndarray (..., 3)
        The vector field describing the backward warping from the target to the
        source.
    """
    use_metric = syn_metric_dict[metric](dim, sigma_diff=sigma_diff)

    sdr = SymmetricDiffeomorphicRegistration(use_metric,
                                             level_iters,
                                             step_length=step_length)

    mapping = sdr.optimize(static,
                           moving,
                           static_grid2world=static_affine,
                           moving_grid2world=moving_affine,
                           prealign=prealign)

    warped_moving = mapping.transform(moving)
    return warped_moving, mapping
Exemplo n.º 6
0
def exampleDipy():
	
    # example obtained from: http://nipy.org/dipy/examples_built/syn_registration_2d.html
    import ssl
    if hasattr(ssl, '_create_unverified_context'):
        ssl._create_default_https_context = ssl._create_unverified_context
    from dipy.data import fetch_stanford_hardi, read_stanford_hardi
    fetch_stanford_hardi()
    nib_stanford, gtab_stanford = read_stanford_hardi()
    stanford_b0 = np.squeeze(nib_stanford.get_data())[..., 0]

    from dipy.data.fetcher import fetch_syn_data, read_syn_data
    fetch_syn_data()
    nib_syn_t1, nib_syn_b0 = read_syn_data()
    syn_b0 = np.array(nib_syn_b0.get_data())

    from dipy.segment.mask import median_otsu

    stanford_b0_masked, stanford_b0_mask = median_otsu(stanford_b0, 4, 4)
    syn_b0_masked, syn_b0_mask = median_otsu(syn_b0, 4, 4)

    static = stanford_b0_masked
    static_affine = nib_stanford.affine
    moving = syn_b0_masked
    moving_affine = nib_syn_b0.affine

    pre_align = np.array(
        [[1.02783543e+00, -4.83019053e-02, -6.07735639e-02, -2.57654118e+00],
         [4.34051706e-03, 9.41918267e-01, -2.66525861e-01, 3.23579799e+01],
         [5.34288908e-02, 2.90262026e-01, 9.80820307e-01, -1.46216651e+01],
         [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])

    from dipy.align.imaffine import AffineMap
    affine_map = AffineMap(pre_align,
                           static.shape, static_affine,
                           moving.shape, moving_affine)

    resampled = affine_map.transform(moving)

    metric = CCMetric(3)

    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, moving, static_affine, moving_affine,
                           pre_align)

    warped_moving = mapping.transform(moving)

    for slice in range(41 - 12, 41 + 13):
        regtools.overlay_slices(static, resampled, slice, 1, 'Static',
                                'Pre Moving',
                                'GIFexample1/' + str(slice) + 'T1pre.png')
        regtools.overlay_slices(static, warped_moving, slice, 1, 'Static',
                                'Post moving',
                                'GIFexample1/' + str(slice) + 'T1post.png')
Exemplo n.º 7
0
def syn_registration(moving, static,
                     moving_affine=None,
                     static_affine=None,
                     step_length=0.25,
                     metric='CC',
                     dim=3,
                     level_iters=[10, 10, 5],
                     sigma_diff=2.0,
                     prealign=None):
    """Register a source image (moving) to a target image (static).

    Parameters
    ----------
    moving : ndarray
        The source image data to be registered
    moving_affine : array, shape (4,4)
        The affine matrix associated with the moving (source) data.
    static : ndarray
        The target image data for registration
    static_affine : array, shape (4,4)
        The affine matrix associated with the static (target) data
    metric : string, optional
        The metric to be optimized. One of `CC`, `EM`, `SSD`,
        Default: CCMetric.
    dim: int (either 2 or 3), optional
       The dimensions of the image domain. Default: 3
    level_iters : list of int, optional
        the number of iterations at each level of the Gaussian Pyramid (the
        length of the list defines the number of pyramid levels to be
        used).

    Returns
    -------
    warped_moving : ndarray
        The data in `moving`, warped towards the `static` data.
    forward : ndarray (..., 3)
        The vector field describing the forward warping from the source to the
        target.
    backward : ndarray (..., 3)
        The vector field describing the backward warping from the target to the
        source.
    """
    use_metric = syn_metric_dict[metric](dim, sigma_diff=sigma_diff)

    sdr = SymmetricDiffeomorphicRegistration(use_metric, level_iters,
                                             step_length=step_length)

    mapping = sdr.optimize(static, moving,
                           static_grid2world=static_affine,
                           moving_grid2world=moving_affine,
                           prealign=prealign)

    warped_moving = mapping.transform(moving)
    return warped_moving, mapping
Exemplo n.º 8
0
 def dipy_work(self, uncorrected, worker_progress_signal):
     radius = 4
     sigma_diff = 3.0
     metric = CCMetric(2, sigma_diff, radius)
     level_iters = [25]
     sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
     corrected = np.zeros_like(uncorrected)
     corrected[0] = uncorrected[0]
     for i in range(1, len(uncorrected)):
         mapping = sdr.optimize(corrected[0], uncorrected[i])
         corrected[i] = mapping.transform(uncorrected[i])
         worker_progress_signal.emit(i)
     return {'corrected': corrected}
Exemplo n.º 9
0
 def get_params(self):
     level_iters = [
         np.random.randint(i, j)
         for i, j in zip(self.iter_limits[0], self.iter_limits[1])
     ]
     sdr = SymmetricDiffeomorphicRegistration(self.metric,
                                              level_iters,
                                              inv_iter=50)
     return {"sdr": sdr}
Exemplo n.º 10
0
def abstractExample():
    numBlobs = 4

    shape = np.array([81, 106, 76])
    static = np.zeros(shape)
    resampled = np.zeros(shape)

    size_blob = 3

    for blob in range(numBlobs):
        jitter = np.random.randint(5)

        randIndX = 41 + 2 * blob
        randIndY = np.random.randint(shape[1] - 2 * size_blob)
        randIndZ = np.random.randint(shape[2] - 2 * size_blob)

        static[randIndX - size_blob:randIndX + size_blob,
        randIndY - size_blob:randIndY + size_blob,
        randIndZ - size_blob:randIndZ + size_blob] = 1

        randIndY = randIndY + jitter
        randIndZ = randIndZ + jitter + np.random.randint(-1, 2)

        resampled[randIndX - size_blob:randIndX + size_blob,
        randIndY - size_blob:randIndY + size_blob,
        randIndZ - size_blob:randIndZ + size_blob] = 1

    metric = CCMetric(3)

    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, resampled)

    warped_moving = mapping.transform(resampled)

    for slice in range(41 - 3 * size_blob, 41 + 3 * size_blob + 1):
        regtools.overlay_slices(static, resampled, slice, 0, 'Static',
                                'Pre Moving',
                                'GIFexample1/' + str(slice) + 'preMov.png')

        regtools.overlay_slices(static, warped_moving, slice, 0, 'Static',
                                'Post moving',
                                'GIFexample1/' + str(slice) + 'postMov.png')
Exemplo n.º 11
0
    def get_elastic_transform(subject_fa, atlas_fa, subject_path=".."):
        '''
        :param subject_fa: the FA (nibabel img) of a static image of a subject       (static)
        :param atlas_fa:  the FA (nibabel img) of an atlas (Atlas will be warped onto subject)   (moving)

        :return: elastic transformation map
        '''

        if isfile(subject_path + "/FAReg_elastic_transform.pklz"):
            logging.debug("Load existing elastic transform...")
            return Utils.load_pkl_compressed(subject_path +
                                             "/FAReg_elastic_transform.pklz")

        static_img = subject_fa
        static = static_img.get_data()
        moving_img = atlas_fa
        moving = moving_img.get_data()

        # Optional (affine transformation of moving image to static coordinate system) -> needed if on very different ones!
        affine_map = AffineMap(np.eye(4), static.shape,
                               static_img.get_affine(), moving.shape,
                               moving_img.get_affine())
        moving = affine_map.transform(moving)

        start_time = time.time()
        metric = CCMetric(3)
        level_iters = [10, 10, 5]  # better
        # level_iters = [2, 2, 2] #fast -> not much
        sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
        mapping = sdr.optimize(static, moving)
        # mapping = sdr.optimize(static, moving, Utils.invert_x_and_y(static_img.get_affine()), Utils.invert_x_and_y(moving_img.get_affine())) #not needed
        logging.debug("elastic transform took {0:.2f}s".format(time.time() -
                                                               start_time))

        logging.debug("write elastic transform...")
        Utils.save_pkl_compressed(
            subject_path + "/FAReg_elastic_transform.pklz", mapping)
        return mapping
Exemplo n.º 12
0
affine = affreg.optimize(t1_s,
                         t1_m,
                         AffineTransform3D(),
                         None,
                         t1_s_grid2world,
                         t1_m_grid2world,
                         starting_affine=rigid.affine)

# apply affine transformation
t1_m_affine = affine.transform(t1_m)

###############################################################################
# Compute Symmetric Diffeomorphic Registration

# set up Symmetric Diffeomorphic Registration (metric, iterations per level)
sdr = SymmetricDiffeomorphicRegistration(CCMetric(3), niter_sdr)

# compute mapping
mapping = sdr.optimize(t1_s, t1_m_affine)

###############################################################################
# Apply transformations and plot

# morph img data
img_sdr_affine = mapping.transform(affine.transform(img))

# make transformed ndarray a nifti
img_vol_sdr_affine = nib.Nifti1Image(img_sdr_affine, affine=t1_s_grid2world)

# save morphed grid
nib.save(img_vol_sdr_affine, 'lcmv_inverse_fsavg.nii.gz')
Exemplo n.º 13
0
hardi_affine = ni.get_affine()
b0 = hardi_data[..., gtab.b0s_mask]
mean_b0 = np.mean(b0, -1)

ni_b0 = nib.Nifti1Image(mean_b0, hardi_affine)
ni_b0.to_filename('mean_b0.nii')
plt.matshow(mean_b0[:,:,mean_b0.shape[-1]//2], cmap=cm.bone)

MNI_T2 = dpd.read_mni_template()
MNI_T2_data = MNI_T2.get_data()
MNI_T2_affine = MNI_T2.get_affine()

level_iters = [10, 10, 5]
dim = 3
metric = CCMetric(dim)
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, step_length=0.25)
sdr.verbosity = VerbosityLevels.DIAGNOSE
mapping = sdr.optimize(MNI_T2_data, mean_b0, MNI_T2_affine, hardi_affine)
warped_b0 = mapping.transform(mean_b0)
plt.matshow(warped_b0[:,:,warped_b0.shape[-1]//2], cmap=cm.bone)
plt.matshow(MNI_T2_data[:, :, MNI_T2_data.shape[-1]//2], cmap=cm.bone)

new_ni = nib.Nifti1Image(warped_b0, MNI_T2_affine)
new_ni.to_filename('./warped_b0.nii.gz')

afqpath = 'D:/opt/AFQ/'
LOCC_ni = nib.load(os.path.join(afqpath,'templates/callosum2/L_Occipital.nii.gz'))
ROCC_ni = nib.load(os.path.join(afqpath,'templates/callosum2/R_Occipital.nii.gz'))
midsag_ni = nib.load(os.path.join(afqpath,'templates/callosum2/Callosum_midsag.nii.gz'))
LOCC_data = LOCC_ni.get_data()
ROCC_data = ROCC_ni.get_data()
Exemplo n.º 14
0
def img_reg(moving_img, target_img, reg='non-lin'):

    m_img = nib.load(moving_img)
    t_img = nib.load(target_img)

    m_img_data = m_img.get_data()
    t_img_data = t_img.get_data()

    m_img_affine = m_img.affine
    t_img_affine = t_img.affine

    identity = np.eye(4)
    affine_map = AffineMap(identity, t_img_data.shape, t_img_affine,
                           m_img_data.shape, m_img_affine)

    m_img_resampled = affine_map.transform(m_img_data)

    c_of_mass = transform_centers_of_mass(t_img_data, t_img_affine, m_img_data,
                                          m_img_affine)

    tf_m_img_c_mass = c_of_mass.transform(m_img_data)

    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]

    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(t_img_data,
                                  m_img_data,
                                  transform,
                                  params0,
                                  t_img_affine,
                                  m_img_affine,
                                  starting_affine=starting_affine)

    tf_m_img_translat = translation.transform(m_img_data)

    transform = RigidTransform3D()
    params0 = None
    starting_affine = translation.affine
    rigid = affreg.optimize(t_img_data,
                            m_img_data,
                            transform,
                            params0,
                            t_img_affine,
                            m_img_affine,
                            starting_affine=starting_affine)

    tf_m_img_rigid = rigid.transform(m_img_data)

    transform = AffineTransform3D()
    affreg.level_iters = [10, 10, 10]
    affine = affreg.optimize(t_img_data,
                             m_img_data,
                             transform,
                             params0,
                             t_img_affine,
                             m_img_affine,
                             starting_affine=rigid.affine)

    if reg is None or reg == 'non-lin':

        metric = CCMetric(3)
        level_iters = [10, 10, 5]
        sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

        mapping = sdr.optimize(t_img_data, m_img_data, t_img_affine,
                               m_img_affine, affine.affine)

        tf_m_img = mapping.transform(m_img_data)

    elif reg == 'affine':

        tf_m_img_aff = affine.transform(m_img_data)

    return tf_m_img

    metric = CCMetric(3)

    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(t_img_data,
                           m_img_data,
                           t_img_affine,
                           m_img_affine,
                           starting_affine=affine.affine)

    tf_m_img = mapping.transform(m_img_data)
Exemplo n.º 15
0
.. figure:: input.png
   :align: center

   Input images before alignment.
"""

"""
Let's the use the general Registration function with some naive parameters,
such as set `step_length` as 1 assuming maximal step 1 pixel and reasonable
small number of iteration since the deformation with already aligned images
should be minimal.
"""

sdr = SymmetricDiffeomorphicRegistration(metric=SSDMetric(img_ref.ndim),
                                         step_length=1.0,
                                         level_iters=[50, 100],
                                         inv_iter=50,
                                         ss_sigma_factor=0.1,
                                         opt_tol=1.e-3)

"""
Perform the registration with equal images.
"""

mapping = sdr.optimize(img_ref.astype(float), img_ref.astype(float))
img_warp = mapping.transform(img_ref, 'linear')
show_images(img_ref, img_warp, 'output-0')
regtools.plot_2d_diffeomorphic_map(mapping, 5, 'map-0.png')

"""
.. figure:: output-0.png
   :align: center
Exemplo n.º 16
0
of Squared Differences (SSD) is a good choice.
"""

dim = static.ndim
metric = SSDMetric(dim) 

"""
Now we define an instance of the registration class. The SyN algorithm uses
a multi-resolution approach by building a Gaussian Pyramid. We instruct the
registration instance to perform at most $[n_0, n_1, ..., n_k]$ iterations at
each level of the pyramid. The 0-th level corresponds to the finest resolution.
"""

level_iters = [200, 100, 50, 25]

sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, inv_iter = 50)

"""
Now we execute the optimization, which returns a DiffeomorphicMap object,
that can be used to register images back and forth between the static and moving
domains
"""

mapping = sdr.optimize(static, moving)

"""
It is a good idea to visualize the resulting deformation map to make sure the
result is reasonable (at least, visually) 
"""

regtools.plot_2d_diffeomorphic_map(mapping, 10, 'diffeomorphic_map.png')
Exemplo n.º 17
0
        'allen_annotation_invsynned_to_' + subject + '_adjusted.nii.gz')

    # Load images
    reference_image = nib.load(reference_image_path)
    reference = reference_image.get_fdata()
    annotation_image = nib.load(annotation_image_path)
    annotation = annotation_image.get_fdata()
    input_image = nib.load(input_image_path)
    input = input_image.get_fdata()

    # syn
    metric = CCMetric(3)
    level_iters = [10, 10, 5, 5, 5]
    print(iSubject)
    print(datetime.datetime.now())
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static=reference,
                           moving=input,
                           static_grid2world=reference_image.get_qform(),
                           moving_grid2world=input_image.get_qform())

    warped_image = mapping.transform(input)

    warped_reference = mapping.transform_inverse(reference)

    warped_annotation = mapping.transform_inverse(annotation,
                                                  interpolation='nearest')

    # save warps
    input_invwarped_image = nib.Nifti1Image(warped_image, np.eye(4))
Exemplo n.º 18
0
def affine_registration(reference, reference_grid2world, scan,
                        scan_grid2world):
    #get first b0 volumes for both scans
    reference_b0 = reference[:, :, :, 0]
    scan_b0 = scan[:, :, :, 0]

    #In this function we use multiple stages to register the 2 scans
    #providng previous results as initialisation to the next stage,
    #the reason we do this is because registration is a non-convex
    #problem thus it is important to initialise as close to the
    #optiaml value as possible

    #Stage1: we obtain a very rough (and fast) registration by just aligning
    #the centers of mass of the two images
    center_of_mass = transform_centers_of_mass(reference_b0,
                                               reference_grid2world, scan_b0,
                                               scan_grid2world)

    #create the similarity metric (Mutual Information) to be used:
    nbins = 32
    sampling_prop = None  #use all voxels to perform registration
    metric = MutualInformationMetric(nbins, sampling_prop)

    #We use a multi-resolution stratergy to accelerate convergence and avoid
    #getting stuck at local optimas (below are the parameters)
    level_iters = [10000, 1000, 100]
    sigmas = [3.0, 1.0, 0.0
              ]  #parameters for gaussian kernel smoothing at each resolution
    factors = [4, 2, 1]  #subsampling factor

    #optimisation algorithm used is L-BFGS-B
    affreg = AffineRegistration(metric=metric,
                                level_iters=level_iters,
                                sigmas=sigmas,
                                factors=factors)

    #Stage2: Perform a basic translation transform
    transform = TranslationTransform3D()
    translation = affreg.optimize(reference_b0,
                                  scan_b0,
                                  transform,
                                  None,
                                  reference_grid2world,
                                  scan_grid2world,
                                  starting_affine=center_of_mass.affine)

    #Stage3 : optimize previous result with a rigid transform
    #(Includes translation, rotation)
    transform = RigidTransform3D()
    rigid = affreg.optimize(reference_b0,
                            scan_b0,
                            transform,
                            None,
                            reference_grid2world,
                            scan_grid2world,
                            starting_affine=translation.affine)

    #Stage4 : optimize previous result with a affine transform
    #(Includes translation, rotation, scale, shear)
    transform = AffineTransform3D()
    affine = affreg.optimize(reference_b0,
                             scan_b0,
                             transform,
                             None,
                             reference_grid2world,
                             scan_grid2world,
                             starting_affine=rigid.affine)

    if params.reg_type == "SDR":
        #Stage 5 : Symmetric Diffeomorphic Registration
        metric = CCMetric(3)
        level_iters = [400, 200, 100]
        sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
        mapping = sdr.optimize(reference_b0, scan_b0, reference_grid2world,
                               scan_grid2world, affine.affine)
    else:
        mapping = affine
    #Once this is completed we can perform the affine transformation on each
    #volume of scan2

    for volume in range(0, scan.shape[3]):
        #note affine is an AffineMap object,
        #The transform method transforms the input image from co-domain to domain space
        #By default, the transformed image is sampled at a grid defined by the shape of the domain
        #The sampling is performed using linear interpolation (refer to comp vision lab on homographies)
        scan[:, :, :, volume] = mapping.transform(scan[:, :, :, volume])

    return scan
Exemplo n.º 19
0
"""
We want to find an invertible map that transforms the moving image into the
static image. We will use the Cross Correlation metric
"""

metric = CCMetric(3)

"""
Now we define an instance of the registration class. The SyN algorithm uses
a multi-resolution approach by building a Gaussian Pyramid. We instruct the
registration object to perform at most [n_0, n_1, ..., n_k] iterations at
each level of the pyramid. The 0-th level corresponds to the finest resolution.  
"""

level_iters = [10, 10, 5]
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

"""
Execute the optimization, which returns a DiffeomorphicMap object,
that can be used to register images back and forth between the static and moving
domains. We provide the pre-aligning matrix that brings the moving image closer
to the static image
"""

mapping = sdr.optimize(static, moving, static_affine, moving_affine, pre_align)

"""
Now let's warp the moving image and see if it gets similar to the static image
"""

warped_moving = mapping.transform(moving)
Exemplo n.º 20
0
if os.path.isfile(config_fname):
    with open(config_fname,'r') as f:
        options = [tuple(line.strip().split()) for line in f.readlines()]
    options = {opt[0]:opt[1] for opt in options}
else:
    options = {}

step_length = float(options.get('step_length', '0.25'))
inv_tol = float(options.get('inv_tol', '1e-3'))
inv_iter = int(options.get('inv_iter', '20'))
experiment_name = options.get('experiment_name')

level_iters = [400, 200, 100, 50, 25]
dim = 3
metric = SSDMetric(dim, smooth=3)
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, inv_iter=inv_iter, inv_tol=inv_tol, opt_tol=1e-6, step_length=step_length, ss_sigma_factor=1.0)
sdr.verbosity = VerbosityLevels.DIAGNOSE

start = time.time()
mapping = sdr.optimize(cup, sphere)
end = time.time()
elapsed = end - start
print('Elapsed: %e'%(elapsed,))

fwd = np.array(mapping.forward)
bwd = np.array(mapping.backward)

# Get deformed mid slices
z0 = fwd.shape[2]//2
whlines, wvlines = get_deformed_grid(fwd, [z0])
fwd_fname = 'fwd_lines_%s.p'%(experiment_name,)
Exemplo n.º 21
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
Exemplo n.º 22
0
of Squared Differences (SSD) is a good choice.
"""

dim = static.ndim
metric = SSDMetric(dim) 

"""
Now we define an instance of the registration class. The SyN algorithm uses
a multi-resolution approach by building a Gaussian Pyramid. We instruct the
registration instance to perform at most $[n_0, n_1, ..., n_k]$ iterations at
each level of the pyramid. The 0-th level corresponds to the finest resolution.
"""

level_iters = [200, 100, 50, 25]

sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, inv_iter = 50)

"""
Now we execute the optimization, which returns a DiffeomorphicMap object,
that can be used to register images back and forth between the static and moving
domains
"""

mapping = sdr.optimize(static, moving)

"""
It is a good idea to visualize the resulting deformation map to make sure the
result is reasonable (at least, visually) 
"""

regtools.plot_2d_diffeomorphic_map(mapping, 10, 'diffeomorphic_map.png')
Exemplo n.º 23
0
    def generate_warp_field(self, static, moving, static_axis_units,
                            moving_axis_units):
        from numpy import eye
        from dipy.align.imaffine import AffineRegistration
        from dipy.align.transforms import (
            TranslationTransform3D,
            RigidTransform3D,
            AffineTransform3D,
        )
        from dipy.align.imwarp import SymmetricDiffeomorphicRegistration as SDR

        static_g2w = eye(1 + static.ndim)
        moving_g2w = static_g2w.copy()
        params0 = None

        static_g2w[range(static.ndim), range(static.ndim)] = static_axis_units
        moving_g2w[range(moving.ndim), range(moving.ndim)] = moving_axis_units

        self.affreg = AffineRegistration(
            metric=self.metric_lin,
            level_iters=self.level_iters_lin,
            sigmas=self.sigmas,
            factors=self.factors,
            verbosity=self.verbosity,
            ss_sigma_factor=self.ss_sigma_factor,
        )

        self.sdreg = SDR(
            metric=self.metric_syn,
            level_iters=self.level_iters_syn,
            ss_sigma_factor=self.ss_sigma_factor,
        )

        self.translation_tx = self.affreg.optimize(
            static,
            moving,
            TranslationTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine="mass",
        )

        self.rigid_tx = self.affreg.optimize(
            static,
            moving,
            RigidTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine=self.translation_tx.affine,
        )

        self.affine_tx = self.affreg.optimize(
            static,
            moving,
            AffineTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine=self.rigid_tx.affine,
        )

        self.sdr_tx = self.sdreg.optimize(static, moving, static_g2w,
                                          moving_g2w, self.affine_tx.affine)
Exemplo n.º 24
0
class SYNreg(object):
    """
    Wrap full linear + nonlinear(syn) registration, with the assumption that affine  params and warp field are
    estimated from spatially downsampled data.
    """
    def __init__(
        self,
        level_iters_lin,
        sigmas,
        factors,
        level_iters_syn,
        metric_lin=None,
        metric_syn=None,
        ss_sigma_factor=1.0,
        verbosity=0,
    ):
        from dipy.align.metrics import CCMetric
        from dipy.align.imaffine import MutualInformationMetric

        self.level_iters_lin = level_iters_lin
        self.sigmas = sigmas
        self.factors = factors
        self.level_iters_syn = level_iters_syn
        self.ss_sigma_factor = ss_sigma_factor
        self.verbosity = verbosity
        if metric_lin is None:
            nbins = 32
            self.metric_lin = MutualInformationMetric(nbins, None)
        if metric_syn is None:
            self.metric_syn = CCMetric(3)

        self.affreg = None
        self.sdreg = None
        self.translation_tx = None
        self.rigid_tx = None
        self.affine_tx = None
        self.sdr_tx = None

    def generate_warp_field(self, static, moving, static_axis_units,
                            moving_axis_units):
        from numpy import eye
        from dipy.align.imaffine import AffineRegistration
        from dipy.align.transforms import (
            TranslationTransform3D,
            RigidTransform3D,
            AffineTransform3D,
        )
        from dipy.align.imwarp import SymmetricDiffeomorphicRegistration as SDR

        static_g2w = eye(1 + static.ndim)
        moving_g2w = static_g2w.copy()
        params0 = None

        static_g2w[range(static.ndim), range(static.ndim)] = static_axis_units
        moving_g2w[range(moving.ndim), range(moving.ndim)] = moving_axis_units

        self.affreg = AffineRegistration(
            metric=self.metric_lin,
            level_iters=self.level_iters_lin,
            sigmas=self.sigmas,
            factors=self.factors,
            verbosity=self.verbosity,
            ss_sigma_factor=self.ss_sigma_factor,
        )

        self.sdreg = SDR(
            metric=self.metric_syn,
            level_iters=self.level_iters_syn,
            ss_sigma_factor=self.ss_sigma_factor,
        )

        self.translation_tx = self.affreg.optimize(
            static,
            moving,
            TranslationTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine="mass",
        )

        self.rigid_tx = self.affreg.optimize(
            static,
            moving,
            RigidTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine=self.translation_tx.affine,
        )

        self.affine_tx = self.affreg.optimize(
            static,
            moving,
            AffineTransform3D(),
            params0,
            static_g2w,
            moving_g2w,
            starting_affine=self.rigid_tx.affine,
        )

        self.sdr_tx = self.sdreg.optimize(static, moving, static_g2w,
                                          moving_g2w, self.affine_tx.affine)

    def apply_transform(self, moving, moving_axis_units, desired_transform):
        from numpy import eye
        from numpy.linalg import inv

        moving_g2w = eye(1 + moving.ndim)
        moving_g2w[range(moving.ndim), range(moving.ndim)] = moving_axis_units

        txs = dict(affine=self.affine_tx, sdr=self.sdr_tx)
        tx = txs[desired_transform]

        if desired_transform == "sdr":
            result = tx.transform(
                moving,
                image_world2grid=inv(moving_g2w),
                out_shape=moving.shape,
                out_grid2world=moving_g2w,
            )
        else:
            result = tx.transform(
                moving,
                image_grid2world=moving_g2w,
                sampling_grid_shape=moving.shape,
                sampling_grid2world=moving_g2w,
            )

        return result
Exemplo n.º 25
0
import nibabel as nib
from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
from dipy.align.metrics import CCMetric


f_t1 = '/home/eleftherios/Data/reg/t1_fa.nii.gz'
f_fa = '/home/eleftherios/Data/reg/fa.nii.gz'

t1 = nib.load(f_t1).get_data()

img = nib.load(f_fa)

fa = img.get_data()

fa_aff = img.get_affine()

cc = CCMetric(3)

sdr = SymmetricDiffeomorphicRegistration(metric=cc)
sdr.verbosity = 2

sdm = sdr.optimize(static=fa, moving=t1)

t1_warped = sdm.transform(t1)

f_t1_warped = '/home/eleftherios/Data/reg/t1_fa_warped.nii.gz'

nib.save(nib.Nifti1Image(t1_warped, fa_aff), f_t1_warped)

Exemplo n.º 26
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
Exemplo n.º 27
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
Exemplo n.º 28
0
def ROI_registration(datapath, template, t1, b0, roi):

    t1_path = datapath + '/' + t1
    b0_path = datapath + '/' + b0
    roi_path = datapath + '/' + roi
    template_path = datapath + '/' + template

    template_img, template_affine = load_nifti(template_path)
    t1_img, t1_affine = load_nifti(t1_path)
    b0_img, b0_affine = load_nifti(b0_path)
    roi_img, roi_affine = load_nifti(roi_path)

    #diff2struct affine registartion

    moving = b0_img
    moving_grid2world = b0_affine
    static = t1_img
    static_grid2world = t1_affine
    affine_path = datapath + '/' + 'diff2struct_affine.mat'

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

    transform = AffineTransform3D()
    params0 = None

    affine_diff2struct = affreg_diff2struct.optimize(static,
                                                     moving,
                                                     transform,
                                                     params0,
                                                     static_grid2world,
                                                     moving_grid2world,
                                                     starting_affine=None)

    saveAffineMat(affine_diff2struct, affine_path)

    # struct2standard affine registartion

    moving = t1_img
    moving_grid2world = t1_affine
    static = template_img
    static_grid2world = template_affine

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

    transform = AffineTransform3D()
    params0 = None
    affine_struct2standard = affreg_struct2standard.optimize(
        static,
        moving,
        transform,
        params0,
        static_grid2world,
        moving_grid2world,
        starting_affine=None)

    # struct2standard SyN registartion
    pre_align = affine_struct2standard.get_affine()
    metric = CCMetric(3)
    level_iters = [10, 10, 5]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

    mapping = sdr.optimize(static, moving, static_grid2world,
                           moving_grid2world, pre_align)

    warped = mapping.transform_inverse(template_img)
    warped = affine_diff2struct.transform_inverse(warped)
    template_diff_path = datapath + '/' + 'MNI152_diff'
    save_nifti(template_diff_path, warped, b0_affine)

    warped_roi = mapping.transform_inverse(roi_img)
    warped_roi = affine_diff2struct.transform_inverse(warped_roi)
    roi_diff_path = datapath + '/' + roi + '_diff.nii.gz'
    save_nifti(roi_diff_path, warped_roi, b0_affine)

    print("  Done!  ")
Exemplo n.º 29
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
img = nib.load(ffa)

fa = img.get_data()

ffa_template = '/usr/share/data/fsl-mni152-templates/FMRIB58_FA_1mm.nii.gz'

img = nib.load(ffa_template)

fa_template = img.get_data()

fa = np.interp(fa, [fa.min(), fa.max()],
               [fa_template.min(), fa_template.max()])

from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
from dipy.align.metrics import CCMetric

cc = CCMetric(3)

sdr = SymmetricDiffeomorphicRegistration(metric=cc)
sdr.verbosity = 2

sdm = sdr.optimize(static=fa_template, moving=fa)

fa_warped = sdm.transform(fa)

ffa_warped = '/home/eleftherios/Data/reg/fa_to_template_warped.nii.gz'

nib.save(nib.Nifti1Image(fa_warped, img.get_affine()), ffa_warped)

Exemplo n.º 31
0
hardi_affine = ni.get_affine()
b0 = hardi_data[..., gtab.b0s_mask]
mean_b0 = np.mean(b0, -1)

ni_b0 = nib.Nifti1Image(mean_b0, hardi_affine)
ni_b0.to_filename('mean_b0.nii')
plt.matshow(mean_b0[:, :, mean_b0.shape[-1] // 2], cmap=cm.bone)

MNI_T2 = dpd.read_mni_template()
MNI_T2_data = MNI_T2.get_data()
MNI_T2_affine = MNI_T2.get_affine()

level_iters = [10, 10, 5]
dim = 3
metric = CCMetric(dim)
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, step_length=0.25)
sdr.verbosity = VerbosityLevels.DIAGNOSE
mapping = sdr.optimize(MNI_T2_data, mean_b0, MNI_T2_affine, hardi_affine)
warped_b0 = mapping.transform(mean_b0)
plt.matshow(warped_b0[:, :, warped_b0.shape[-1] // 2], cmap=cm.bone)
plt.matshow(MNI_T2_data[:, :, MNI_T2_data.shape[-1] // 2], cmap=cm.bone)

new_ni = nib.Nifti1Image(warped_b0, MNI_T2_affine)
new_ni.to_filename('./warped_b0.nii.gz')

afqpath = 'D:/opt/AFQ/'
LOCC_ni = nib.load(
    os.path.join(afqpath, 'templates/callosum2/L_Occipital.nii.gz'))
ROCC_ni = nib.load(
    os.path.join(afqpath, 'templates/callosum2/R_Occipital.nii.gz'))
midsag_ni = nib.load(
Exemplo n.º 32
0
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)

# Start diffeomorphic registration
diff_name = "ibsr1_to_brainweb_diff.p"
if os.path.isfile(diff_name):
    ibsr_bw_diffmap = pickle.load(open(diff_name, "r"))
else:
    metric = CCMetric(3)
    level_iters = [50, 10]
    sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
    sdr.verbosity = VerbosityLevels.DEBUG
    ibsr_bw_diffmap = sdr.optimize(ibsr1, brainweb, ibsr1_affine, brainweb_affine, ibsr_bw_affmap.affine)
    pickle.dump(ibsr_bw_diffmap, open(diff_name, "w"))

bw_warped_ibsr1 = ibsr_bw_diffmap.transform(brainweb)
rt.overlay_slices(ibsr1, bw_warped_ibsr1, slice_type=0)  # warped (sagital view)
rt.overlay_slices(ibsr1, bw_warped_ibsr1, slice_type=1)  # warped (axial view)
rt.overlay_slices(ibsr1, bw_warped_ibsr1, slice_type=2)  # warped (coronal view)

# Now the initial segmentation
bw_mask_ibsr1 = ibsr_bw_diffmap.transform(brainweb_mask)
bw_mask_ibsr1 = bw_mask_ibsr1 > 0

# Dilate
structure = np.ones((5, 5, 5))
Exemplo n.º 33
0
    def run(self, static_image_files, moving_image_files, prealign_file='',
            inv_static=False, level_iters=[10, 10, 5], metric="cc",
            mopt_sigma_diff=2.0, mopt_radius=4, mopt_smooth=0.0,
            mopt_inner_iter=0.0, mopt_q_levels=256, mopt_double_gradient=True,
            mopt_step_type='', step_length=0.25,
            ss_sigma_factor=0.2, opt_tol=1e-5, inv_iter=20,
            inv_tol=1e-3, out_dir='', out_warped='warped_moved.nii.gz',
            out_inv_static='inc_static.nii.gz',
            out_field='displacement_field.nii.gz'):

        """
        Parameters
        ----------
        static_image_files : string
            Path of the static image file.

        moving_image_files : string
            Path to the moving image file.

        prealign_file : string, optional
            The text file containing pre alignment information via an
             affine matrix.

        inv_static : boolean, optional
            Apply the inverse mapping to the static image (default 'False').

        level_iters : variable int, optional
            The number of iterations at each level of the gaussian pyramid.
             By default, a 3-level scale space with iterations
             sequence equal to [10, 10, 5] will be used. The 0-th
             level corresponds to the finest resolution.

        metric : string, optional
            The metric to be used (Default cc, 'Cross Correlation metric').
            metric available: cc (Cross Correlation), ssd (Sum Squared
            Difference), em (Expectation-Maximization).

        mopt_sigma_diff : float, optional
            Metric option applied on Cross correlation (CC).
            The standard deviation of the Gaussian smoothing kernel to be
            applied to the update field at each iteration (default 2.0)

        mopt_radius : int, optional
            Metric option applied on Cross correlation (CC).
            the radius of the squared (cubic) neighborhood at each voxel to
            be considered to compute the cross correlation. (default 4)

        mopt_smooth : float, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). Smoothness parameter, the
            larger the value the smoother the deformation field.
            (default 1.0 for EM, 4.0 for SSD)

        mopt_inner_iter : int, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). This is number of iterations to be
            performed at each level of the multi-resolution Gauss-Seidel
            optimization algorithm (this is not the number of steps per
            Gaussian Pyramid level, that parameter must be set for the
            optimizer, not the metric). Default 5 for EM, 10 for SSD.

        mopt_q_levels : int, optional
            Metric option applied on Expectation Maximization (EM).
            Number of quantization levels (Default: 256 for EM)

        mopt_double_gradient : bool, optional
            Metric option applied on Expectation Maximization (EM).
            if True, the gradient of the expected static image under the moving
            modality will be added to the gradient of the moving image,
            similarly, the gradient of the expected moving image under the
            static modality will be added to the gradient of the static image.

        mopt_step_type : string, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). The optimization schedule to be
            used in the multi-resolution Gauss-Seidel optimization algorithm
            (not used if Demons Step is selected). Possible value:
            ('gauss_newton', 'demons'). default: 'gauss_newton' for EM,
            'demons' for SSD.

        step_length : float, optional
            the length of the maximum displacement vector of the update
             displacement field at each iteration.

        ss_sigma_factor : float, optional
            parameter of the scale-space smoothing kernel. For example, the
             std. dev. of the kernel will be factor*(2^i) in the isotropic case
             where i = 0, 1, ..., n_scales is the scale.

        opt_tol : float, optional
            the optimization will stop when the estimated derivative of the
             energy profile w.r.t. time falls below this threshold.

        inv_iter : int, optional
            the number of iterations to be performed by the displacement field
             inversion algorithm.

        inv_tol : float, optional
            the displacement field inversion algorithm will stop iterating
             when the inversion error falls below this threshold.

        out_dir : string, optional
            Directory to save the transformed files (default '').

        out_warped : string, optional
            Name of the warped file. (default 'warped_moved.nii.gz').

        out_inv_static : string, optional
            Name of the file to save the static image after applying the
             inverse mapping (default 'inv_static.nii.gz').

        out_field : string, optional
            Name of the file to save the diffeomorphic map.
            (default 'displacement_field.nii.gz')

        """
        io_it = self.get_io_iterator()
        metric = metric.lower()
        if metric not in ['ssd', 'cc', 'em']:
            raise ValueError("Invalid similarity metric: Please"
                             " provide a valid metric like 'ssd', 'cc', 'em'")

        logging.info("Starting Diffeormorphic Registration")
        logging.info('Using {0} Metric'.format(metric.upper()))

        # Init parameter if they are not setup
        init_param = {'ssd': {'mopt_smooth': 4.0,
                              'mopt_inner_iter': 10,
                              'mopt_step_type': 'demons'
                              },
                      'em': {'mopt_smooth': 1.0,
                             'mopt_inner_iter': 5,
                             'mopt_step_type': 'gauss_newton'
                             }
                      }
        mopt_smooth = mopt_smooth or init_param[metric]['mopt_smooth']
        mopt_inner_iter = mopt_inner_iter or  \
            init_param[metric]['mopt_inner_iter']
        mopt_step_type = mopt_step_type or \
            init_param[metric]['mopt_step_type']

        for (static_file, moving_file, owarped_file, oinv_static_file,
             omap_file) in io_it:

            logging.info('Loading static file {0}'.format(static_file))
            logging.info('Loading moving file {0}'.format(moving_file))

            # Loading the image data from the input files into object.
            static_image, static_grid2world = load_nifti(static_file)
            moving_image, moving_grid2world = load_nifti(moving_file)

            # Sanity check for the input image dimensions.
            check_dimensions(static_image, moving_image)

            # Loading the affine matrix.
            prealign = np.loadtxt(prealign_file) if prealign_file else None

            l_metric = {"ssd": SSDMetric(static_image.ndim,
                                         smooth=mopt_smooth,
                                         inner_iter=mopt_inner_iter,
                                         step_type=mopt_step_type
                                         ),
                        "cc": CCMetric(static_image.ndim,
                                       sigma_diff=mopt_sigma_diff,
                                       radius=mopt_radius),
                        "em": EMMetric(static_image.ndim,
                                       smooth=mopt_smooth,
                                       inner_iter=mopt_inner_iter,
                                       step_type=mopt_step_type,
                                       q_levels=mopt_q_levels,
                                       double_gradient=mopt_double_gradient)
                        }

            current_metric = l_metric.get(metric.lower())

            sdr = SymmetricDiffeomorphicRegistration(
                metric=current_metric,
                level_iters=level_iters,
                step_length=step_length,
                ss_sigma_factor=ss_sigma_factor,
                opt_tol=opt_tol,
                inv_iter=inv_iter,
                inv_tol=inv_tol
                )

            mapping = sdr.optimize(static_image, moving_image,
                                   static_grid2world, moving_grid2world,
                                   prealign)

            mapping_data = np.array([mapping.forward.T, mapping.backward.T]).T
            warped_moving = mapping.transform(moving_image)

            # Saving
            logging.info('Saving warped {0}'.format(owarped_file))
            save_nifti(owarped_file, warped_moving, static_grid2world)
            logging.info('Saving Diffeormorphic map {0}'.format(omap_file))
            save_nifti(omap_file, mapping_data, mapping.codomain_world2grid)
def register_save(inputpathdir, target_path, subject, outputpath, figspath,
                  params, registration_types, applydirs, verbose):
    anat_path = get_anat(inputpathdir, subject)
    #myanat = load_nifti(anat_path)
    myanat = nib.load(anat_path)
    anat_data = np.squeeze(myanat.get_data()[..., 0])
    anat_affine = myanat.affine
    anat_hdr = myanat.header
    vox_size = myanat.header.get_zooms()[0]
    #mynifti = load_nifti("/Volumes/Data/Badea/Lab/19abb14/N57437_nii4D.nii")
    #anat_data = np.squeeze(myanat[0])[..., 0]
    #anat_affine = myanat[1]
    #hdr = myanat.header

    mytarget = nib.load(target_path)
    target_data = np.squeeze(mytarget.get_data()[..., 0])
    target_affine = mytarget.affine

    identity = np.eye(4)

    affine_map = AffineMap(identity, target_data.shape, target_affine,
                           anat_data.shape, anat_affine)
    resampled = affine_map.transform(anat_data)
    """
    regtools.overlay_slices(target_data, resampled, None, 0,
                            "target_data", "anat_data", figspath + "resampled_0.png")
    regtools.overlay_slices(target_data, resampled, None, 1,
                            "target_data", "anat_data", figspath + "resampled_1.png")
    regtools.overlay_slices(target_data, resampled, None, 2,
                            "target_data", "anat_data", figspath + "resampled_2.png")
    """
    c_of_mass = transform_centers_of_mass(target_data, target_affine,
                                          anat_data, anat_affine)
    apply_niftis = []
    apply_trks = []
    if inputpathdir in applydirs:
        applyfiles = [anat_path]
    else:
        applyfiles = []
    for applydir in applydirs:
        apply_niftis.extend(get_niftis(applydir, subject))
        apply_trks.extend(get_trks(applydir, subject))

    if "center_mass" in registration_types:

        if apply_trks:
            metric = CCMetric(3)
            level_iters = [10, 10, 5]
            sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
            mapping = sdr.optimize(target_data, anat_data, target_affine,
                                   anat_affine, c_of_mass.affine)

        for apply_nifti in apply_niftis:
            fname = os.path.basename(apply_nifti).split(".")[0]
            fpath = outputpath + fname + "_centermass.nii"
            applynii = nib.load(apply_nifti)
            apply_data = applynii.get_data()
            apply_affine = applynii.affine
            apply_hdr = myanat.header

            if len(np.shape(apply_data)) == 4:
                transformed_all = c_of_mass.transform(apply_data, apply4D=True)
                transformed = transformed_all[:, :, :, 0]
            else:
                transformed_all = c_of_mass.transform(apply_data)
                transformed = transformed_all
            save_nifti(fpath, transformed_all, apply_affine, hdr=apply_hdr)
            if figspath is not None:
                regtools.overlay_slices(target_data, transformed, None, 0,
                                        "target_data", "Transformed",
                                        figspath + fname + "_centermass_1.png")
                regtools.overlay_slices(target_data, transformed, None, 1,
                                        "target_data", "Transformed",
                                        figspath + fname + "_centermass_2.png")
                regtools.overlay_slices(target_data, transformed, None, 2,
                                        "target_data", "Transformed",
                                        figspath + fname + "_centermass_3.png")
            if verbose:
                print("Saved the file at " + fpath)
        #mapping = sdr.optimize(target_data, anat_data, target_affine, anat_affine,
        #                       c_of_mass.affine)
        #warped_moving = mapping.transform(anat_data)
        for apply_trk in apply_trks:

            fname = os.path.basename(apply_trk).split(".")[0]
            fpath = outputpath + fname + "_centermass.trk"

            sft = load_tractogram(apply_trk, 'same')
            target_isocenter = np.diag(
                np.array([-vox_size, vox_size, vox_size, 1]))
            origin_affine = affine_map.affine.copy()
            origin_affine[0][3] = -origin_affine[0][3]
            origin_affine[1][3] = -origin_affine[1][3]
            origin_affine[2][3] = origin_affine[2][3] / vox_size

            origin_affine[1][3] = origin_affine[1][3] / vox_size**2

            # Apply the deformation and correct for the extents
            mni_streamlines = deform_streamlines(
                sft.streamlines,
                deform_field=mapping.get_forward_field(),
                stream_to_current_grid=target_isocenter,
                current_grid_to_world=origin_affine,
                stream_to_ref_grid=target_isocenter,
                ref_grid_to_world=np.eye(4))

            if has_fury:

                show_template_bundles(mni_streamlines,
                                      anat_data,
                                      show=False,
                                      fname=figspath + fname +
                                      '_streamlines_centermass.png')

            sft = StatefulTractogram(mni_streamlines, myanat, Space.RASMM)

            save_tractogram(sft, fpath, bbox_valid_check=False)
            if verbose:
                print("Saved the file at " + fpath)

    metric = MutualInformationMetric(params.nbins, params.sampling_prop)

    if "AffineRegistration" in registration_types:
        affreg = AffineRegistration(metric=metric,
                                    level_iters=params.level_iters,
                                    sigmas=params.sigmas,
                                    factors=params.factors)

        transform = TranslationTransform3D()
        params0 = None
        starting_affine = c_of_mass.affine
        translation = affreg.optimize(target_data,
                                      anat_data,
                                      transform,
                                      params0,
                                      target_affine,
                                      anat_affine,
                                      starting_affine=starting_affine)

        if apply_trks:
            metric = CCMetric(3)
            level_iters = [10, 10, 5]
            sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
            mapping = sdr.optimize(target_data, anat_data, target_affine,
                                   anat_affine, translation.affine)

        for apply_nifti in apply_niftis:
            fname = os.path.basename(apply_nifti).split(".")[0]
            fpath = outputpath + fname + "_affinereg.nii"

            applynii = nib.load(apply_nifti)
            apply_data = applynii.get_data()
            apply_affine = applynii.affine
            apply_hdr = myanat.header

            if len(np.shape(apply_data)) == 4:
                transformed_all = translation.transform(apply_data,
                                                        apply4D=True)
                transformed = transformed_all[:, :, :, 0]
            else:
                transformed_all = translation.transform(apply_data)
                transformed = transformed_all
            save_nifti(fpath, transformed_all, anat_affine, hdr=anat_hdr)
            if figspath is not None:
                regtools.overlay_slices(target_data, transformed, None, 0,
                                        "target_data", "Transformed",
                                        figspath + fname + "_affinereg_1.png")
                regtools.overlay_slices(target_data, transformed, None, 1,
                                        "target_data", "Transformed",
                                        figspath + fname + "_affinereg_2.png")
                regtools.overlay_slices(target_data, transformed, None, 2,
                                        "target_data", "Transformed",
                                        figspath + fname + "_affinereg_3.png")
            if verbose:
                print("Saved the file at " + fpath)

        for apply_trk in apply_trks:

            fname = os.path.basename(apply_trk).split(".")[0]
            fpath = outputpath + fname + "_affinereg.trk"

            sft = load_tractogram(apply_trk, 'same')
            target_isocenter = np.diag(
                np.array([-vox_size, vox_size, vox_size, 1]))
            origin_affine = affine_map.affine.copy()
            origin_affine[0][3] = -origin_affine[0][3]
            origin_affine[1][3] = -origin_affine[1][3]
            origin_affine[2][3] = origin_affine[2][3] / vox_size

            origin_affine[1][3] = origin_affine[1][3] / vox_size**2

            # Apply the deformation and correct for the extents
            mni_streamlines = deform_streamlines(
                sft.streamlines,
                deform_field=mapping.get_forward_field(),
                stream_to_current_grid=target_isocenter,
                current_grid_to_world=origin_affine,
                stream_to_ref_grid=target_isocenter,
                ref_grid_to_world=np.eye(4))

            if has_fury:

                show_template_bundles(mni_streamlines,
                                      anat_data,
                                      show=False,
                                      fname=figspath + fname +
                                      '_streamlines_affinereg.png')

            sft = StatefulTractogram(mni_streamlines, myanat, Space.RASMM)

            save_tractogram(sft, fpath, bbox_valid_check=False)
            if verbose:
                print("Saved the file at " + fpath)

    if "RigidTransform3D" in registration_types:
        transform = RigidTransform3D()
        params0 = None
        if 'translation' not in locals():
            affreg = AffineRegistration(metric=metric,
                                        level_iters=params.level_iters,
                                        sigmas=params.sigmas,
                                        factors=params.factors)
            translation = affreg.optimize(target_data,
                                          anat_data,
                                          transform,
                                          params0,
                                          target_affine,
                                          anat_affine,
                                          starting_affine=c_of_mass.affine)
        starting_affine = translation.affine
        rigid = affreg.optimize(target_data,
                                anat_data,
                                transform,
                                params0,
                                target_affine,
                                anat_affine,
                                starting_affine=starting_affine)

        transformed = rigid.transform(anat_data)

        if apply_trks:
            metric = CCMetric(3)
            level_iters = [10, 10, 5]
            sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
            mapping = sdr.optimize(target_data, anat_data, target_affine,
                                   anat_affine, rigid.affine)

        for apply_nifti in apply_niftis:
            fname = os.path.basename(apply_nifti).split(".")[0]
            fpath = outputpath + fname + "_rigidtransf3d.nii"

            applynii = nib.load(apply_nifti)
            apply_data = applynii.get_data()
            apply_affine = applynii.affine
            apply_hdr = myanat.header

            if len(np.shape(apply_data)) == 4:
                transformed_all = rigid.transform(apply_data, apply4D=True)
                transformed = transformed_all[:, :, :, 0]
            else:
                transformed_all = rigid.transform(apply_data)
                transformed = transformed_all
            save_nifti(fpath, transformed_all, anat_affine, hdr=anat_hdr)
            if figspath is not None:
                regtools.overlay_slices(
                    target_data, transformed, None, 0, "target_data",
                    "Transformed", figspath + fname + "_rigidtransf3d_1.png")
                regtools.overlay_slices(
                    target_data, transformed, None, 1, "target_data",
                    "Transformed", figspath + fname + "_rigidtransf3d_2.png")
                regtools.overlay_slices(
                    target_data, transformed, None, 2, "target_data",
                    "Transformed", figspath + fname + "_rigidtransf3d_3.png")
            if verbose:
                print("Saved the file at " + fpath)

        for apply_trk in apply_trks:

            fname = os.path.basename(apply_trk).split(".")[0]
            fpath = outputpath + fname + "_rigidtransf3d.trk"

            sft = load_tractogram(apply_trk, 'same')
            target_isocenter = np.diag(
                np.array([-vox_size, vox_size, vox_size, 1]))
            origin_affine = affine_map.affine.copy()
            origin_affine[0][3] = -origin_affine[0][3]
            origin_affine[1][3] = -origin_affine[1][3]
            origin_affine[2][3] = origin_affine[2][3] / vox_size

            origin_affine[1][3] = origin_affine[1][3] / vox_size**2

            # Apply the deformation and correct for the extents
            mni_streamlines = deform_streamlines(
                sft.streamlines,
                deform_field=mapping.get_forward_field(),
                stream_to_current_grid=target_isocenter,
                current_grid_to_world=origin_affine,
                stream_to_ref_grid=target_isocenter,
                ref_grid_to_world=np.eye(4))

            if has_fury:

                show_template_bundles(mni_streamlines,
                                      anat_data,
                                      show=False,
                                      fname=figspath + fname +
                                      '_rigidtransf3d.png')

            sft = StatefulTractogram(mni_streamlines, myanat, Space.RASMM)

            save_tractogram(sft, fpath, bbox_valid_check=False)
            if verbose:
                print("Saved the file at " + fpath)

    if "AffineTransform3D" in registration_types:
        transform = AffineTransform3D()
        params0 = None
        starting_affine = rigid.affine
        affine = affreg.optimize(target_data,
                                 anat_data,
                                 transform,
                                 params0,
                                 target_affine,
                                 anat_affine,
                                 starting_affine=starting_affine)

        transformed = affine.transform(anat_data)

        if apply_trks:
            metric = CCMetric(3)
            level_iters = [10, 10, 5]
            sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
            mapping = sdr.optimize(target_data, anat_data, target_affine,
                                   anat_affine, affine.affine)

        for apply_nifti in apply_niftis:
            fname = os.path.basename(apply_nifti).split(".")[0]
            fpath = outputpath + fname + "_affinetransf3d.nii"

            applynii = nib.load(apply_nifti)
            apply_data = applynii.get_data()
            apply_affine = applynii.affine
            apply_hdr = myanat.header

            if len(np.shape(apply_data)) == 4:
                transformed_all = affine.transform(apply_data, apply4D=True)
                transformed = transformed_all[:, :, :, 0]
            else:
                transformed_all = affine.transform(apply_data)
                transformed = transformed_all
            save_nifti(fpath, transformed_all, anat_affine, hdr=anat_hdr)
            if figspath is not None:
                regtools.overlay_slices(
                    target_data, transformed, None, 0, "target_data",
                    "Transformed", figspath + fname + "_affinetransf3d_1.png")
                regtools.overlay_slices(
                    target_data, transformed, None, 1, "target_data",
                    "Transformed", figspath + fname + "_affinetransf3d_2.png")
                regtools.overlay_slices(
                    target_data, transformed, None, 2, "target_data",
                    "Transformed", figspath + fname + "_affinetransf3d_3.png")
            if verbose:
                print("Saved the file at " + fpath)

        for apply_trk in apply_trks:

            fname = os.path.basename(apply_trk).split(".")[0]
            fpath = outputpath + fname + "_affinetransf3d.trk"

            sft = load_tractogram(apply_trk, 'same')
            target_isocenter = np.diag(
                np.array([-vox_size, vox_size, vox_size, 1]))
            origin_affine = affine_map.affine.copy()
            origin_affine[0][3] = -origin_affine[0][3]
            origin_affine[1][3] = -origin_affine[1][3]
            origin_affine[2][3] = origin_affine[2][3] / vox_size

            origin_affine[1][3] = origin_affine[1][3] / vox_size**2

            # Apply the deformation and correct for the extents
            mni_streamlines = deform_streamlines(
                sft.streamlines,
                deform_field=mapping.get_forward_field(),
                stream_to_current_grid=target_isocenter,
                current_grid_to_world=origin_affine,
                stream_to_ref_grid=target_isocenter,
                ref_grid_to_world=np.eye(4))

            if has_fury:

                show_template_bundles(mni_streamlines,
                                      anat_data,
                                      show=False,
                                      fname=figspath + fname +
                                      '_streamlines_affinetransf3d.png')

            sft = StatefulTractogram(mni_streamlines, myanat, Space.RASMM)

            save_tractogram(sft, fpath, bbox_valid_check=False)
            if verbose:
                print("Saved the file at " + fpath)
Exemplo n.º 35
0
    def run(self,
            static_image_files,
            moving_image_files,
            prealign_file='',
            inv_static=False,
            level_iters=[10, 10, 5],
            metric="cc",
            mopt_sigma_diff=2.0,
            mopt_radius=4,
            mopt_smooth=0.0,
            mopt_inner_iter=0.0,
            mopt_q_levels=256,
            mopt_double_gradient=True,
            mopt_step_type='',
            step_length=0.25,
            ss_sigma_factor=0.2,
            opt_tol=1e-5,
            inv_iter=20,
            inv_tol=1e-3,
            out_dir='',
            out_warped='warped_moved.nii.gz',
            out_inv_static='inc_static.nii.gz',
            out_field='displacement_field.nii.gz'):
        """
        Parameters
        ----------
        static_image_files : string
            Path of the static image file.

        moving_image_files : string
            Path to the moving image file.

        prealign_file : string, optional
            The text file containing pre alignment information via an
             affine matrix.

        inv_static : boolean, optional
            Apply the inverse mapping to the static image (default 'False').

        level_iters : variable int, optional
            The number of iterations at each level of the gaussian pyramid.
             By default, a 3-level scale space with iterations
             sequence equal to [10, 10, 5] will be used. The 0-th
             level corresponds to the finest resolution.

        metric : string, optional
            The metric to be used (Default cc, 'Cross Correlation metric').
            metric available: cc (Cross Correlation), ssd (Sum Squared
            Difference), em (Expectation-Maximization).

        mopt_sigma_diff : float, optional
            Metric option applied on Cross correlation (CC).
            The standard deviation of the Gaussian smoothing kernel to be
            applied to the update field at each iteration (default 2.0)

        mopt_radius : int, optional
            Metric option applied on Cross correlation (CC).
            the radius of the squared (cubic) neighborhood at each voxel to
            be considered to compute the cross correlation. (default 4)

        mopt_smooth : float, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). Smoothness parameter, the
            larger the value the smoother the deformation field.
            (default 1.0 for EM, 4.0 for SSD)

        mopt_inner_iter : int, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). This is number of iterations to be
            performed at each level of the multi-resolution Gauss-Seidel
            optimization algorithm (this is not the number of steps per
            Gaussian Pyramid level, that parameter must be set for the
            optimizer, not the metric). Default 5 for EM, 10 for SSD.

        mopt_q_levels : int, optional
            Metric option applied on Expectation Maximization (EM).
            Number of quantization levels (Default: 256 for EM)

        mopt_double_gradient : bool, optional
            Metric option applied on Expectation Maximization (EM).
            if True, the gradient of the expected static image under the moving
            modality will be added to the gradient of the moving image,
            similarly, the gradient of the expected moving image under the
            static modality will be added to the gradient of the static image.

        mopt_step_type : string, optional
            Metric option applied on Sum Squared Difference (SSD) and
            Expectation Maximization (EM). The optimization schedule to be
            used in the multi-resolution Gauss-Seidel optimization algorithm
            (not used if Demons Step is selected). Possible value:
            ('gauss_newton', 'demons'). default: 'gauss_newton' for EM,
            'demons' for SSD.

        step_length : float, optional
            the length of the maximum displacement vector of the update
             displacement field at each iteration.

        ss_sigma_factor : float, optional
            parameter of the scale-space smoothing kernel. For example, the
             std. dev. of the kernel will be factor*(2^i) in the isotropic case
             where i = 0, 1, ..., n_scales is the scale.

        opt_tol : float, optional
            the optimization will stop when the estimated derivative of the
             energy profile w.r.t. time falls below this threshold.

        inv_iter : int, optional
            the number of iterations to be performed by the displacement field
             inversion algorithm.

        inv_tol : float, optional
            the displacement field inversion algorithm will stop iterating
             when the inversion error falls below this threshold.

        out_dir : string, optional
            Directory to save the transformed files (default '').

        out_warped : string, optional
            Name of the warped file. (default 'warped_moved.nii.gz').

        out_inv_static : string, optional
            Name of the file to save the static image after applying the
             inverse mapping (default 'inv_static.nii.gz').

        out_field : string, optional
            Name of the file to save the diffeomorphic map.
            (default 'displacement_field.nii.gz')

        """
        io_it = self.get_io_iterator()
        metric = metric.lower()
        if metric not in ['ssd', 'cc', 'em']:
            raise ValueError("Invalid similarity metric: Please"
                             " provide a valid metric like 'ssd', 'cc', 'em'")

        logging.info("Starting Diffeomorphic Registration")
        logging.info('Using {0} Metric'.format(metric.upper()))

        # Init parameter if they are not setup
        init_param = {
            'ssd': {
                'mopt_smooth': 4.0,
                'mopt_inner_iter': 10,
                'mopt_step_type': 'demons'
            },
            'em': {
                'mopt_smooth': 1.0,
                'mopt_inner_iter': 5,
                'mopt_step_type': 'gauss_newton'
            }
        }
        mopt_smooth = mopt_smooth or init_param[metric]['mopt_smooth']
        mopt_inner_iter = mopt_inner_iter or  \
            init_param[metric]['mopt_inner_iter']
        mopt_step_type = mopt_step_type or \
            init_param[metric]['mopt_step_type']

        for (static_file, moving_file, owarped_file, oinv_static_file,
             omap_file) in io_it:

            logging.info('Loading static file {0}'.format(static_file))
            logging.info('Loading moving file {0}'.format(moving_file))

            # Loading the image data from the input files into object.
            static_image, static_grid2world = load_nifti(static_file)
            moving_image, moving_grid2world = load_nifti(moving_file)

            # Sanity check for the input image dimensions.
            check_dimensions(static_image, moving_image)

            # Loading the affine matrix.
            prealign = np.loadtxt(prealign_file) if prealign_file else None

            l_metric = {
                "ssd":
                SSDMetric(static_image.ndim,
                          smooth=mopt_smooth,
                          inner_iter=mopt_inner_iter,
                          step_type=mopt_step_type),
                "cc":
                CCMetric(static_image.ndim,
                         sigma_diff=mopt_sigma_diff,
                         radius=mopt_radius),
                "em":
                EMMetric(static_image.ndim,
                         smooth=mopt_smooth,
                         inner_iter=mopt_inner_iter,
                         step_type=mopt_step_type,
                         q_levels=mopt_q_levels,
                         double_gradient=mopt_double_gradient)
            }

            current_metric = l_metric.get(metric.lower())

            sdr = SymmetricDiffeomorphicRegistration(
                metric=current_metric,
                level_iters=level_iters,
                step_length=step_length,
                ss_sigma_factor=ss_sigma_factor,
                opt_tol=opt_tol,
                inv_iter=inv_iter,
                inv_tol=inv_tol)

            mapping = sdr.optimize(static_image, moving_image,
                                   static_grid2world, moving_grid2world,
                                   prealign)

            mapping_data = np.array([mapping.forward.T, mapping.backward.T]).T
            warped_moving = mapping.transform(moving_image)

            # Saving
            logging.info('Saving warped {0}'.format(owarped_file))
            save_nifti(owarped_file, warped_moving, static_grid2world)
            logging.info('Saving Diffeomorphic map {0}'.format(omap_file))
            save_nifti(omap_file, mapping_data, mapping.codomain_world2grid)
Exemplo n.º 36
0
                             -ref ' + template_path + ' \
                             -out ' + input_skull_flirted_path + ' \
                             -init ' + input_flirt_path + ' \
                             -verbose 0')
            input_skull_flirted_image = nib.load(input_skull_flirted_path)
            input_skull_flirted = input_skull_flirted_image.get_fdata()
        else:
            print('without skull processing')
            input_skull_flirted = input_flirted

        # SyN
        # metric = SSDMetric(3)
        # metric = EMMetric(3)
        metric = CCMetric(3)
        level_iters = [10, 10, 5, 5, 5]
        sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

        mapping = sdr.optimize(
            static=template,
            moving=input_skull_flirted,
            static_grid2world=template_image.get_qform(),
            moving_grid2world=input_flirted_image.get_qform())
        with open(input_flirted_syn_path, 'wb') as f:
            dump([mapping, metric, level_iters, sdr],
                 f,
                 protocol=4,
                 compression='gzip')

        forw_field = mapping.get_forward_field()
        back_field = mapping.get_backward_field()
        forw_SS = np.sum(np.power(forw_field, 2))
Exemplo n.º 37
0
# allen template flirted cropping
allen_template_flirted_cropped, crop_index = zeroPadImage(
    allen_template_flirted, allen_template_flirted, 0.1)
allen_template_flirted_cropped_image = nib.Nifti1Image(
    allen_template_flirted_cropped, allen_template_flirted_image.affine)
allen_template_flirted_cropped_path = allen_template_flirted_path.split(
    '.')[0] + '_cropped.nii.gz'
print(allen_template_flirted_cropped_path)
nib.save(allen_template_flirted_cropped_image,
         allen_template_flirted_cropped_path)

# SyN flirted images to AMBMC
print('SyN')
metric = CCMetric(3)
level_iters = [10, 10, 5, 5, 5]
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)
mapping = sdr.optimize(
    static=AMBMC_template_zeropadded,
    moving=allen_template_flirted,
    static_grid2world=AMBMC_template_zeropadded_image.get_qform(),
    moving_grid2world=allen_template_flirted_image.get_qform())
with open(allen_template_flirted_syn_path, 'wb') as f:
    dump([mapping, metric, level_iters, sdr],
         f,
         protocol=4,
         compression='gzip')
# with open(allen_template_flirted_syn_path, 'rb') as f:
#     [mapping, metric, level_iters, sdr] = load(f, compression='gzip')

forw_field = mapping.get_forward_field()
back_field = mapping.get_backward_field()
Exemplo n.º 38
0
def align_atlas():
    neo_fname = get_neobrain('train', 1, 'T2')
    neo_nib = nib.load(neo_fname)
    neo = neo_nib.get_data()
    neo_affine = neo_nib.get_affine()

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

    # The first training volume dimensions are about  5cm x 5cm x 8cm
    # The atlas  dimensions are about 7cm x 9cm x 11 cm
    # Assuming isotropic scale, the atlas is about 1.5 times larger than
    # the input image:
    iso_scale = (float(7*9*11)/float(5*5*8))**(1.0/3)
    print(iso_scale)

    #We can use this to constraint the transformation to rigid
    scale = np.eye(4)
    scale[:3,:3] *= iso_scale

    rigid_map_fname = 'atlas_towards_neo1_rigid.p'

    if os.path.isfile(rigid_map_fname):
        rigid_map = pickle.load(open(rigid_map_fname, 'r'))
    else:
        transforms = ['RIGID']
        rigid_map = dipy_align(neo, neo_affine, atlas, atlas_affine,
                         transforms=transforms, prealign=scale)
        pickle.dump(rigid_map, open(rigid_map_fname, 'w'))

    atlas_resampled = rigid_map.transform(atlas)

    # Compare anterior coronal slices
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=10, ltitle='Neo1', rtitle='Atlas');
    # Compare middle coronal slices
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=25, ltitle='Neo1', rtitle='Atlas');
    # Compare posterior coronal slices
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=40, ltitle='Neo1', rtitle='Atlas');

    # Load the peeled atlas
    atlas_wcerebellum_fname = get_neobrain('atlas', 'neo-withCerebellum', None)
    atlas_wcerebellum_nib = nib.load(atlas_wcerebellum_fname)
    atlas_wcerebellum = atlas_wcerebellum_nib.get_data()
    atlas_wcerebellum_affine = atlas_wcerebellum_nib.get_affine()

    # Configure diffeomorphic registration
    diff_map_name = 'atlas_towards_neo1_diff.p'
    if os.path.isfile(diff_map_name):
        diff_map = pickle.load(open(diff_map_name, 'r'))
    else:
        metric = CCMetric(3)
        sdr = SymmetricDiffeomorphicRegistration(metric)
        # The atlases are not aligned in physical space!! use atlas_affine instead of atlas_wcerebellum_affine
        diff_map = sdr.optimize(neo, atlas_wcerebellum, neo_affine, atlas_affine, prealign=rigid_map.affine)
        pickle.dump(diff_map, open(diff_map_name, 'w'))

    atlas_wcerebellum_deformed = diff_map.transform(atlas_wcerebellum)

    # Before and after diffeomorphic registration
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=10, ltitle='Neo1', rtitle='Atlas');
    rt.overlay_slices(neo, atlas_wcerebellum_deformed, slice_type=2, slice_index=10, ltitle='Neo1', rtitle='Atlas');
    # Before and after diffeomorphic registration
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=25, ltitle='Neo1', rtitle='Atlas');
    rt.overlay_slices(neo, atlas_wcerebellum_deformed, slice_type=2, slice_index=25, ltitle='Neo1', rtitle='Atlas');
    # Before and after diffeomorphic registration
    rt.overlay_slices(neo, atlas_resampled, slice_type=2, slice_index=40, ltitle='Neo1', rtitle='Atlas');
    rt.overlay_slices(neo, atlas_wcerebellum_deformed, slice_type=2, slice_index=40, ltitle='Neo1', rtitle='Atlas');
    
    
    
    
    # Now all volumes
    atlas_fname = get_neobrain('atlas', 'neo-withSkull', None)
    atlas_nib = nib.load(atlas_fname)
    atlas = atlas_nib.get_data()
    atlas_affine = atlas_nib.get_affine()
    
    atlas_wcerebellum_fname = get_neobrain('atlas', 'neo-withCerebellum', None)
    atlas_wcerebellum_nib = nib.load(atlas_wcerebellum_fname)
    atlas_wcerebellum = atlas_wcerebellum_nib.get_data()
    atlas_wcerebellum_affine = atlas_wcerebellum_nib.get_affine()
    
    
    
    
    
    idx = 2
    neoi_fname = get_neobrain('train', idx, 'T2')
    neoi_nib = nib.load(neoi_fname)
    neoi = neoi_nib.get_data()
    neoi_affine = neoi_nib.get_affine()
    
    iso_scale = (float(7*9*11)/float(5*5*8))**(1.0/3)
    print(iso_scale)
    

    #We can use this to constraint the transformation to rigid
    scale = np.eye(4)
    scale[:3,:3] *= iso_scale

    rigid_map_fname = 'atlas_towards_neo%d_affine.p'%(idx,)

    if os.path.isfile(rigid_map_fname):
        rigid_map = pickle.load(open(rigid_map_fname, 'r'))
    else:
        transforms = ['RIGID', 'AFFINE']
        level_iters = [[10000, 1000, 100], [100]]
        rigid_map = dipy_align(neoi, neoi_affine, atlas, atlas_affine,
                               transforms=transforms,
                               level_iters=level_iters,
                               prealign=scale)
        pickle.dump(rigid_map, open(rigid_map_fname, 'w'))

    atlas_resampled = rigid_map.transform(atlas)
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index = 6)
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index = 10)
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index = 25)
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index = 40)
    
    diff_map_name = 'atlas_towards_neo%d_diff.p'%(idx,)
    if os.path.isfile(diff_map_name):
        diff_map = pickle.load(open(diff_map_name, 'r'))
    else:
        metric = CCMetric(3)
        sdr = SymmetricDiffeomorphicRegistration(metric)
        # The atlases are not aligned in physical space!! use atlas_affine instead of atlas_wcerebellum_affine
        diff_map = sdr.optimize(neoi, atlas_wcerebellum, neoi_affine, atlas_affine, prealign=rigid_map.affine)
        pickle.dump(diff_map, open(diff_map_name, 'w'))

    atlas_wcerebellum_deformed = diff_map.transform(atlas_wcerebellum)

    # Before and after diffeomorphic registration
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index=6, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    rt.overlay_slices(neoi, atlas_wcerebellum_deformed, slice_type=2, slice_index=6, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index=10, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    rt.overlay_slices(neoi, atlas_wcerebellum_deformed, slice_type=2, slice_index=10, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    # Before and after diffeomorphic registration
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index=25, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    rt.overlay_slices(neoi, atlas_wcerebellum_deformed, slice_type=2, slice_index=25, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    # Before and after diffeomorphic registration
    rt.overlay_slices(neoi, atlas_resampled, slice_type=2, slice_index=40, ltitle='Neo%d'%(idx,), rtitle='Atlas');
    rt.overlay_slices(neoi, atlas_wcerebellum_deformed, slice_type=2, slice_index=40, ltitle='Neo%d'%(idx,), rtitle='Atlas');
Exemplo n.º 39
0
                                  moving_affine,
                                  starting_affine=rigid_map.affine)
transformed = highres_map.transform(moving)
"""
We now perform the non-rigid deformation using the Symmetric Diffeomorphic
Registration (SyN) Algorithm proposed by Avants et al. [Avants09]_ (also
implemented in the ANTs software [Avants11]_):

"""

from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
from dipy.align.metrics import CCMetric

metric = CCMetric(3)
level_iters = [10, 10, 5]
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters)

mapping = sdr.optimize(static, moving, static_affine, moving_affine,
                       highres_map.affine)
warped_moving = mapping.transform(moving)
"""
We show the registration result with:

"""

from dipy.viz import regtools

regtools.overlay_slices(static, warped_moving, None, 0, 'Static', 'Moving',
                        'transformed_sagittal.png')
regtools.overlay_slices(static, warped_moving, None, 1, 'Static', 'Moving',
                        'transformed_coronal.png')
Exemplo n.º 40
0
"""
.. figure:: input.png
   :align: center

   Input images before alignment.
"""
"""
Let's use the general Registration function with some naive parameters,
such as set `step_length` as 1 assuming maximal step 1 pixel and a reasonably
small number of iterations since the deformation with already aligned images
should be minimal.
"""

sdr = SymmetricDiffeomorphicRegistration(metric=SSDMetric(img_ref.ndim),
                                         step_length=1.0,
                                         level_iters=[50, 100],
                                         inv_iter=50,
                                         ss_sigma_factor=0.1,
                                         opt_tol=1.e-3)
"""
Perform the registration with equal images.
"""

mapping = sdr.optimize(img_ref.astype(float), img_ref.astype(float))
img_warp = mapping.transform(img_ref, 'linear')
show_images(img_ref, img_warp, 'output-0')
regtools.plot_2d_diffeomorphic_map(mapping, 5, 'map-0.png')
"""
.. figure:: output-0.png
   :align: center
.. figure:: map-0.png
   :align: center
Exemplo n.º 41
0
def syn_registration(moving,
                     static,
                     moving_affine=None,
                     static_affine=None,
                     step_length=0.25,
                     metric='CC',
                     dim=3,
                     level_iters=None,
                     prealign=None,
                     **metric_kwargs):
    """Register a 2D/3D source image (moving) to a 2D/3D target image (static).

    Parameters
    ----------
    moving, static : array or nib.Nifti1Image or str.
        Either as a 2D/3D array or as a nifti image object, or as
        a string containing the full path to a nifti file.
    moving_affine, static_affine : 4x4 array, optional.
        Must be provided for `data` provided as an array. If provided together
        with Nifti1Image or str `data`, this input will over-ride the affine
        that is stored in the `data` input. Default: use the affine stored
        in `data`.
    metric : string, optional
        The metric to be optimized. One of `CC`, `EM`, `SSD`,
        Default: 'CC' => CCMetric.
    dim: int (either 2 or 3), optional
       The dimensions of the image domain. Default: 3
    level_iters : list of int, optional
        the number of iterations at each level of the Gaussian Pyramid (the
        length of the list defines the number of pyramid levels to be
        used). Default: [10, 10, 5].
    metric_kwargs : dict, optional
        Parameters for initialization of the metric object. If not provided,
        uses the default settings of each metric.

    Returns
    -------
    warped_moving : ndarray
        The data in `moving`, warped towards the `static` data.
    forward : ndarray (..., 3)
        The vector field describing the forward warping from the source to the
        target.
    backward : ndarray (..., 3)
        The vector field describing the backward warping from the target to the
        source.
    """
    level_iters = level_iters or [10, 10, 5]

    static, static_affine, moving, moving_affine, _ = \
        _handle_pipeline_inputs(moving, static,
                                moving_affine=moving_affine,
                                static_affine=static_affine,
                                starting_affine=None)

    use_metric = syn_metric_dict[metric.upper()](dim, **metric_kwargs)

    sdr = SymmetricDiffeomorphicRegistration(use_metric,
                                             level_iters,
                                             step_length=step_length)

    mapping = sdr.optimize(static,
                           moving,
                           static_grid2world=static_affine,
                           moving_grid2world=moving_affine,
                           prealign=prealign)

    warped_moving = mapping.transform(moving)
    return warped_moving, mapping
Exemplo n.º 42
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