def test_approx_ei_traj(): segs = 100 t = np.linspace(0, 1.75 * 2 * np.pi, segs) x = t y = 5 * np.sin(5 * t) z = np.zeros(x.shape) xyz = np.vstack((x, y, z)).T xyza = pf.approx_polygon_track(xyz) assert_equal(len(xyza), 27) # test repeated point track = np.array([[1., 0., 0.], [1., 0., 0.], [3., 0., 0.], [4., 0., 0.]]) xyza = pf.approx_polygon_track(track) assert_array_equal(xyza, np.array([[1., 0., 0.], [4., 0., 0.]]))
def test_approx_ei_traj(): segs = 100 t = np.linspace(0, 1.75 * 2 * np.pi, segs) x = t y = 5 * np.sin(5 * t) z = np.zeros(x.shape) xyz = np.vstack((x, y, z)).T xyza = pf.approx_polygon_track(xyz) assert_equal(len(xyza), 27)
def test_approx_ei_traj(): segs=100 t=np.linspace(0,1.75*2*np.pi,segs) x =t y=5*np.sin(5*t) z=np.zeros(x.shape) xyz=np.vstack((x,y,z)).T xyza=pf.approx_polygon_track(xyz) assert_equal(len(xyza), 27)
different number of points which could be of a trouble for some algorithms. The function ``set_number_of_points`` can be used to set the number of points of a streamline at a specific number and at the same time enforce that all the segments of the streamline will have equal length. """ bundle_downsampled = set_number_of_points(bundle, 12) n_pts_ds = [len(s) for s in bundle_downsampled] """ Alternatively, the function ``approx_polygon_track`` allows to reduce the number of points so that they are more points in curvy regions and less points in less curvy regions. In contrast with ``set_number_of_points`` it does not enforce that segments should be of equal size. """ bundle_downsampled2 = [approx_polygon_track(s, 0.25) for s in bundle] n_pts_ds2 = [len(streamline) for streamline in bundle_downsampled2] """ Both, ``set_number_of_points`` and ``approx_polygon_track`` can be thought as methods for lossy compression of streamlines. """ from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() ren.SetBackground(*window.colors.white) bundle_actor = actor.streamtube(bundle, window.colors.red, linewidth=0.3)
del streams,hdr """ Perform Local Skeleton Clustering (LSC) with a 5mm threshold: """ now=time.clock() C=td.local_skeleton_clustering(tracks,d_thr=5) print('Done in %.2f s' % (time.clock()-now,)) """ Reduce the number of points for faster visualization using the ``approx_polygon_track`` algorithm which retains points depending on how much they are need to define the shape of the track: """ T=[td.approx_polygon_track(t) for t in T] """ Show the initial *Fornix* dataset: """ r=fvtk.ren() fvtk.add(r,fvtk.line(T,fvtk.white,opacity=1)) #fvtk.show(r) fvtk.record(r,n_frames=1,out_path='fornix_initial',size=(600,600)) """ .. figure:: fornix_initial1000000.png :align: center **Initial Fornix dataset**.
. The function ``downsample`` can be used to set the number of points of a streamline at a specific number and at the same time enforce that all the segments of the streamline will have equal length. """ bundle_downsampled = [downsample(s, 12) for s in bundle] n_pts_ds = [len(s) for s in bundle_downsampled] """ Alternatively, the function ``approx_polygon_track`` allows to reduce the number of points so that they are more points in curvy regions and less points in less curvy regions. In contrast with ``downsample`` it does not enforce that segments should be of equal size. """ bundle_downsampled2 = [approx_polygon_track(s, 0.25) for s in bundle] n_pts_ds2 = [len(streamline) for streamline in bundle_downsampled2] """ Both, ``downsample`` and ``approx_polygon_track`` can be thought as methods for lossy compression of streamlines. """ from dipy.viz import fvtk ren = fvtk.ren() ren.SetBackground(*fvtk.colors.white) bundle_actor = fvtk.streamtube(bundle, fvtk.colors.red, linewidth=0.3) fvtk.add(ren, bundle_actor)
def lossy_compression_of_tractogram(tractogramfile, outdir, rate=0.392, search_optimal_rate=False, weightsfile=None, weights_thr=0., max_search_dist=2.2, verbose=0): """ Reduce the number of points of the track by keeping intact the start and endpoints of the track and trying to remove as many points as possible without distorting much the shape of the track, ie. more points in curvy regions and less points in less curvy regions. Parameters ---------- tractogramfile: str the path to the tractogram. outdir: str the destination folder. rate: float, default 0.392 the compression rate, ie. smoothing parameter (<0.392 smoother, >0.392 rougher). search_optimal_rate: bool, default False determine the optimal compression rate. weightsfile: str, default None use these weights to remove unsignificant streamlines. weights_thr: float, default 0. the threshold used to identify unsignificant streamlines. max_search_dist: float, default 2.2 the maximum distance between the initial and downsampled streamlines allowed during the best rate search. verbose: int, default 0 the verbosity level. Returns ------- compressed_tractogramfile: str the compressed tractogram. nb_points_file: str the compression result compared to the original sampling. """ # Load the tractogram trk = nibabel.streamlines.load(tractogramfile) if verbose > 0: print("[info] Number of tracks: {0}".format(len(trk.streamlines))) # Keep only significant streamlines tracks = trk.streamlines if weightsfile is not None: weights = numpy.loadtxt(weightsfile) keep_indices = numpy.where(weights > weights_thr)[0] tracks = list(numpy.array(tracks)[keep_indices]) weights = weights[numpy.where(keep_indices)[0]] if verbose > 0: print("[info] Number of significant tracks: {0}".format( len(tracks))) else: weights = None # Compress tractogram # > dynamic compression rate if search_optimal_rate: rate = "dynamic" ref_lengths = list(length(tracks)) rates = numpy.linspace(1, 0, 21) opt_lengths = numpy.zeros((len(rates), len(tracks))) for idx, optrate in enumerate(rates): if verbose > 0: print("[info] Grid search at rate '{0}'.".format(optrate)) decimated_tracks = [ approx_polygon_track(t, optrate) for t in tracks] opt_lengths[idx] = list(length(decimated_tracks)) opt_lengths[idx] -= ref_lengths opt_lengths = numpy.abs(opt_lengths) if verbose > 2: print("[debug] Optimal lengths: {0}".format(opt_lengths)) opt_lengths[numpy.where(opt_lengths > max_search_dist)] = 0 opt_rate_indices = numpy.argmax(opt_lengths, axis=0) if verbose > 2: print("[debug] Optimal rate indices: {0}".format(opt_rate_indices)) tracks = [approx_polygon_track(t, rates[i]) for t, i in zip(tracks, opt_rate_indices)] # > static compression rate else: tracks = [approx_polygon_track(t, rate) for t in tracks] compressed_tractogramfile = os.path.join( outdir, "compressed_tractogram.trk") compressed_trk = Tractogram( streamlines=tracks, affine_to_rasmm=trk.affine) nibabel.streamlines.save(compressed_trk, compressed_tractogramfile) # Summary graph n_pts_initial = [len(t) for t in trk.streamlines] n_pts_compressed = [len(t) for t in compressed_trk.streamlines] nb_points_file = os.path.join(outdir, "nb_points.png") fig, ax = plt.subplots(1) ax.hist(n_pts_initial, color="r", histtype="step", label="initial") ax.hist(n_pts_compressed, color="b", histtype="step", label="compressed ({0})".format(rate)) ax.set_xlabel("Number of points") ax.set_ylabel("Count") plt.legend() plt.savefig(nb_points_file) return compressed_tractogramfile, nb_points_file
Delete unnecessary data: """ del streams, hdr """ Perform Local Skeleton Clustering (LSC) with a 5mm threshold: """ now = time.clock() C = td.local_skeleton_clustering(tracks, d_thr=5) print('Done in %.2f s' % (time.clock() - now, )) """ Reduce the number of points for faster visualization using the ``approx_polygon_track`` algorithm which retains points depending on how much they are need to define the shape of the track: """ T = [td.approx_polygon_track(t) for t in T] """ Show the initial *Fornix* dataset: """ r = fvtk.ren() fvtk.add(r, fvtk.line(T, fvtk.white, opacity=1)) #fvtk.show(r) fvtk.record(r, n_frames=1, out_path='fornix_initial', size=(600, 600)) """ .. figure:: fornix_initial1000000.png :align: center **Initial Fornix dataset**. """ """