Пример #1
0
def test_affine_registration():
    moving = subset_b0
    static = subset_b0
    moving_affine = static_affine = np.eye(4)
    xformed, affine = affine_registration(moving, static,
                                          moving_affine=moving_affine,
                                          static_affine=static_affine,
                                          level_iters=[5, 5],
                                          sigmas=[3, 1],
                                          factors=[2, 1])

    # We don't ask for much:
    npt.assert_almost_equal(affine[:3, :3], np.eye(3), decimal=1)

    with pytest.raises(ValueError):
        # For array input, must provide affines:
        xformed, affine = affine_registration(moving, static)

    # If providing nifti image objects, don't need to provide affines:
    moving_img = nib.Nifti1Image(moving, moving_affine)
    static_img = nib.Nifti1Image(static, static_affine)
    xformed, affine = affine_registration(moving_img, static_img)
    npt.assert_almost_equal(affine[:3, :3], np.eye(3), decimal=1)

    # Using strings with full paths as inputs also works:
    t1_name, b0_name = dpd.get_fnames('syn_data')
    moving = b0_name
    static = t1_name
    xformed, affine = affine_registration(moving, static,
                                          level_iters=[5, 5],
                                          sigmas=[3, 1],
                                          factors=[4, 2])
    npt.assert_almost_equal(affine[:3, :3], np.eye(3), decimal=1)
Пример #2
0
 def prealign(self, afq_object, row, save=True):
     prealign_file = afq_object._get_fname(
         row, '_prealign_from-DWI_to-MNI_xfm.npy')
     if not op.exists(prealign_file):
         reg_subject_img, _ = afq_object._reg_img(
             afq_object.reg_subject, True, row)
         start_time = time()
         _, aff = affine_registration(
             reg_subject_img,
             afq_object.reg_template_img,
             **self.affine_kwargs)
         row['timing']['Registration_pre_align'] =\
             row['timing']['Registration_pre_align'] + time() - start_time
         if save:
             np.save(prealign_file, aff)
             meta_fname = afq_object._get_fname(
                 row, '_prealign_from-DWI_to-MNI_xfm.json')
             meta = dict(type="rigid")
             afd.write_json(meta_fname, meta)
         else:
             return aff
     if save:
         return prealign_file
     else:
         return np.load(prealign_file)
Пример #3
0
    def __call__(self):
        xformed_img, reg_affine = affine_registration(
            self.sample_data,  # moving image data
            self.static_data,  # static or template image data
            moving_affine=self.sample_affine,
            static_affine=self.static_affine,
            nbins=32,
            metric='MI',
            pipeline=self.pipeline,
            level_iters=[10000, 1000, 100],
            sigmas=[3.0, 1.0, 0.0],
            factors=[4, 2, 1])

        return xformed_img
Пример #4
0
 def prealign(self, subses_dict, reg_subject, reg_template, save=True):
     prealign_file = get_fname(subses_dict,
                               '_prealign_from-DWI_to-MNI_xfm.npy')
     if not op.exists(prealign_file):
         start_time = time()
         _, aff = affine_registration(reg_subject, reg_template,
                                      **self.affine_kwargs)
         meta = dict(type="rigid", timing=time() - start_time)
         if save:
             np.save(prealign_file, aff)
             meta_fname = get_fname(subses_dict,
                                    '_prealign_from-DWI_to-MNI_xfm.json')
             afd.write_json(meta_fname, meta)
         else:
             return aff
     if save:
         return prealign_file
     else:
         return np.load(prealign_file)
Пример #5
0
def Sequential_Registration_b0(static,
                               static_grid2world,
                               moving,
                               moving_grid2world,
                               level_iters=[5],
                               sigmas=[3.0],
                               factors=[2]):
    pipeline = [center_of_mass, translation, rigid, affine]
    xformed_img, reg_affine = affine_registration(
        moving,
        static,
        moving_affine=moving_grid2world,
        static_affine=static_grid2world,
        nbins=16,
        metric='MI',
        pipeline=pipeline,
        level_iters=level_iters,
        sigmas=sigmas,
        factors=factors)
    affine_map = AffineMap(reg_affine, static.shape, static_grid2world,
                           moving.shape, moving_grid2world)
    return xformed_img, reg_affine, affine_map
Пример #6
0
def reg_func(figname, static_mask=None, moving_mask=None):
    """Convenience function for registration using a pipeline.
       Uses variables in global scope, except for static_mask and moving_mask.
    """

    pipeline = [translation, rigid]

    xformed_img, reg_affine = affine_registration(moving,
                                                  static,
                                                  moving_affine=moving_affine,
                                                  static_affine=static_affine,
                                                  nbins=32,
                                                  metric='MI',
                                                  pipeline=pipeline,
                                                  level_iters=level_iters,
                                                  sigmas=sigmas,
                                                  factors=factors,
                                                  static_mask=static_mask,
                                                  moving_mask=moving_mask)

    regtools.overlay_slices(static, xformed_img, None, 2, "Static",
                            "Transformed", figname)

    return
Пример #7
0
def test_affine_registration():
    moving = subset_b0
    static = subset_b0
    moving_affine = static_affine = np.eye(4)
    xformed, affine_mat = affine_registration(moving, static,
                                              moving_affine=moving_affine,
                                              static_affine=static_affine,
                                              level_iters=[5, 5],
                                              sigmas=[3, 1],
                                              factors=[2, 1])

    # We don't ask for much:
    npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)

    # [center_of_mass] + ret_metric=True should raise an error
    with pytest.raises(ValueError):
        # For array input, must provide affines:
        xformed, affine_mat = affine_registration(moving, static,
                                                  moving_affine=moving_affine,
                                                  static_affine=static_affine,
                                                  pipeline=["center_of_mass"],
                                                  ret_metric=True)

    # Define list of methods
    reg_methods = ["center_of_mass", "translation", "rigid",
                   "rigid_isoscaling", "rigid_scaling", "affine",
                   center_of_mass, translation, rigid,
                   rigid_isoscaling, rigid_scaling, affine]

    # Test methods individually (without returning any metric)
    for func in reg_methods:
        xformed, affine_mat = affine_registration(moving, static,
                                                  moving_affine=moving_affine,
                                                  static_affine=static_affine,
                                                  level_iters=[5, 5],
                                                  sigmas=[3, 1],
                                                  factors=[2, 1],
                                                  pipeline=[func])
        # We don't ask for much:
        npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)

    # Bad method
    with pytest.raises(ValueError, match=r'^pipeline\[0\] must be one.*foo.*'):
        affine_registration(
            moving, static, moving_affine, static_affine, pipeline=['foo'])

    # Test methods individually (returning quality metric)
    expected_nparams = [0, 3, 6, 7, 9, 12] * 2
    assert len(expected_nparams) == len(reg_methods)
    for i, func in enumerate(reg_methods):
        if func in ('center_of_mass', center_of_mass):
            # can't return metric
            with pytest.raises(ValueError, match='cannot return any quality'):
                affine_registration(
                    moving, static, moving_affine, static_affine,
                    pipeline=[func], ret_metric=True)
            continue

        xformed, affine_mat, \
            xopt, fopt = affine_registration(moving, static,
                                             moving_affine=moving_affine,
                                             static_affine=static_affine,
                                             level_iters=[5, 5],
                                             sigmas=[3, 1],
                                             factors=[2, 1],
                                             pipeline=[func],
                                             ret_metric=True)
        # Expected number of optimization parameters
        npt.assert_equal(len(xopt), expected_nparams[i])
        # Optimization metric must be a single numeric value
        npt.assert_equal(isinstance(fopt, (int, float)), True)

    with pytest.raises(ValueError):
        # For array input, must provide affines:
        xformed, affine_mat = affine_registration(moving, static)

    # Not supported transform names should raise an error
    npt.assert_raises(ValueError, affine_registration, moving, static,
                      moving_affine, static_affine,
                      pipeline=["wrong_transform"])

    # If providing nifti image objects, don't need to provide affines:
    moving_img = nib.Nifti1Image(moving, moving_affine)
    static_img = nib.Nifti1Image(static, static_affine)
    xformed, affine_mat = affine_registration(moving_img, static_img)
    npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)

    # Using strings with full paths as inputs also works:
    t1_name, b0_name = dpd.get_fnames('syn_data')
    moving = b0_name
    static = t1_name
    xformed, affine_mat = affine_registration(moving, static,
                                              level_iters=[5, 5],
                                              sigmas=[3, 1],
                                              factors=[4, 2])
    npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)
Пример #8
0
This interface constructs a pipeline of operations as a sequence of functions
that each implement one of the transforms.
"""

pipeline = [center_of_mass, translation, rigid, affine]
"""
And then applies the functions in the pipeline on the input (from left to
right) with a call to an `affine_registration` function, which takes optional
settings for things like the iterations, sigmas and factors.
"""

xformed_img, reg_affine = affine_registration(moving,
                                              static,
                                              moving_affine=moving_affine,
                                              static_affine=static_affine,
                                              nbins=32,
                                              metric='MI',
                                              pipeline=pipeline,
                                              level_iters=level_iters,
                                              sigmas=sigmas,
                                              factors=factors)

regtools.overlay_slices(static, xformed_img, None, 0, "Static", "Transformed",
                        "xformed_affine_0.png")
regtools.overlay_slices(static, xformed_img, None, 1, "Static", "Transformed",
                        "xformed_affine_1.png")
regtools.overlay_slices(static, xformed_img, None, 2, "Static", "Transformed",
                        "xformed_affine_2.png")
"""

.. figure:: xformed_affine_0.png
   :align: center
Пример #9
0
#
#     To find the right place for the waypoint ROIs, we calculate a non-linear
#     transformation between the individual's brain DWI measurement (the b0
#     measurements) and the MNI T2 template.
#     Before calculating this non-linear warping, we perform a pre-alignment
#     using an affine transformation.

print("Registering to template...")
MNI_T2_img = afd.read_mni_template()

if not op.exists(op.join(working_dir, 'mapping.nii.gz')):
    import dipy.core.gradients as dpg
    gtab = dpg.gradient_table(hardi_fbval, hardi_fbvec)
    b0 = np.mean(img.get_fdata()[..., gtab.b0s_mask], -1)
    # Prealign using affine registration
    _, prealign = affine_registration(b0, MNI_T2_img.get_fdata(), img.affine,
                                      MNI_T2_img.affine)

    # Then register using a non-linear registration using the affine for
    # prealignment
    warped_hardi, mapping = reg.syn_register_dwi(hardi_fdata,
                                                 gtab,
                                                 prealign=prealign)
    reg.write_mapping(mapping, op.join(working_dir, 'mapping.nii.gz'))
else:
    mapping = reg.read_mapping(op.join(working_dir, 'mapping.nii.gz'), img,
                               MNI_T2_img)

##########################################################################
# Read in bundle specification
# -------------------------------------------
# The waypoint ROIs, in addition to bundle probability maps are stored in this
Пример #10
0
    def run(self, static_image_files, moving_image_files, transform='affine',
            nbins=32, sampling_prop=None, metric='mi',
            level_iters=[10000, 1000, 100], sigmas=[3.0, 1.0, 0.0],
            factors=[4, 2, 1], progressive=True, save_metric=False,
            out_dir='', out_moved='moved.nii.gz', out_affine='affine.txt',
            out_quality='quality_metric.txt'):
        """
        Parameters
        ----------
        static_image_files : string
            Path to the static image file.

        moving_image_files : string
            Path to the moving image file.

        transform : string, optional
            com: center of mass, trans: translation, rigid: rigid body,
            rigid_isoscaling: rigid body + isotropic scaling, rigid_scaling:
            rigid body + scaling, affine: full affine including translation,
            rotation, shearing and scaling.

        nbins : int, optional
            Number of bins to discretize the joint and marginal PDF.

        sampling_prop : int, optional
            Number ([0-100]) of voxels for calculating the PDF.
             'None' implies all voxels.

        metric : string, optional
            Similarity metric for gathering mutual information).

        level_iters : variable int, optional
            The number of iterations at each scale of the scale space.
             `level_iters[0]` corresponds to the coarsest scale,
             `level_iters[-1]` the finest, where n is the length of the
              sequence.

        sigmas : variable floats, optional
            Custom smoothing parameter to build the scale space (one parameter
             for each scale).

        factors : variable floats, optional
            Custom scale factors to build the scale space (one factor for each
             scale).

        progressive : boolean, optional
            Enable/Disable the progressive registration.

        save_metric : boolean, optional
            If true, quality assessment metric are saved in
            'quality_metric.txt'.

        out_dir : string, optional
            Directory to save the transformed image and the affine matrix
             (default current directory).

        out_moved : string, optional
            Name for the saved transformed image.

        out_affine : string, optional
            Name for the saved affine matrix.

        out_quality : string, optional
            Name of the file containing the saved quality
             metric.
        """

        io_it = self.get_io_iterator()
        transform = transform.lower()
        metric = metric.upper()
        if metric != 'MI':
            raise ValueError("Invalid similarity metric: Please provide a"
                             "valid metric.")

        if progressive:
            pipeline_opt = {
                "com": ["center_of_mass"],
                "trans": ["center_of_mass", "translation"],
                "rigid": ["center_of_mass", "translation", "rigid"],
                "rigid_isoscaling": ["center_of_mass", "translation",
                                     "rigid_isoscaling"],
                "rigid_scaling": ["center_of_mass", "translation",
                                  "rigid_scaling"],
                "affine": ["center_of_mass", "translation", "rigid", "affine"]}
        else:
            pipeline_opt = {
                "com": ["center_of_mass"],
                "trans": ["center_of_mass", "translation"],
                "rigid": ["center_of_mass", "rigid"],
                "rigid_isoscaling": ["center_of_mass", "rigid_isoscaling"],
                "rigid_scaling": ["center_of_mass", "rigid_scaling"],
                "affine": ["center_of_mass", "affine"]}

        pipeline = pipeline_opt.get(transform)

        if pipeline is None:
            raise ValueError('Invalid transformation:'
                             ' Please see program\'s help'
                             ' for allowed values of'
                             ' transformation.')

        for static_img, mov_img, moved_file, affine_matrix_file, \
                qual_val_file in io_it:

            # Load the data from the input files and store into objects.
            static, static_grid2world = load_nifti(static_img)
            moving, moving_grid2world = load_nifti(mov_img)

            check_dimensions(static, moving)

            starting_affine = None

            # If only center of mass is selected do not return metric
            if pipeline == ["center_of_mass"]:
                moved_image, affine_matrix = \
                    affine_registration(moving,
                                        static,
                                        moving_grid2world,
                                        static_grid2world,
                                        pipeline,
                                        starting_affine,
                                        metric,
                                        level_iters,
                                        sigmas,
                                        factors,
                                        nbins=nbins,
                                        sampling_proportion=sampling_prop)
            else:
                moved_image, affine_matrix, xopt, fopt = \
                    affine_registration(moving,
                                        static,
                                        moving_grid2world,
                                        static_grid2world,
                                        pipeline,
                                        starting_affine,
                                        metric,
                                        level_iters,
                                        sigmas,
                                        factors,
                                        ret_metric=True,
                                        nbins=nbins,
                                        sampling_proportion=sampling_prop)

                """
                Saving the moved image file and the affine matrix.
                """
                logging.info("Optimal parameters: {0}".format(str(xopt)))
                logging.info("Similarity metric: {0}".format(str(fopt)))

                if save_metric:
                    save_qa_metric(qual_val_file, xopt, fopt)

            save_nifti(moved_file, moved_image, static_grid2world)
            np.savetxt(affine_matrix_file, affine_matrix)
Пример #11
0
Файл: core.py Проект: nrdg/hmc
def hmc(data, gtab, mask=None, b0_ref=0, affine=None):
    data, affine = read_img_arr_or_path(data, affine=affine)
    if isinstance(gtab, collections.Sequence):
        gtab = dpg.gradient_table(*gtab)

    # We fix b0 to be one volume, registered to one of the
    # b0 volumes (first, per default):
    if np.sum(gtab.b0s_mask) > 1:
        b0_img = nib.Nifti1Image(data[..., gtab.b0s_mask], affine)
        trans_b0, b0_affines = dpa.register_series(b0_img, ref=b0_ref)
        ref_data = np.mean(trans_b0, -1)[..., np.newaxis]
    else:
        # There's only one b0 and we register everything to it
        trans_b0 = ref_data = data[..., gtab.b0s_mask]

    moving_data = data[..., ~gtab.b0s_mask]
    moving_bvals = gtab.bvals[~gtab.b0s_mask]
    moving_bvecs = gtab.bvecs[~gtab.b0s_mask]
    mask = np.ones(ref_data.shape[:3], dtype=bool)
    mask[np.where(ref_data[..., 0] == 0)] = False
    moved = []
    affines = []

    # We fit the isotropic prediction once for all the data:
    sfm_all = SFM4HMC(
        gtab,
        isotropic=ExponentialIsotropicModel)

    sff_all, iso_params = sfm_all.fit(data, alpha=10e-10, mask=mask, tol=10e-10, iso_params=None)

    for loo in range(moving_data.shape[-1]):
        print(loo)
        loo_idxer = np.ones(moving_data.shape[-1]).astype(bool)
        loo_idxer[loo] = False

        in_data = np.concatenate([ref_data, moving_data[..., loo_idxer]], -1)
        in_gtab = dpg.gradient_table(
            np.concatenate([np.array([0]), moving_bvals[loo_idxer]]),
            np.concatenate([np.array([[0, 0, 0]]), moving_bvecs[loo_idxer]]))

        sfm = SFM4HMC(
            in_gtab,
            isotropic=ExponentialIsotropicModel)

        t1 = time.time()
        sff, _ = sfm.fit(in_data, mask=mask, alpha=10e-10, iso_params=iso_params)
        t2 = time.time()
        print(t2 - t1)
        out_data = moving_data[..., ~loo_idxer]
        out_gtab = dpg.gradient_table(moving_bvals[~loo_idxer],
                                      moving_bvecs[~loo_idxer])

        out_pred = sff.predict(out_gtab, S0=ref_data[..., 0])
        t1 = time.time()
        resampled, out_affine = dpa.affine_registration(
            out_data[..., 0],
            out_pred,
            moving_affine=affine,
            static_affine=affine,
            pipeline=[dpa.affine],
            level_iters=[1000, 100, 10])
        t2 = time.time()
        print(t2 - t1)
        moved.append(resampled)
        affines.append(out_affine)
        in_data[..., loo] = resampled
        # XXX Also rotate the b-vector here
        new_out_gtab = dpg.reorient_bvecs(out_gtab, [out_affine])
        moving_bvals[~loo_idxer] = new_out_gtab.bvals
        moving_bvecs[~loo_idxer] = new_out_gtab.bvecs

    return moved, affines

# Reuse USV from a single SVD decomposition of X at the beginning of each
# loop through all of the volumes. Should speed up the RR fit in every volume.
# <= We can't do that, because the directions are different each time

# Use a sliding window to fit only to n nearest neighbors.

# Fit isotropic component once per voxel and be done with it
Пример #12
0
#     transformation between the individual's brain DWI measurement (the b0
#     measurements) and the MNI T1 template.
#     Before calculating this non-linear warping, we perform a pre-alignment
#     using an affine transformation.

print("Registering to template...")

MNI_T1w_img = afd.read_mni_template(weight="T1w")

if not op.exists(op.join(working_dir, 'mapping.nii.gz')):
    import dipy.core.gradients as dpg
    gtab = dpg.gradient_table(hardi_fbval, hardi_fbvec)
    # Prealign using affine registration
    _, prealign = affine_registration(
        apm,
        MNI_T1w_img.get_fdata(),
        img.affine,
        MNI_T1w_img.affine)

    # Then register using a non-linear registration using the affine for
    # prealignment
    warped_hardi, mapping = reg.syn_register_dwi(hardi_fdata, gtab,
                                                 prealign=prealign)
    reg.write_mapping(mapping, op.join(working_dir, 'mapping.nii.gz'))
else:
    mapping = reg.read_mapping(op.join(working_dir, 'mapping.nii.gz'),
                               img, MNI_T1w_img)


##########################################################################
# Bundle specification