예제 #1
0
    def _register_neighb_to_model(self, model_bundle, neighb_streamlines,
                                  metric=None, x0=None, bounds=None,
                                  select_model=400, select_target=600,
                                  method='L-BFGS-B',
                                  nb_pts=20, num_threads=None):

        if self.verbose:
            print('# Local SLR of neighb_streamlines to model')
            t = time()

        if metric is None or metric == 'symmetric':
            metric = BundleMinDistanceMetric(num_threads=num_threads)
        if metric == 'asymmetric':
            metric = BundleMinDistanceAsymmetricMetric()
        if metric == 'diagonal':
            metric = BundleSumDistanceMatrixMetric()

        if x0 is None:
            x0 = 'similarity'

        if bounds is None:
            bounds = [(-30, 30), (-30, 30), (-30, 30),
                      (-45, 45), (-45, 45), (-45, 45), (0.8, 1.2)]

        # TODO this can be speeded up by using directly the centroids
        static = select_random_set_of_streamlines(model_bundle,
                                                  select_model, rng=self.rng)
        moving = select_random_set_of_streamlines(neighb_streamlines,
                                                  select_target, rng=self.rng)

        static = set_number_of_points(static, nb_pts)
        moving = set_number_of_points(moving, nb_pts)

        slr = StreamlineLinearRegistration(metric=metric, x0=x0,
                                           bounds=bounds,
                                           method=method)
        slm = slr.optimize(static, moving)

        transf_streamlines = neighb_streamlines.copy()
        transf_streamlines._data = apply_affine(
            slm.matrix, transf_streamlines._data)

        transf_matrix = slm.matrix
        slr_bmd = slm.fopt
        slr_iterations = slm.iterations

        if self.verbose:
            print(' Square-root of BMD is %.3f' % (np.sqrt(slr_bmd),))
            if slr_iterations is not None:
                print(' Number of iterations %d' % (slr_iterations,))
            print(' Matrix size {}'.format(slm.matrix.shape))
            original = np.get_printoptions()
            np.set_printoptions(3, suppress=True)
            print(transf_matrix)
            print(slm.xopt)
            np.set_printoptions(**original)

            print(' Duration %0.3f sec. \n' % (time() - t,))

        return transf_streamlines, slr_bmd
예제 #2
0
def test_select_random_streamlines():
    streamlines = [np.random.rand(10, 3), np.random.rand(20, 3), np.random.rand(5, 3)]
    new_streamlines = select_random_set_of_streamlines(streamlines, 2)
    assert_equal(len(new_streamlines), 2)

    new_streamlines = select_random_set_of_streamlines(streamlines, 4)
    assert_equal(len(new_streamlines), 3)
예제 #3
0
def test_select_random_streamlines():
    streamlines = [np.random.rand(10, 3),
                   np.random.rand(20, 3),
                   np.random.rand(5, 3)]
    new_streamlines = select_random_set_of_streamlines(streamlines, 2)
    assert_equal(len(new_streamlines), 2)

    new_streamlines = select_random_set_of_streamlines(streamlines, 4)
    assert_equal(len(new_streamlines), 3)
예제 #4
0
    def evaluate_results(self, model_bundle, pruned_streamlines, slr_select):
        """ Compare the similiarity between two given bundles, model bundle,
        and extracted bundle.

        Parameters
        ----------
        model_bundle : Streamlines
        pruned_streamlines : Streamlines
        slr_select : tuple
            Select the number of streamlines from model to neirborhood of
            model to perform the local SLR.

        Returns
        -------
        ba_value : float
            bundle adjacency value between model bundle and pruned bundle
        bmd_value : float
            bundle minimum distance value between model bundle and
            pruned bundle
        """

        spruned_streamlines = Streamlines(pruned_streamlines)
        recog_centroids = self._cluster_model_bundle(
            spruned_streamlines,
            model_clust_thr=1.25)
        mod_centroids = self._cluster_model_bundle(
            model_bundle,
            model_clust_thr=1.25)
        recog_centroids = Streamlines(recog_centroids)
        model_centroids = Streamlines(mod_centroids)
        ba_value = bundle_adjacency(set_number_of_points(recog_centroids, 20),
                                    set_number_of_points(model_centroids, 20),
                                    threshold=10)

        BMD = BundleMinDistanceMetric()
        static = select_random_set_of_streamlines(model_bundle,
                                                  slr_select[0])
        moving = select_random_set_of_streamlines(pruned_streamlines,
                                                  slr_select[1])
        nb_pts = 20
        static = set_number_of_points(static, nb_pts)
        moving = set_number_of_points(moving, nb_pts)

        BMD.setup(static, moving)
        x0 = np.array([0, 0, 0, 0, 0, 0, 1., 1., 1, 0, 0, 0])  # affine
        bmd_value = BMD.distance(x0.tolist())

        return ba_value, bmd_value
예제 #5
0
def get_data(in_fn, out_fn):
    # Load volume
    tom = nib.load(in_fn).get_data() # 144 x 144 x 144 x 3
    #tom = np.sum(tom, axis=0)
    #tom = cv2.resize(tom, (256, 256))

    # Preprocess input
    tom = (tom - np.min(tom)) / (np.max(tom) - np.min(tom)) # normalise into range [0,1]
    tom = torch.from_numpy(tom)
    tom = tom.permute(3, 0, 1, 2) # channels first for pytorch
    
    # Load the tractogram
    tractogram = load_trk(out_fn, 'same', bbox_valid_check=False)
    streamlines = tractogram.streamlines

    # Preprocess the streamlines
    streamlines = select_random_set_of_streamlines(streamlines, 1024)
    streamlines = set_number_of_points(streamlines, 100)
    streamlines = np.array(streamlines)
    if len(streamlines) < 1024:
        temp_streamlines = np.zeros((1024, 100, 3))
        temp_streamlines[:streamlines.shape[0],:streamlines.shape[1], :streamlines.shape[2]] = streamlines
        streamlines = np.float32(temp_streamlines)
    streamlines = np.reshape(streamlines, (32, 32, 300))

    #tractogram = (tractogram - np.min(tractogram)) / (np.max(tractogram) - np.min(tractogram))
    tractogram = torch.from_numpy(streamlines)
    tractogram = tractogram.permute(2, 0, 1) # channels first for pytorch

    return [tom, tractogram]
예제 #6
0
파일: bundles.py 프로젝트: grlee77/dipy
    def evaluate_results(self, model_bundle, pruned_streamlines, slr_select):
        """ Comapare the similiarity between two given bundles, model bundle,
        and extracted bundle.

        Parameters
        ----------
        model_bundle : Streamlines
        pruned_streamlines : Streamlines
        slr_select : tuple
            Select the number of streamlines from model to neirborhood of
            model to perform the local SLR.

        Returns
        -------
        ba_value : float
            bundle analytics value between model bundle and pruned bundle
        bmd_value : float
            bundle minimum distance value between model bundle and
            pruned bundle
        """

        spruned_streamlines = Streamlines(pruned_streamlines)
        recog_centroids = self._cluster_model_bundle(
            spruned_streamlines,
            model_clust_thr=1.25)
        mod_centroids = self._cluster_model_bundle(
            model_bundle,
            model_clust_thr=1.25)
        recog_centroids = Streamlines(recog_centroids)
        model_centroids = Streamlines(mod_centroids)
        ba_value = ba_analysis(recog_centroids, model_centroids, threshold=10)

        BMD = BundleMinDistanceMetric()
        static = select_random_set_of_streamlines(model_bundle,
                                                  slr_select[0])
        moving = select_random_set_of_streamlines(pruned_streamlines,
                                                  slr_select[1])
        nb_pts = 20
        static = set_number_of_points(static, nb_pts)
        moving = set_number_of_points(moving, nb_pts)

        BMD.setup(static, moving)
        x0 = np.array([0, 0, 0, 0, 0, 0, 1., 1., 1, 0, 0, 0])  # affine
        bmd_value = BMD.distance(x0.tolist())

        return ba_value, bmd_value
예제 #7
0
    def _read_tg(self, tg=None):
        if tg is None:
            tg = self.tg
        else:
            self.tg = tg
        self._tg_orig_space = self.tg.space

        if self.nb_streamlines and len(self.tg) > self.nb_streamlines:
            self.tg = StatefulTractogram.from_sft(
                dts.select_random_set_of_streamlines(self.tg.streamlines,
                                                     self.nb_streamlines),
                self.tg)

        return tg
예제 #8
0
def density_map(tractogram, n_sls=None, to_vox=False, normalize=False):
    """
    Create a streamline density map.
    based on:
    https://dipy.org/documentation/1.1.1./examples_built/streamline_formats/

    Parameters
    ----------
    tractogram : StatefulTractogram
        Stateful tractogram whose streamlines are used to make
        the density map.
    n_sls : int or None, optional
        n_sls to randomly select to make the density map.
        If None, all streamlines are used.
        Default: None
    to_vox : bool, optional
        Whether to put the stateful tractogram in VOX space before making
        the density map.
        Default: False
    normalize : bool, optional
        Whether to normalize maximum values to 1.
        Default: False

    Returns
    -------
    Nifti1Image containing the density map.
    """
    if to_vox:
        tractogram.to_vox()

    sls = tractogram.streamlines
    if n_sls is not None:
        sls = select_random_set_of_streamlines(sls, n_sls)

    affine, vol_dims, voxel_sizes, voxel_order = get_reference_info(tractogram)
    tractogram_density = dtu.density_map(sls, np.eye(4), vol_dims)
    if normalize:
        tractogram_density = tractogram_density / tractogram_density.max()

    nifti_header = create_nifti_header(affine, vol_dims, voxel_sizes)
    density_map_img = nib.Nifti1Image(tractogram_density, affine, nifti_header)

    return density_map_img
예제 #9
0
def get_data(in_fn, out_fn, mean, sdev):

    # Load volume
    tom = nib.load(in_fn).get_data() # 144 x 144 x 144 x 3
    #tom = np.sum(tom, axis=0)
    #tom = cv2.resize(tom, (256, 256))

    # Preprocess input
    tom = (tom - mean) / sdev # normalise based on dataset mean/stdev
    """
    do_flip_X = False if random.randint(0,1) == 0 else True
    do_flip_Y = False if random.randint(0,1) == 0 else True
    do_flip_Z = False if random.randint(0,1) == 0 else True
    if do_flip_X:
        tom = tom[::-1,:,:]
    if do_flip_Y:
        tom = tom[:,::-1,:]
    if do_flip_Z:
        tom = tom[:,:,::-1]
    """
    tom = torch.from_numpy(np.float32(tom))
    tom = tom.permute(3, 0, 1, 2) # channels first for pytorch
    
    # Load the tractogram
    tractogram = load_trk(out_fn, 'same', bbox_valid_check=False)
    streamlines = tractogram.streamlines

    # Preprocess the streamlines
    streamlines = select_random_set_of_streamlines(streamlines, num_streamlines)
    streamlines = set_number_of_points(streamlines, num_points)
    streamlines = np.array(streamlines)
    if len(streamlines) < num_streamlines:
        temp_streamlines = np.zeros((num_streamlines, num_points, 3))
        temp_streamlines[:streamlines.shape[0],:streamlines.shape[1], :streamlines.shape[2]] = streamlines
        streamlines = np.float32(temp_streamlines)
    streamlines = np.reshape(streamlines, (int(num_streamlines**(1/2)), int(num_streamlines**(1/2)), num_points*3))

    #tractogram = (tractogram - np.min(tractogram)) / (np.max(tractogram) - np.min(tractogram))
    tractogram = torch.from_numpy(streamlines)
    tractogram = tractogram.permute(2, 0, 1) # channels first for pytorch

    return [tom, tractogram]
예제 #10
0
    def _register_model_to_neighb(self,
                                  slr_num_thread=1,
                                  select_model=1000,
                                  select_target=1000,
                                  slr_transform_type='scaling'):
        """
        Parameters
        ----------
        slr_num_thread : int
            Number of threads for SLR.
            Should remain 1 for nearly all use-case.
        select_model : int
            Maximum number of clusters to select from the model.
        select_target : int
            Maximum number of clusters to select from the neighborhood.
        slr_transform_type : str
            Define the transformation for the local SLR.
            [translation, rigid, similarity, scaling].

        Returns
        -------
        transf_neighbor : list
            The neighborhood clusters transformed into model space.
        """
        possible_slr_transform_type = {
            'translation': 0,
            'rigid': 1,
            'similarity': 2,
            'scaling': 3
        }
        static = select_random_set_of_streamlines(self.model_centroids,
                                                  select_model, self.rng)
        moving = select_random_set_of_streamlines(self.neighb_centroids,
                                                  select_target, self.rng)

        # Tuple 0,1,2 are the min & max bound in x,y,z for translation
        # Tuple 3,4,5 are the min & max bound in x,y,z for rotation
        # Tuple 6,7,8 are the min & max bound in x,y,z for scaling
        # For uniform scaling (similarity), tuple #6 is enough
        bounds_dof = [(-20, 20), (-20, 20), (-20, 20), (-10, 10), (-10, 10),
                      (-10, 10), (0.8, 1.2), (0.8, 1.2), (0.8, 1.2)]
        metric = BundleMinDistanceMetric(num_threads=slr_num_thread)
        slr_transform_type_id = possible_slr_transform_type[slr_transform_type]
        if slr_transform_type_id >= 0:
            init_transfo_dof = np.zeros(3)
            slr = StreamlineLinearRegistration(metric=metric,
                                               method="Powell",
                                               x0=init_transfo_dof,
                                               bounds=bounds_dof[:3],
                                               num_threads=slr_num_thread)
            slm = slr.optimize(static, moving)

        if slr_transform_type_id >= 1:
            init_transfo_dof = np.zeros(6)
            init_transfo_dof[:3] = slm.xopt

            slr = StreamlineLinearRegistration(metric=metric,
                                               x0=init_transfo_dof,
                                               bounds=bounds_dof[:6],
                                               num_threads=slr_num_thread)
            slm = slr.optimize(static, moving)

        if slr_transform_type_id >= 2:
            if slr_transform_type_id == 2:
                init_transfo_dof = np.zeros(7)
                init_transfo_dof[:6] = slm.xopt
                init_transfo_dof[6] = 1.

                slr = StreamlineLinearRegistration(metric=metric,
                                                   x0=init_transfo_dof,
                                                   bounds=bounds_dof[:7],
                                                   num_threads=slr_num_thread)
                slm = slr.optimize(static, moving)

            else:
                init_transfo_dof = np.zeros(9)
                init_transfo_dof[:6] = slm.xopt[:6]
                init_transfo_dof[6:] = np.array((slm.xopt[6], ) * 3)

                slr = StreamlineLinearRegistration(metric=metric,
                                                   x0=init_transfo_dof,
                                                   bounds=bounds_dof[:9],
                                                   num_threads=slr_num_thread)
                slm = slr.optimize(static, moving)
        self.model_centroids = transform_streamlines(self.model_centroids,
                                                     np.linalg.inv(slm.matrix))
예제 #11
0
def lesspoints(lines):
    #line_out= [approx_polygon_track(line,0.06) for line in lines]
    if len(lines) > 1000:
        return select_random_set_of_streamlines(lines, 1000)
    else:
        return lines
예제 #12
0
    print('Loading from' + npath)
    #load native and unfolded strealines
    nlines = lesspoints(load_vtk_streamlines(npath + 'native_streamlines.vtk'))
    ulines = lesspoints(
        load_vtk_streamlines(npath + 'from_unfold_streamlines.vtk'))

    print('Filtering...')
    nlines_tang = nicelines(npath, nlines)
    ulines_tang = nicelines(npath, ulines)
    print(len(nlines))

    print('Getting native voxels')
    # #get the voxel inds
    Nrand = 200
    if len(nlines_tang) > Nrand:
        nlines = select_random_set_of_streamlines(nlines_tang, Nrand)
        ulines = select_random_set_of_streamlines(ulines_tang, Nrand)
    ninds = []
    nginds = []
    for line in nlines:
        ninds.append(unfoldTracking.connectedInds(line, mask_nii))

    print('Getting unfold voxels')
    uinds = []
    uginds = []
    for line in ulines:
        uinds.append(unfoldTracking.connectedInds(line, mask_nii))

    print('Getting true tact instance')
    # #truetracts class instance
    tt = trueTracts(radtang_nii, U_nii, V_nii, 2, phi, phiInv)
예제 #13
0
t1_data = t1.get_data()
t1_aff = t1.affine
color = cmap.line_colors(streamlines)

# Enables/disables interactive visualization
interactive = False

"""
To speed up visualization, we will select a random sub-set of streamlines to
display. This is particularly important, if you track from seeds throughout the
entire white matter, generating many streamlines. In this case, for
demonstration purposes, we subselect 900 streamlines.
"""

from dipy.tracking.streamline import select_random_set_of_streamlines
plot_streamlines = select_random_set_of_streamlines(streamlines, 900)

streamlines_actor = actor.streamtube(
    list(move_streamlines(plot_streamlines, inv(t1_aff))),
         cmap.line_colors(streamlines), linewidth=0.1)

vol_actor = actor.slicer(t1_data)

vol_actor.display(40, None, None)
vol_actor2 = vol_actor.copy()
vol_actor2.display(None, None, 35)

ren = window.Renderer()
ren.add(streamlines_actor)
ren.add(vol_actor)
ren.add(vol_actor2)
예제 #14
0
function 'to_vox()' and 'to_corner()'
"""

cc_sft.to_vox()
laf_sft.to_vox()
raf_sft.to_vox()
lpt_sft.to_vox()
rpt_sft.to_vox()

cc_sft.to_corner()
laf_sft.to_corner()
raf_sft.to_corner()
lpt_sft.to_corner()
rpt_sft.to_corner()

cc_streamlines_vox = select_random_set_of_streamlines(cc_sft.streamlines, 1000)
laf_streamlines_vox = select_random_set_of_streamlines(laf_sft.streamlines,
                                                       1000)
raf_streamlines_vox = select_random_set_of_streamlines(raf_sft.streamlines,
                                                       1000)
lpt_streamlines_vox = select_random_set_of_streamlines(lpt_sft.streamlines,
                                                       1000)
rpt_streamlines_vox = select_random_set_of_streamlines(rpt_sft.streamlines,
                                                       1000)

# Same dimensions for every stateful tractogram, can be re-use
affine, dimensions, voxel_sizes, voxel_order = cc_sft.space_attributes
cc_density = density_map(cc_streamlines_vox, np.eye(4), dimensions)
laf_density = density_map(laf_streamlines_vox, np.eye(4), dimensions)
raf_density = density_map(raf_streamlines_vox, np.eye(4), dimensions)
lpt_density = density_map(lpt_streamlines_vox, np.eye(4), dimensions)
예제 #15
0
def slr_with_qbx(static,
                 moving,
                 x0='affine',
                 rm_small_clusters=50,
                 maxiter=100,
                 select_random=None,
                 verbose=False,
                 greater_than=50,
                 less_than=250,
                 qbx_thr=[40, 30, 20, 15],
                 nb_pts=20,
                 progressive=True,
                 rng=None,
                 num_threads=None):
    """ Utility function for registering large tractograms.

    For efficiency, we apply the registration on cluster centroids and remove
    small clusters.

    Parameters
    ----------
    static : Streamlines
    moving : Streamlines

    x0 : str, optional.
        rigid, similarity or affine transformation model (default affine)

    rm_small_clusters : int, optional
        Remove clusters that have less than `rm_small_clusters` (default 50)

    select_random : int, optional.
        If not, None selects a random number of streamlines to apply clustering
        Default None.

    verbose : bool, optional
        If True, logs information about optimization. Default: False

    greater_than : int, optional
            Keep streamlines that have length greater than
            this value (default 50)

    less_than : int, optional
            Keep streamlines have length less than this value (default 250)

    qbx_thr : variable int
            Thresholds for QuickBundlesX (default [40, 30, 20, 15])

    np_pts : int, optional
            Number of points for discretizing each streamline (default 20)

    progressive : boolean, optional
            (default True)

    rng : RandomState
        If None creates RandomState in function.

    num_threads : int
        Number of threads. If None (default) then all available threads
        will be used. Only metrics using OpenMP will use this variable.

    Notes
    -----
    The order of operations is the following. First short or long streamlines
    are removed. Second, the tractogram or a random selection of the tractogram
    is clustered with QuickBundles. Then SLR [Garyfallidis15]_ is applied.

    References
    ----------
    .. [Garyfallidis15] Garyfallidis et al. "Robust and efficient linear
    registration of white-matter fascicles in the space of streamlines",
    NeuroImage, 117, 124--140, 2015
    .. [Garyfallidis14] Garyfallidis et al., "Direct native-space fiber
            bundle alignment for group comparisons", ISMRM, 2014.
    .. [Garyfallidis17] Garyfallidis et al. Recognition of white matter
    bundles using local and global streamline-based registration and
    clustering, Neuroimage, 2017.
    """
    if rng is None:
        rng = np.random.RandomState()

    if verbose:
        logger.info('Static streamlines size {}'.format(len(static)))
        logger.info('Moving streamlines size {}'.format(len(moving)))

    def check_range(streamline, gt=greater_than, lt=less_than):

        if (length(streamline) > gt) & (length(streamline) < lt):
            return True
        else:
            return False

    streamlines1 = Streamlines(static[np.array(
        [check_range(s) for s in static])])
    streamlines2 = Streamlines(moving[np.array(
        [check_range(s) for s in moving])])
    if verbose:
        logger.info('Static streamlines after length reduction {}'.format(
            len(streamlines1)))
        logger.info('Moving streamlines after length reduction {}'.format(
            len(streamlines2)))

    if select_random is not None:
        rstreamlines1 = select_random_set_of_streamlines(streamlines1,
                                                         select_random,
                                                         rng=rng)
    else:
        rstreamlines1 = streamlines1

    rstreamlines1 = set_number_of_points(rstreamlines1, nb_pts)

    rstreamlines1._data.astype('f4')

    cluster_map1 = qbx_and_merge(rstreamlines1, thresholds=qbx_thr, rng=rng)
    qb_centroids1 = remove_clusters_by_size(cluster_map1, rm_small_clusters)

    if select_random is not None:
        rstreamlines2 = select_random_set_of_streamlines(streamlines2,
                                                         select_random,
                                                         rng=rng)
    else:
        rstreamlines2 = streamlines2

    rstreamlines2 = set_number_of_points(rstreamlines2, nb_pts)
    rstreamlines2._data.astype('f4')

    cluster_map2 = qbx_and_merge(rstreamlines2, thresholds=qbx_thr, rng=rng)

    qb_centroids2 = remove_clusters_by_size(cluster_map2, rm_small_clusters)

    if verbose:
        t = time()

    if not progressive:
        slr = StreamlineLinearRegistration(x0=x0,
                                           options={'maxiter': maxiter},
                                           num_threads=num_threads)
        slm = slr.optimize(qb_centroids1, qb_centroids2)
    else:
        bounds = DEFAULT_BOUNDS

        slm = progressive_slr(qb_centroids1,
                              qb_centroids2,
                              x0=x0,
                              metric=None,
                              bounds=bounds,
                              num_threads=num_threads)

    if verbose:
        logger.info('QB static centroids size %d' % len(qb_centroids1, ))
        logger.info('QB moving centroids size %d' % len(qb_centroids2, ))
        duration = time() - t
        logger.info('SLR finished in  %0.3f seconds.' % (duration, ))
        if slm.iterations is not None:
            logger.info('SLR iterations: %d ' % (slm.iterations, ))

    moved = slm.transform(moving)

    return moved, slm.matrix, qb_centroids1, qb_centroids2
예제 #16
0
파일: streamlinear.py 프로젝트: arokem/dipy
def slr_with_qbx(static, moving,
                 x0='affine',
                 rm_small_clusters=50,
                 maxiter=100,
                 select_random=None,
                 verbose=False,
                 greater_than=50,
                 less_than=250,
                 qbx_thr=[40, 30, 20, 15],
                 nb_pts=20,
                 progressive=True, rng=None, num_threads=None):
    """ Utility function for registering large tractograms.

    For efficiency we apply the registration on cluster centroids and remove
    small clusters.

    Parameters
    ----------
    static : Streamlines
    moving : Streamlines

    x0 : str
        rigid, similarity or affine transformation model (default affine)

    rm_small_clusters : int
        Remove clusters that have less than `rm_small_clusters` (default 50)

    select_random : int
        If not None select a random number of streamlines to apply clustering
        Default None.

    verbose : bool,
        If True then information about the optimization is shown.

    greater_than : int, optional
            Keep streamlines that have length greater than
            this value (default 50)

    less_than : int, optional
            Keep streamlines have length less than this value (default 250)

    qbx_thr : variable int
            Thresholds for QuickBundlesX (default [40, 30, 20, 15])

    np_pts : int, optional
            Number of points for discretizing each streamline (default 20)

    progressive : boolean, optional
            (default True)

    rng : RandomState
        If None creates RandomState in function.

    num_threads : int
        Number of threads. If None (default) then all available threads
        will be used. Only metrics using OpenMP will use this variable.

    Notes
    -----
    The order of operations is the following. First short or long streamlines
    are removed. Second the tractogram or a random selection of the tractogram
    is clustered with QuickBundles. Then SLR [Garyfallidis15]_ is applied.

    References
    ----------
    .. [Garyfallidis15] Garyfallidis et al. "Robust and efficient linear
    registration of white-matter fascicles in the space of streamlines",
    NeuroImage, 117, 124--140, 2015
    .. [Garyfallidis14] Garyfallidis et al., "Direct native-space fiber
            bundle alignment for group comparisons", ISMRM, 2014.
    .. [Garyfallidis17] Garyfallidis et al. Recognition of white matter
    bundles using local and global streamline-based registration and
    clustering, Neuroimage, 2017.
    """
    if rng is None:
        rng = np.random.RandomState()

    if verbose:
        print('Static streamlines size {}'.format(len(static)))
        print('Moving streamlines size {}'.format(len(moving)))

    def check_range(streamline, gt=greater_than, lt=less_than):

        if (length(streamline) > gt) & (length(streamline) < lt):
            return True
        else:
            return False

    streamlines1 = Streamlines(static[np.array([check_range(s)
                                                for s in static])])
    streamlines2 = Streamlines(moving[np.array([check_range(s)
                                                for s in moving])])

    if verbose:

        print('Static streamlines after length reduction {}'
              .format(len(streamlines1)))
        print('Moving streamlines after length reduction {}'
              .format(len(streamlines2)))

    if select_random is not None:
        rstreamlines1 = select_random_set_of_streamlines(streamlines1,
                                                         select_random,
                                                         rng=rng)
    else:
        rstreamlines1 = streamlines1

    rstreamlines1 = set_number_of_points(rstreamlines1, nb_pts)

    rstreamlines1._data.astype('f4')

    cluster_map1 = qbx_and_merge(rstreamlines1, thresholds=qbx_thr, rng=rng)
    qb_centroids1 = remove_clusters_by_size(cluster_map1, rm_small_clusters)

    if select_random is not None:
        rstreamlines2 = select_random_set_of_streamlines(streamlines2,
                                                         select_random,
                                                         rng=rng)
    else:
        rstreamlines2 = streamlines2

    rstreamlines2 = set_number_of_points(rstreamlines2, nb_pts)
    rstreamlines2._data.astype('f4')

    cluster_map2 = qbx_and_merge(rstreamlines2, thresholds=qbx_thr, rng=rng)

    qb_centroids2 = remove_clusters_by_size(cluster_map2, rm_small_clusters)

    if verbose:
        t = time()

    if not progressive:
        slr = StreamlineLinearRegistration(x0=x0,
                                           options={'maxiter': maxiter},
                                           num_threads=num_threads)
        slm = slr.optimize(qb_centroids1, qb_centroids2)
    else:
        bounds = DEFAULT_BOUNDS

        slm = progressive_slr(qb_centroids1, qb_centroids2,
                              x0=x0, metric=None,
                              bounds=bounds, num_threads=num_threads)

    if verbose:
        print('QB static centroids size %d' % len(qb_centroids1,))
        print('QB moving centroids size %d' % len(qb_centroids2,))
        duration = time() - t
        print('SLR finished in  %0.3f seconds.' % (duration,))
        if slm.iterations is not None:
            print('SLR iterations: %d ' % (slm.iterations,))

    moved = slm.transform(moving)

    return moved, slm.matrix, qb_centroids1, qb_centroids2
예제 #17
0
def slr_with_qb(static,
                moving,
                x0='affine',
                rm_small_clusters=50,
                maxiter=100,
                select_random=None,
                verbose=False,
                greater_than=50,
                less_than=250,
                qb_thr=15,
                nb_pts=20,
                progressive=True,
                num_threads=None):
    """ Utility function for registering large tractograms.

    For efficiency we apply the registration on cluster centroids and remove
    small clusters.

    Parameters
    ----------
    static : Streamlines
    moving : Streamlines
    x0 : str
        rigid, similarity or affine transformation model (default affine)

    rm_small_clusters : int
        Remove clusters that have less than `rm_small_clusters` (default 50)

    verbose : bool,
        If True then information about the optimization is shown.

    select_random : int
        If not None select a random number of streamlines to apply clustering
        Default None.

    options : None or dict,
        Extra options to be used with the selected method.

    num_threads : int
        Number of threads. If None (default) then all available threads
        will be used. Only metrics using OpenMP will use this variable.

    Notes
    -----
    The order of operations is the following. First short or long streamlines
    are removed. Second the tractogram or a random selection of the tractogram
    is clustered with QuickBundles. Then SLR [Garyfallidis15]_ is applied.

    References
    ----------
    .. [Garyfallidis15] Garyfallidis et al. "Robust and efficient linear
            registration of white-matter fascicles in the space of streamlines"
            , NeuroImage, 117, 124--140, 2015
    .. [Garyfallidis14] Garyfallidis et al., "Direct native-space fiber
            bundle alignment for group comparisons", ISMRM, 2014.
    .. [Garyfallidis17] Garyfallidis et al. Recognition of white matter
            bundles using local and global streamline-based registration and
            clustering, Neuroimage, 2017.
    """
    if verbose:
        print('Static streamlines size {}'.format(len(static)))
        print('Moving streamlines size {}'.format(len(moving)))

    def check_range(streamline, gt=greater_than, lt=less_than):

        if (length(streamline) > gt) & (length(streamline) < lt):
            return True
        else:
            return False

    # TODO change this to the new Streamlines API
    streamlines1 = [s for s in static if check_range(s)]
    streamlines2 = [s for s in moving if check_range(s)]

    if verbose:

        print('Static streamlines after length reduction {}'.format(
            len(streamlines1)))
        print('Moving streamlines after length reduction {}'.format(
            len(streamlines2)))

    if select_random is not None:
        rstreamlines1 = select_random_set_of_streamlines(
            streamlines1, select_random)
    else:
        rstreamlines1 = streamlines1

    rstreamlines1 = set_number_of_points(rstreamlines1, nb_pts)
    qb1 = QuickBundles(threshold=qb_thr)
    rstreamlines1 = [s.astype('f4') for s in rstreamlines1]
    cluster_map1 = qb1.cluster(rstreamlines1)
    clusters1 = remove_clusters_by_size(cluster_map1, rm_small_clusters)
    qb_centroids1 = [cluster.centroid for cluster in clusters1]

    if select_random is not None:
        rstreamlines2 = select_random_set_of_streamlines(
            streamlines2, select_random)
    else:
        rstreamlines2 = streamlines2

    rstreamlines2 = set_number_of_points(rstreamlines2, nb_pts)
    qb2 = QuickBundles(threshold=qb_thr)
    rstreamlines2 = [s.astype('f4') for s in rstreamlines2]
    cluster_map2 = qb2.cluster(rstreamlines2)
    clusters2 = remove_clusters_by_size(cluster_map2, rm_small_clusters)
    qb_centroids2 = [cluster.centroid for cluster in clusters2]

    if verbose:
        t = time()

    if not progressive:
        slr = StreamlineLinearRegistration(x0=x0,
                                           options={'maxiter': maxiter},
                                           num_threads=num_threads)
        slm = slr.optimize(qb_centroids1, qb_centroids2)
    else:
        bounds = DEFAULT_BOUNDS

        slm = progressive_slr(qb_centroids1,
                              qb_centroids2,
                              x0=x0,
                              metric=None,
                              bounds=bounds,
                              num_threads=num_threads)

    if verbose:
        print('QB static centroids size %d' % len(qb_centroids1, ))
        print('QB moving centroids size %d' % len(qb_centroids2, ))
        duration = time() - t
        print('SLR finished in  %0.3f seconds.' % (duration, ))
        if slm.iterations is not None:
            print('SLR iterations: %d ' % (slm.iterations, ))

    moved = slm.transform(moving)

    return moved, slm.matrix, qb_centroids1, qb_centroids2
예제 #18
0
t1_data = t1.get_data()
t1_aff = t1.affine
color = cmap.line_colors(streamlines)

# Enables/disables interactive visualization
interactive = False

"""
To speed up visualization, we will select a random sub-set of streamlines to
display. This is particularly important, if you track from seeds throughout the
entire white matter, generating many streamlines. In this case, for
demonstration purposes, we subselect 900 streamlines.
"""

from dipy.tracking.streamline import select_random_set_of_streamlines
plot_streamlines = select_random_set_of_streamlines(streamlines, 900)

streamlines_actor = actor.streamtube(
    list(move_streamlines(plot_streamlines, inv(t1_aff))),
         cmap.line_colors(streamlines), linewidth=0.1)

vol_actor = actor.slicer(t1_data)

vol_actor.display(40, None, None)
vol_actor2 = vol_actor.copy()
vol_actor2.display(None, None, 35)

ren = window.Renderer()
ren.add(streamlines_actor)
ren.add(vol_actor)
ren.add(vol_actor2)
예제 #19
0
def slr_with_qb(static, moving,
                x0='affine',
                rm_small_clusters=50,
                maxiter=100,
                select_random=None,
                verbose=False,
                greater_than=50,
                less_than=250,
                qb_thr=15,
                nb_pts=20,
                progressive=True, num_threads=None):
    """ Utility function for registering large tractograms.

    For efficiency we apply the registration on cluster centroids and remove
    small clusters.

    Parameters
    ----------
    static : Streamlines
    moving : Streamlines
    x0 : str
        rigid, similarity or affine transformation model (default affine)

    rm_small_clusters : int
        Remove clusters that have less than `rm_small_clusters` (default 50)

    verbose : bool,
        If True then information about the optimization is shown.

    select_random : int
        If not None select a random number of streamlines to apply clustering
        Default None.

    options : None or dict,
        Extra options to be used with the selected method.

    num_threads : int
        Number of threads. If None (default) then all available threads
        will be used. Only metrics using OpenMP will use this variable.

    Notes
    -----
    The order of operations is the following. First short or long streamlines
    are removed. Second the tractogram or a random selection of the tractogram
    is clustered with QuickBundles. Then SLR [Garyfallidis15]_ is applied.

    References
    ----------
    .. [Garyfallidis15] Garyfallidis et al. "Robust and efficient linear
            registration of white-matter fascicles in the space of streamlines"
            , NeuroImage, 117, 124--140, 2015
    .. [Garyfallidis14] Garyfallidis et al., "Direct native-space fiber
            bundle alignment for group comparisons", ISMRM, 2014.
    .. [Garyfallidis17] Garyfallidis et al. Recognition of white matter
            bundles using local and global streamline-based registration and
            clustering, Neuroimage, 2017.
    """
    if verbose:
        print('Static streamlines size {}'.format(len(static)))
        print('Moving streamlines size {}'.format(len(moving)))

    def check_range(streamline, gt=greater_than, lt=less_than):

        if (length(streamline) > gt) & (length(streamline) < lt):
            return True
        else:
            return False

    # TODO change this to the new Streamlines API
    streamlines1 = [s for s in static if check_range(s)]
    streamlines2 = [s for s in moving if check_range(s)]

    if verbose:

        print('Static streamlines after length reduction {}'
              .format(len(streamlines1)))
        print('Moving streamlines after length reduction {}'
              .format(len(streamlines2)))

    if select_random is not None:
        rstreamlines1 = select_random_set_of_streamlines(streamlines1,
                                                         select_random)
    else:
        rstreamlines1 = streamlines1

    rstreamlines1 = set_number_of_points(rstreamlines1, nb_pts)
    qb1 = QuickBundles(threshold=qb_thr)
    rstreamlines1 = [s.astype('f4') for s in rstreamlines1]
    cluster_map1 = qb1.cluster(rstreamlines1)
    clusters1 = remove_clusters_by_size(cluster_map1, rm_small_clusters)
    qb_centroids1 = [cluster.centroid for cluster in clusters1]

    if select_random is not None:
        rstreamlines2 = select_random_set_of_streamlines(streamlines2,
                                                         select_random)
    else:
        rstreamlines2 = streamlines2

    rstreamlines2 = set_number_of_points(rstreamlines2, nb_pts)
    qb2 = QuickBundles(threshold=qb_thr)
    rstreamlines2 = [s.astype('f4') for s in rstreamlines2]
    cluster_map2 = qb2.cluster(rstreamlines2)
    clusters2 = remove_clusters_by_size(cluster_map2, rm_small_clusters)
    qb_centroids2 = [cluster.centroid for cluster in clusters2]

    if verbose:
        t = time()

    if not progressive:
        slr = StreamlineLinearRegistration(x0=x0,
                                           options={'maxiter': maxiter},
                                           num_threads=num_threads)
        slm = slr.optimize(qb_centroids1, qb_centroids2)
    else:
        bounds = DEFAULT_BOUNDS

        slm = progressive_slr(qb_centroids1, qb_centroids2,
                              x0=x0, metric=None,
                              bounds=bounds, num_threads=num_threads)

    if verbose:
        print('QB static centroids size %d' % len(qb_centroids1,))
        print('QB moving centroids size %d' % len(qb_centroids2,))
        duration = time() - t
        print('SLR finished in  %0.3f seconds.' % (duration,))
        if slm.iterations is not None:
            print('SLR iterations: %d ' % (slm.iterations,))

    moved = slm.transform(moving)

    return moved, slm.matrix, qb_centroids1, qb_centroids2