def test_qbundles(): streams, hdr = nib.trackvis.read(get_fnames('fornix')) T = [s[0] for s in streams] qb = QuickBundles(T, 10., 12) qb.virtuals() qb.exemplars() assert_equal(4, qb.total_clusters)
def subsample_streamlines(streamlines, clustering_threshold=6., removal_distance=2.): """ Subsample a group of streamlines (should be used on streamlines from a single bundle or similar structure). Streamlines are first clustered using `clustering_threshold`, then for each cluster, similar streamlines (closer than `removal_distance`) are removed. Parameters ---------- streamlines : `ArraySequence` object Streamlines to subsample clustering_threshold : float distance threshold for clustering (in the space of the tracks) removal_distance : float distance threshold for removal (in the space of the tracks) Returns ------- `ArraySequence` object Downsampled streamlines """ output_streamlines = [] qb = QuickBundles(streamlines, dist_thr=clustering_threshold, pts=20) for i in range(len(qb.centroids)): temp_streamlines = qb.label2tracks(streamlines, i) output_streamlines.extend( remove_similar_streamlines(temp_streamlines, removal_distance=removal_distance)) return output_streamlines
def bundle_centroids(self, streamlines=None, cluster_thre=10, dist_thre=10.0, pts=12): """ QuickBundles-based segmentation Parameters ---------- streamlines: streamline data cluster_thre: remove small cluster dist_thre: clustering threshold (distance mm) pts: each streamlines are divided into sections Return ------ centroids: cluster's centroids """ if streamlines is None: streamlines = self._fasciculus.get_data() else: streamlines = streamlines bundles = QuickBundles(streamlines, dist_thre, pts) bundles.remove_small_clusters(cluster_thre) centroids = bundles.centroids return nibas.ArraySequence(centroids)
def bundle_thre_seg(self, streamlines=None, cluster_thre=10, dist_thre=10.0, pts=12): """ QuickBundles-based segmentation Parameters ---------- streamlines: streamline data cluster_thre: remove small cluster dist_thre: clustering threshold (distance mm) pts: each streamlines are divided into sections Return ------ sort_index: sort of clusters according to y mean of cluster's centroids data_cluster: cluster data corresponding to sort_index """ if streamlines is None: streamlines = self._fasciculus.get_data() else: streamlines = streamlines bundles = QuickBundles(streamlines, dist_thre, pts) bundles.remove_small_clusters(cluster_thre) clusters = bundles.clusters() data_clusters = [] for key in clusters.keys(): data_clusters.append(streamlines[clusters[key]['indices']]) centroids = bundles.centroids clusters_y_mean = [clu[:, 1].mean() for clu in centroids] sort_index = np.argsort(clusters_y_mean) return sort_index, data_clusters
def bundle_seg(self, streamlines=None, dist_thre=10.0, pts=12): """ QuickBundles-based segmentation Parameters ---------- streamlines: streamline data dist_thre: clustering threshold (distance mm) pts: each streamlines are divided into sections Return ------ labels: label of each streamline data_cluster: cluster data N_list: size of each cluster """ if streamlines is None: streamlines = self._fasciculus.get_data() else: streamlines = streamlines bundles = QuickBundles(streamlines, dist_thre, pts) clusters = bundles.clusters() labels = np.array(len(streamlines) * [None]) N_list = [] for i in range(len(clusters)): N_list.append(clusters[i]['N']) # show(N_list, title='N histogram', xlabel='N') data_clusters = [] for i in range(len(clusters)): labels[clusters[i]['indices']] = i + 1 data_clusters.append(streamlines[clusters[i]['indices']]) return labels, data_clusters, N_list
def freeze(self): print( "Freezing current expanded real tracks, then doing QB on them, then restarting." ) print("Selected virtuals: %s" % self.selected) tracks_frozen = [] tracks_frozen_ids = [] for tid in self.selected: print tid part_tracks = self.qb.label2tracks(self.tracks, tid) part_tracks_ids = self.qb.label2tracksids(tid) print("virtual %s represents %s tracks." % (tid, len(part_tracks))) tracks_frozen += part_tracks tracks_frozen_ids += part_tracks_ids print "frozen tracks size:", len(tracks_frozen) print "Computing quick bundles...", self.unselect_track('all') self.tracks = tracks_frozen self.tracks_ids = self.tracks_ids[ tracks_frozen_ids] # range(len(self.tracks)) root = Tkinter.Tk() root.wm_title('QuickBundles threshold') ts = ThresholdSelector(root, default_value=self.qb.dist_thr / 2.0) root.wait_window() #print "Threshold value ",ts.value #self.qb = QuickBundles(self.tracks, dist_thr=qb.dist_thr/2., pts=self.qb.pts) self.qb = QuickBundles(self.tracks, dist_thr=ts.value, pts=self.qb.pts) #self.qb.dist_thr = qb.dist_thr/2. self.qb.dist_thr = ts.value if self.reps == 'virtuals': self.virtuals = qb.virtuals() if self.reps == 'exemplars': self.virtuals, self.ex_ids = self.qb.exemplars() print len(self.virtuals), 'virtuals' self.virtuals_buffer, self.virtuals_colors, self.virtuals_first, self.virtuals_count = self.compute_buffers( self.virtuals, self.virtuals_alpha) #compute buffers self.tracks_buffer, self.tracks_colors, self.tracks_first, self.tracks_count = self.compute_buffers( self.tracks, self.tracks_alpha) # self.unselect_track('all') self.selected = [] self.old_color = {} self.expand = False self.history.append([ self.qb, self.tracks, self.tracks_ids, self.virtuals_buffer, self.virtuals_colors, self.virtuals_first, self.virtuals_count, self.tracks_buffer, self.tracks_colors, self.tracks_first, self.tracks_count ]) if self.vol_shape is not None: print("Shifting!") self.virtuals_shifted = [ downsample(t + np.array(self.vol_shape) / 2., 30) for t in self.virtuals ] else: self.virtuals_shifted = None
def test_qbundles(): streams, hdr = nib.trackvis.read(get_data('fornix')) T = [s[0] for s in streams] Trk = np.array(T, dtype=np.object) qb = QuickBundles(T, 10., 12) Tqb = qb.virtuals() # Tqbe,Tqbei=qb.exemplars(T) Tqbe, Tqbei = qb.exemplars() assert_equal(4, qb.total_clusters)
def visualization(streamlines_file): # clustering of fibers into bundles and visualization thereof streamlines = np.load(streamlines_file)['arr_0'] qb = QuickBundles(streamlines, dist_thr=10., pts=18) centroids = qb.centroids #centroids = streamlines colors = line_colors(centroids).astype(np.float) mlab.figure(bgcolor=(0., 0., 0.)) for streamline, color in zip(centroids, colors): mlab.plot3d(streamline.T[0], streamline.T[1], streamline.T[2], line_width=1., tube_radius=.5, color=tuple(color))
def bundle_tracks(in_file, dist_thr=40., pts=16, skip=80.): import subprocess import os.path as op from nibabel import trackvis as tv from dipy.segment.quickbundles import QuickBundles streams, hdr = tv.read(in_file) streamlines = [i[0] for i in streams] qb = QuickBundles(streamlines, float(dist_thr), int(pts)) clusters = qb.clustering #scalars = [i[0] for i in streams] out_files = [] name = "quickbundle_" n_clusters = clusters.keys() print("%d clusters found" % len(n_clusters)) new_hdr = tv.empty_header() new_hdr['n_scalars'] = 1 for cluster in clusters: cluster_trk = op.abspath(name + str(cluster) + ".trk") print("Writing cluster %d to %s" % (cluster, cluster_trk)) out_files.append(cluster_trk) clust_idxs = clusters[cluster]['indices'] new_streams = [streamlines[i] for i in clust_idxs] for_save = [(sl, None, None) for sl in new_streams] tv.write(cluster_trk, for_save, hdr) out_merged_file = "MergedBundles.trk" command_list = ["track_merge"] command_list.extend(out_files) command_list.append(out_merged_file) subprocess.call(command_list) out_scene_file = write_trackvis_scene(out_merged_file, n_clusters=len(clusters), skip=skip, names=None, out_file="NewScene.scene") print("Merged track file written to %s" % out_merged_file) print("Scene file written to %s" % out_scene_file) return out_files, out_merged_file, out_scene_file
print('ind.shape (%d, %d, %d)' % ind.shape) # Compute Eular Delta Crossing with FA eu = EuDX(a=fa, ind=ind, seeds=100000, odf_vertices=sphere.vertices, a_low=0.2) # FA uses a_low = 0.2 streamlines = [line for line in eu] print('Number of streamlines %i' % len(streamlines)) ''' for line in streamlines: print(line.shape) ''' # Do steamline clustering using QuickBundles (QB) using Eular's Method # dist_thr (distance threshold) which affects number of clusters and their size # pts (number of points in each streamline) which will be used for downsampling before clustering # Default values : dist_thr = 4 & pts = 12 qb = QuickBundles(streamlines, dist_thr=20, pts=20) clusters = qb.clusters() print('Number of clusters %i' % qb.total_clusters) print('Cluster size', qb.clusters_sizes()) # Display streamlines ren = window.Renderer() ren.add(actor.streamtube(streamlines, window.colors.white)) window.show(ren) window.record(ren, out_path=filename + '_stream_lines_eu.png', size=(600, 600)) # Display centroids window.clear(ren) colormap = actor.create_colormap(np.arange(qb.total_clusters)) ren.add(actor.streamtube(streamlines, window.colors.white, opacity=0.1)) ren.add(actor.streamtube(qb.centroids, colormap, linewidth=0.5))
# 'response_dhollander/101107/Diffusion/1M_20_01_20dynamic250_SD_Stream_occipital8_lr5.tck' img_path = '/home/brain/workingdir/data/dwi/hcp/preprocessed/' \ 'response_dhollander/101107/Structure/T1w_acpc_dc_restore_brain1.25.nii.gz' img = nib.load(img_path) fa = Fasciculus(fib) streamlines = fa.get_data() length_t = fa.get_lengths() ind = length_t > 10 streamlines = streamlines[ind] fa.set_data(streamlines) fibcluster = FibClustering(fa) print len(streamlines) # 1 qb = QuickBundles(streamlines, 2) clusters = qb.clusters() print qb.clusters_sizes() indexs = [] for i in range(len(clusters)): if clusters[i]['N'] >= 400: indexs += clusters[i]['indices'] # 2 streamlines = streamlines[indexs] qb = QuickBundles(streamlines, 2) clusters = qb.clusters() centroids = qb.centroids centroids_lengths = np.array(list(length(centroids))) print centroids_lengths
from dipy.io.streamline import load_tck from dipy.segment.quickbundles import QuickBundles from dipy.viz import window, actor from dipy.io.pickles import save_pickle filename = 'DTI30s010' # Load streamlines streamlines, header = load_tck(filename + '_fod_streamlines.tck') print('Number of streamlines %i' %len(streamlines)) # Do steamline clustering using QuickBundles (QB) using FOD (Probalistic Method) # dist_thr (distance threshold) which affects number of clusters and their size # pts (number of points in each streamline) which will be used for downsampling before clustering # Default values : dist_thr = 4 & pts = 12 qb = QuickBundles(streamlines, dist_thr=42, pts=18) clusters = qb.clusters() print('Number of clusters %i' %qb.total_clusters) print('Cluster size', qb.clusters_sizes()) # Display streamlines ren = window.Renderer() ren.add(actor.streamtube(streamlines, window.colors.white)) ren.set_camera(position=(-176.42, 118.52, 128.20), focal_point=(113.30, 128.31, 76.56), view_up=(0.18, 0.00, 0.98)) window.show(ren) window.record(ren, out_path=filename + '_stream_lines_fod.png', size=(600, 600)) # Display centroids window.clear(ren)
from dipy.io.pickles import save_pickle from dipy.data import get_data from dipy.viz import fvtk import nipype.interfaces.mrtrix as mrt import os import sys streams, hdr = tv.read(sys.argv[1]) streamlines = [i[0] for i in streams] """ Perform QuickBundles clustering with a 10mm distance threshold after having downsampled the streamlines to have only 12 points. """ print("Computing bundles") qb = QuickBundles(streamlines, dist_thr=int(sys.argv[3]), pts=int(sys.argv[4])) print("Completed") """ qb has attributes like `centroids` (cluster representatives), `total_clusters` (total number of clusters) and methods like `partitions` (complete description of all clusters) and `label2tracksids` (provides the indices of the streamlines which belong in a specific cluster). """ centroids = qb.centroids print(len(centroids)) streamlines = [i[0] for i in streams] for i, centroid in enumerate(centroids): print(i) inds = qb.label2tracksids(i) list1 = [] for number in range(1, len(inds)):
def terminus2hemi_surface_density_map(streamlines, geo_path, hemi): """ Streamline endpoints areas mapping to hemisphere surface streamlines > 1000 Parameters ---------- streamlines: streamline data geo_path: surface data path Return ------ endpoints areas map on surface """ streamlines = _sort_streamlines(streamlines) bundles = QuickBundles(streamlines, 10, 12) # bundles.remove_small_clusters(10) clusters = bundles.clusters() data_clusters = [] for key in clusters.keys(): data_clusters.append(streamlines[clusters[key]['indices']]) data0 = data_clusters[0] stream_terminus_lh0 = np.array([s[0] for s in data0]) stream_terminus_rh0 = np.array([s[-1] for s in data0]) suffix = os.path.split(geo_path)[1].split('.')[-1] if suffix in ('white', 'inflated', 'pial'): coords, faces = nib.freesurfer.read_geometry(geo_path) elif suffix == 'gii': gii_data = nib.load(geo_path).darrays coords, faces = gii_data[0].data, gii_data[1].data else: raise ImageFileError( 'This file format-{} is not supported at present.'.format(suffix)) if hemi == 'lh': dist_lh0 = cdist(coords, stream_terminus_lh0) vert_value = np.array([ float(np.array(dist_lh0[m] < 5).sum(axis=0)) for m in range(len(dist_lh0[:])) ]) else: dist_rh0 = cdist(coords, stream_terminus_rh0) vert_value = np.array([ float(np.array(dist_rh0[n] < 5).sum(axis=0)) for n in range(len(dist_rh0[:])) ]) for i in range(len(data_clusters)): data = data_clusters[i] if hemi == 'lh': stream_terminus = np.array([s[0] for s in data]) else: stream_terminus = np.array([s[-1] for s in data]) dist = cdist(coords, stream_terminus) vert_value_i = np.array( [np.array(dist[j] < 5).sum(axis=0) for j in range(len(dist[:]))]) if i != 0: vert_value += vert_value_i return vert_value
T = [i[0] for i in streams] """ Downsample tracks to 12 points: """ tracks = [tm.downsample(t, 12) for t in T] """ Delete unnecessary data: """ del streams, hdr """ Perform QuickBundles clustering with a 10mm threshold: """ qb = QuickBundles(tracks, dist_thr=10., pts=None) """ Show the initial *Fornix* dataset: """ r = fvtk.ren() fvtk.add(r, fvtk.line(T, fvtk.white, opacity=1, linewidth=3)) #fvtk.show(r) fvtk.record(r, n_frames=1, out_path='fornix_initial', size=(600, 600)) fvtk.clear(r) """ .. figure:: fornix_initial1000000.png :align: center **Initial Fornix dataset**. """