def displaySphericalHist(odf, pts, minmax=False): # assumes pts and odf are hemisphere fullsphere = HemiSphere(xyz=pts).mirror() fullodf = np.concatenate((odf, odf), axis=0) r = fvtk.ren() if minmax: a = fvtk.sphere_funcs(fullodf - fullodf.min(), fullsphere) else: a = fvtk.sphere_funcs(fullodf, fullsphere) fvtk.add(r, a) fvtk.show(r)
def plot_proj_shell(ms, use_sym=True, use_sphere=True, same_color=False, rad=0.025): ren = fvtk.ren() ren.SetBackground(1, 1, 1) if use_sphere: sphere = get_sphere('symmetric724') sphere_actor = fvtk.sphere_funcs(np.ones(sphere.vertices.shape[0]), sphere, colormap='winter', scale=0) fvtk.add(ren, sphere_actor) for i, shell in enumerate(ms): if same_color: i = 0 pts_actor = fvtk.point(shell, vtkcolors[i], point_radius=rad) fvtk.add(ren, pts_actor) if use_sym: pts_actor = fvtk.point(-shell, vtkcolors[i], point_radius=rad) fvtk.add(ren, pts_actor) fvtk.show(ren)
def prepare_odfplot(data, params, dipy_sph, p_slice=None): p_slice = params['slice'] if p_slice is None else p_slice data = (data, ) if type(data) is np.ndarray else data slicedims = data[0][p_slice].shape[:-1] l_labels = data[0].shape[-1] camera_params, long_ax, view_ax, stack_ax = \ prepare_plot_camera(slicedims, datalen=len(data), scale=params['scale']) stack = [u[p_slice] for u in data] if params['spacing']: uniform_odf = np.ones((1, 1, 1, l_labels), order='C') / (4 * np.pi) tile_descr = [1, 1, 1, 1] tile_descr[long_ax] = slicedims[long_ax] spacing = np.tile(uniform_odf, tile_descr) for i in reversed(range(1, len(stack))): stack.insert(i, spacing) if stack_ax == max(long_ax, stack_ax): stack = list(reversed(stack)) plotdata = np.concatenate(stack, axis=stack_ax) r = fvtk.ren() r_data = fvtk.sphere_funcs(plotdata, dipy_sph, colormap='jet', norm=params['norm'], scale=params['scale']) fvtk.add(r, r_data) r.set_camera(**camera_params) return r
def draw_ellipsoid(data, gtab, outliers, data_without_noise): bvecs = gtab.bvecs raw_data = bvecs * np.array([data, data, data]).T ren = fvtk.ren() # Draw Sphere of predicted data new_sphere = sphere.Sphere(xyz=bvecs[~gtab.b0s_mask, :]) sf1 = fvtk.sphere_funcs(data_without_noise[~gtab.b0s_mask], new_sphere, colormap=None, norm=False, scale=1) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1) # Draw Raw Data as points, Red means outliers good_values = [index for index, voxel in enumerate(outliers) if voxel == 0] bad_values = [index for index, voxel in enumerate(outliers) if voxel == 1] point_actor_good = fvtk.point(raw_data[good_values, :], fvtk.colors.yellow, point_radius=.05) point_actor_bad = fvtk.point(raw_data[bad_values, :], fvtk.colors.red, point_radius=0.05) fvtk.add(ren, point_actor_good) fvtk.add(ren, point_actor_bad) fvtk.show(ren)
def show_sim_odfs(peaks, sphere, title): ren = fvtk.ren() odf = np.dot(peaks.shm_coeff, peaks.invB) odf2 = peaks.odf print(np.sum( np.abs(odf - odf2))) sfu = fvtk.sphere_funcs(odf, sphere, norm=True) fvtk.add(ren, sfu) fvtk.show(ren, title=title)
def draw_p(p, x, new_sphere): ren = fvtk.ren() raw_data = x * np.array([p, p, p]) sf1 = fvtk.sphere_funcs(raw_data, new_sphere, colormap=None, norm=False, scale=0) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1) fvtk.show(ren)
def plotODF(ODF, sphere): r = fvtk.ren() sfu = fvtk.sphere_funcs(ODF, sphere, scale=2.2, norm=True) sfu.RotateY(90) # sfu.RotateY(180) fvtk.add(r, sfu) # outname = 'screenshot_signal_r.png' # fvtk.record(r, n_frames=1, out_path = outname, size=(3000, 1500), magnification = 2) fvtk.show(r)
def show_odfs(peaks, sphere): ren = fvtk.ren() odf = np.dot(peaks.shm_coeff, peaks.invB) #odf = odf[14:24, 22, 23:33] #odf = odf[:, 22, :] odf = odf[:, 0, :] sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True) sfu.RotateX(-90) fvtk.add(ren, sfu) fvtk.show(ren)
def show_odf_sample(filename): odf = nib.load(filename).get_data() sphere = get_sphere('symmetric724') from dipy.viz import fvtk r = fvtk.ren() # fvtk.add(r, fvtk.sphere_funcs(odf[:, :, 25], sphere)) fvtk.add(r, fvtk.sphere_funcs(odf[25 - 10:25 + 10, 25 - 10:25 + 10, 25], sphere)) fvtk.show(r)
def draw_p(p, x): ren = fvtk.ren() raw_data = x * np.array([p, p, p]) #point = fvtk.point(raw_data, fvtk.colors.red, point_radius=0.00001) #fvtk.add(ren, point) #fvtk.show(ren) new_sphere = sphere.Sphere(xyz=x) sf1 = fvtk.sphere_funcs(raw_data, new_sphere, colormap=None, norm=False, scale=0) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1)
def show_odfs(peaks, sphere, fname): ren = fvtk.ren() ren.SetBackground(1, 1, 1.) odf = np.dot(peaks.shm_coeff, peaks.invB) #odf = odf[14:24, 22, 23:33] #odf = odf[:, 22, :] odf = odf[:, 0, :] sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True) sfu.RotateX(-90) fvtk.add(ren, sfu) fvtk.show(ren) fvtk.record(ren, n_frames=1, out_path=fname, size=(600, 600))
def show_odfs_with_map(odf, sphere, map): ren = fvtk.ren() sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True) sfu.RotateX(-90) sfu.SetPosition(5, 5, 1) sfu.SetScale(0.435) slice = fvtk.slicer(map, plane_i=None, plane_j=[0]) slice.RotateX(-90) fvtk.add(ren, slice) fvtk.add(ren, sfu) fvtk.show(ren)
def show_odfs_from_nii(fshm_coeff, finvB, sphere=None): odf_sh = nib.load(fshm_coeff).get_data() invB = np.loadtxt(finvB) odf = np.dot(odf_sh, invB.T) # odf = odf[14:24, 22, 23:33] odf = odf[:, 22, :] if sphere is None: sphere = get_sphere('symmetric724') ren = fvtk.ren() sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True) fvtk.add(ren, sfu) fvtk.show(ren)
def show_odfs(fpng, odf_sh, invB, sphere): ren = fvtk.ren() ren.SetBackground(1, 1, 1.0) odf = np.dot(odf_sh, invB) print(odf.shape) odf = odf[14:24, 22, 23:33] # odf = odf[:, 22, :] # odf = odf[:, 0, :] sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True) sfu.RotateX(-90) fvtk.add(ren, sfu) fvtk.show(ren) fvtk.record(ren, n_frames=1, out_path=fpng, size=(900, 900)) fvtk.clear(ren)
def draw_odf(data, gtab, odf, sphere_odf): ren = fvtk.ren() bvecs = gtab.bvecs raw_data = bvecs * np.array([data, data, data]).T # Draw Raw Data as points, Red means outliers point = fvtk.point(raw_data[~gtab.b0s_mask, :], fvtk.colors.red, point_radius=0.05) fvtk.add(ren, point) sf1 = fvtk.sphere_funcs(odf, sphere_odf, colormap=None, norm=False, scale=0) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1) fvtk.show(ren)
def show_odfs_with_map2(odf, sphere, map, w, fpng): ren = fvtk.ren() sfu = fvtk.sphere_funcs(odf, sphere, norm=True) #sfu.RotateX(-90) sfu.SetPosition(w, w, 1) sfu.SetScale(0.435) sli = fvtk.slicer(map, plane_i=None, plane_k=[0], outline=False) #sli.RotateX(-90) fvtk.add(ren, sli) fvtk.add(ren, sfu) #fvtk.add(ren, fvtk.axes((20, 20, 20))) #fvtk.show(ren) fvtk.record(ren, n_frames=1, out_path=fpng, magnification=2, size=(900, 900))
def draw_points(data, gtab, predicted_data): ren = fvtk.ren() bvecs = gtab.bvecs raw_points = bvecs * np.array([data, data, data]).T predicted_points = bvecs * np.array([predicted_data, predicted_data, predicted_data]).T # Draw Raw Data as points, Red means outliers point = fvtk.point(raw_points[~gtab.b0s_mask, :], fvtk.colors.red, point_radius=0.02) fvtk.add(ren, point) new_sphere = sphere.Sphere(xyz=bvecs[~gtab.b0s_mask, :]) sf1 = fvtk.sphere_funcs(predicted_data[~gtab.b0s_mask], new_sphere, colormap=None, norm=False, scale=0) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1) fvtk.show(ren)
def show_odf_sample(filename): odf = nib.load(filename).get_data() from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.viz import fvtk r = fvtk.ren() #odf = odf[:, :, 25] #fvtk.add(r, fvtk.sphere_funcs(odf[:, :, None], sphere, norm=True)) odf = odf[:, 22, :] #odf = odf[14: 23, 22, 34: 43] #odf = odf[14:24, 22, 23:33] fvtk.add(r, fvtk.sphere_funcs(odf[:, None, :], sphere, norm=True)) fvtk.show(r)
def draw_points(data, gtab, predicted_data): ren = fvtk.ren() bvecs = gtab.bvecs raw_points = bvecs * np.array([data, data, data]).T predicted_points = bvecs * np.array( [predicted_data, predicted_data, predicted_data]).T # Draw Raw Data as points, Red means outliers point = fvtk.point(raw_points[~gtab.b0s_mask, :], fvtk.colors.red, point_radius=0.02) fvtk.add(ren, point) new_sphere = sphere.Sphere(xyz=bvecs[~gtab.b0s_mask, :]) sf1 = fvtk.sphere_funcs(predicted_data[~gtab.b0s_mask], new_sphere, colormap=None, norm=False, scale=0) sf1.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf1) fvtk.show(ren)
sphere = get_sphere('symmetric724') """ Compute the ODFs """ odf = mapfit.odf(sphere) print('odf.shape (%d, %d, %d, %d)' % odf.shape) """ Display the ODFs """ r = fvtk.ren() sfu = fvtk.sphere_funcs(odf, sphere, colormap='jet') sfu.RotateX(-90) fvtk.add(r, sfu) fvtk.record(r, n_frames=1, out_path='odfs.png', size=(600, 600)) """ .. figure:: odfs.png :align: center **Orientation distribution functions**. With MAPMRI it is also possible to extract the Return To the Origin Probability (RTOP), the Return To the Axis Probability (RTAP), and the Return To the Plane Probability (RTPP). These ensemble average propagator (EAP) features directly reflects microstructural properties of the underlying tissues [Ozarslan2013]_. """
from dipy.viz import fvtk from dipy.data import get_sphere from dipy.reconst.shm import sf_to_sh, sh_to_sf ren = fvtk.ren() # convolve kernel with delta spike spike = np.zeros((7, 7, 7, k.get_orientations().shape[0]), dtype=np.float64) spike[3, 3, 3, 0] = 1 spike_shm_conv = convolve(sf_to_sh(spike, k.get_sphere(), sh_order=8), k, sh_order=8, test_mode=True) sphere = get_sphere('symmetric724') spike_sf_conv = sh_to_sf(spike_shm_conv, sphere, sh_order=8) model_kernel = fvtk.sphere_funcs((spike_sf_conv * 6)[3,:,:,:], sphere, norm=False, radial_scale=True) fvtk.add(ren, model_kernel) fvtk.camera(ren, pos=(30, 0, 0), focal=(0, 0, 0), viewup=(0, 0, 1), verbose=False) fvtk.record(ren, out_path='kernel.png', size=(900, 900)) """ .. figure:: kernel.png :align: center Visualization of the contour enhancement kernel. """ """ Shift-twist convolution is applied on the noisy data """
""" Obviously, the quantities are identical. Finally lets try to visualize the orientation distribution functions of a small rectangular area around the middle of our datasets. """ i,j,k,w = np.array(data.shape) / 2 data_small = data[i-5:i+5, j-5:j+5, k-2:k+2] from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.viz import fvtk r = fvtk.ren() fvtk.add(r, fvtk.sphere_funcs(tenmodel.fit(data_small).odf(sphere), sphere, colormap=None)) print('Saving illustration as tensor_odfs.png') fvtk.record(r, n_frames=1, out_path='tensor_odfs.png', size=(600, 600)) """ .. figure:: tensor_odfs.png :align: center **Tensor ODFs**. Note that while the tensor model is an accurate and reliable model of the diffusion signal in the white matter, it has the drawback that it only has one principal diffusion direction. Therefore, in locations in the brain that contain multiple fiber populations crossing each other, the tensor model may indicate that the principal diffusion direction is intermediate to these
from dipy.data import get_sphere sphere = get_sphere('symmetric724') csd_odf = csd_fit.odf(sphere) from dipy.viz import fvtk ren = fvtk.ren() """ Here we visualize only a 30x30 region. """ fodf_spheres = fvtk.sphere_funcs(csd_odf, sphere, scale=1.3, norm=False) fvtk.add(ren, fodf_spheres) print('Saving illustration as csd_odfs.png') fvtk.record(ren, out_path='csd_odfs.png', size=(600, 600)) """ .. figure:: csd_odfs.png :align: center **CSD ODFs**. .. [Tournier2007] J-D. Tournier, F. Calamante and A. Connelly, "Robust determination of the fibre orientation distribution in diffusion MRI: Non-negativity constrained super-resolved spherical deconvolution", Neuroimage, vol. 35, no. 4, pp. 1459-1472, 2007. .. include:: ../links_names.inc
.. figure:: tensor_ellipsoids.png :align: center **Tensor Ellipsoids**. """ fvtk.clear(ren) """ Finally, we can visualize the tensor orientation distribution functions for the same area as we did with the ellipsoids. """ tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere) fvtk.add(ren, fvtk.sphere_funcs(tensor_odfs, sphere, colormap=None)) #fvtk.show(r) print('Saving illustration as tensor_odfs.png') fvtk.record(ren, n_frames=1, out_path='tensor_odfs.png', size=(600, 600)) """ .. figure:: tensor_odfs.png :align: center **Tensor ODFs**. Note that while the tensor model is an accurate and reliable model of the diffusion signal in the white matter, it has the drawback that it only has one principal diffusion direction. Therefore, in locations in the brain that contain multiple fiber populations crossing each other, the tensor model may indicate that the principal diffusion direction is intermediate to these
md1 = dti.mean_diffusivity(tenfit.evals) nibabel.save(nibabel.Nifti1Image(md1.astype(numpy.float32), img.affine), 'output_md.nii') shutil.move('output_md.nii', args.output_nifti1_md) move_directory_files(input_dir, args.output_nifti1_md_files_path, copy=True) fa = numpy.clip(fa, 0, 1) rgb = color_fa(fa, tenfit.evecs) nibabel.save(nibabel.Nifti1Image(numpy.array(255 * rgb, 'uint8'), img.affine), 'output_rgb.nii') shutil.move('output_rgb.nii', args.output_nifti1_rgb) move_directory_files(input_dir, args.output_nifti1_rgb_files_path, copy=True) sphere = get_sphere('symmetric724') ren = fvtk.ren() evals = tenfit.evals[13:43, 44:74, 28:29] evecs = tenfit.evecs[13:43, 44:74, 28:29] cfa = rgb[13:43, 44:74, 28:29] cfa /= cfa.max() fvtk.add(ren, fvtk.tensor(evals, evecs, cfa, sphere)) fvtk.record(ren, n_frames=1, out_path='tensor_ellipsoids.png', size=(600, 600)) shutil.move('tensor_ellipsoids.png', args.output_png_ellipsoids) fvtk.clear(ren) tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere) fvtk.add(ren, fvtk.sphere_funcs(tensor_odfs, sphere, colormap=None)) fvtk.record(ren, n_frames=1, out_path='tensor_odfs.png', size=(600, 600)) shutil.move('tensor_odfs.png', args.output_png_odfs)
Fit the SHORE model to the data """ asmfit = asm.fit(data_small) """ Load an odf reconstruction sphere """ sphere = get_sphere('symmetric724') """ Compute the ODF """ odf = asmfit.odf(sphere) print('odf.shape (%d, %d, %d)' % odf.shape) """ Display the ODFs """ r = fvtk.ren() fvtk.add(r, fvtk.sphere_funcs(odf, sphere, colormap='jet')) fvtk.show(r) fvtk.record(r, n_frames=1, out_path='odfs.png', size=(600, 600)) """ .. include:: ../links_names.inc """
data_small = maskdata[13:43, 44:74, 28:29] from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.viz import fvtk r = fvtk.ren() csaodfs = csamodel.fit(data_small).odf(sphere) """ It is common with CSA ODFs to produce negative values, we can remove those using ``np.clip`` """ csaodfs = np.clip(csaodfs, 0, np.max(csaodfs, -1)[..., None]) fvtk.add(r, fvtk.sphere_funcs(csaodfs, sphere, colormap='jet')) print('Saving illustration as csa_odfs.png') fvtk.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) """ .. figure:: csa_odfs.png :align: center **Constant Solid Angle ODFs**. .. include:: ../links_names.inc """
Load an odf reconstruction sphere """ sphere = get_sphere('symmetric724') """ Compute the ODFs """ odf = asmfit.odf(sphere) print('odf.shape (%d, %d, %d)' % odf.shape) """ Display the ODFs """ r = fvtk.ren() sfu = fvtk.sphere_funcs(odf[:, None, :], sphere, colormap='jet') sfu.RotateX(-90) fvtk.add(r, sfu) fvtk.record(r, n_frames=1, out_path='odfs.png', size=(600, 600)) """ .. figure:: odfs.png :align: center **Orientation distribution functions**. .. [Merlet2013] Merlet S. et. al, "Continuous diffusion signal, EAP and ODF estimation via Compressive Sensing in diffusion MRI", Medical Image Analysis, 2013. .. [Cheng2011] Cheng J. et. al, "Theoretical Analysis and Pratical Insights on EAP Estimation via Unified HARDI Framework", MICCAI
""" 0.21197 We can double-check that we have a good response function by visualizing the response function's ODF. Here is how you would do that: """ from dipy.viz import fvtk ren = fvtk.ren() evals = response[0] evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.sims.voxel import single_tensor_odf response_odf = single_tensor_odf(sphere.vertices, evals, evecs) response_actor = fvtk.sphere_funcs(response_odf, sphere) fvtk.add(ren, response_actor) print('Saving illustration as csd_response.png') fvtk.record(ren, out_path='csd_response.png', size=(200, 200)) """ .. figure:: csd_response.png :align: center **Estimated response function**. """ fvtk.rm(ren, response_actor) """ Depending on the dataset, FA threshold may not be the best way to find the best possible response function. For one, it depends on the diffusion tensor
gtab = gradient_table(20000 * np.ones(len(sphere.vertices)), sphere.vertices) S, sticks = MultiTensor(gtab, mevals, S0=100, angles=[(0, 0), (20, 0)], fractions=[50, 50], snr=None) # S = np.log(S/np.float(S[0])) S2, sticks2 = MultiTensor(gtab, mevals, S0=100, angles=[(0, 0), (35, 0)], fractions=[50, 50], snr=None) # S2 = np.log(S2/np.float(S2[0])) from dipy.viz import fvtk r = fvtk.ren() # fvtk.add(r, fvtk.dots(sphere.vertices, fvtk.red)) fvtk.add(r, fvtk.sphere_funcs(np.vstack((S, S2)), sphere, scale=30., norm=False)) fvtk.add(r, fvtk.sphere_funcs(np.abs(S - S2), sphere, scale=30., norm=False)) fvtk.show(r)
# nib.save(nib.Nifti1Image(odf_sh, affine), model_tag + 'fodf_sh.nii.gz') from dipy.reconst.shm import real_sph_harm_mrtrix from dipy.data import get_sphere from dipy.core.geometry import cart2sphere r, theta, phi = cart2sphere(sphere.x, sphere.y, sphere.z) B_regul, m, n = real_sph_harm_mrtrix(8, theta[:, None], phi[:, None]) fodf = np.dot(fodf_sh, B_regul.T) from dipy.viz import fvtk #odf = odf[25 - 10:25 + 10, 25 - 10:25 + 10, 25] r = fvtk.ren() fvtk.add(r, fvtk.sphere_funcs(odf, sphere)) fvtk.show(r) fvtk.clear(r) # odf_var = tv_denoise_4d(odf, weight=0.1) # fvtk.add(r, fvtk.sphere_funcs(odf_var, sphere)) # fvtk.show(r) # fvtk.clear(r) # #odf_sh2 = odf_sh[25 - 10:25 + 10, 25 - 10:25 + 10, 25] # odf2 = np.dot(odf_sh, B_regul.T) # fvtk.add(r, fvtk.sphere_funcs(odf2, sphere)) # fvtk.show(r) # fvtk.clear(r) r = fvtk.ren()
""" 0.21197 We can double-check that we have a good response function by visualizing the response function's ODF. Here is how you would do that: """ from dipy.viz import fvtk ren = fvtk.ren() evals = response[0] evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.sims.voxel import single_tensor_odf response_odf = single_tensor_odf(sphere.vertices, evals, evecs) response_actor = fvtk.sphere_funcs(response_odf, sphere) fvtk.add(ren, response_actor) print('Saving illustration as csd_response.png') fvtk.record(ren, out_path='csd_response.png', size=(200, 200)) """ .. figure:: csd_response.png :align: center **Estimated response function**. """ fvtk.rm(ren, response_actor) """
""" For the purpose of the example, we will consider a small volume of data containing parts of the corpus callosum and of the centrum semiovale """ data_small = data[20:50, 55:85, 38:39] """ Fitting the model to this small volume of data, we calculate the ODF of this model on the sphere, and plot it. """ sf_fit = sf_model.fit(data_small) sf_odf = sf_fit.odf(sphere) fodf_spheres = fvtk.sphere_funcs(sf_odf, sphere, scale=1.3, norm=True) ren = fvtk.ren() fvtk.add(ren, fodf_spheres) print('Saving illustration as sf_odfs.png') fvtk.record(ren, out_path='sf_odfs.png', size=(1000, 1000)) """ We can extract the peaks from the ODF, and plot these as well """ sf_peaks = dpp.peaks_from_model(sf_model, data_small, sphere, relative_peak_threshold=.5,
ODF. peak_values shows the maxima values of the ODF and peak_indices gives us their position on the discrete sphere that was used to do the reconstruction of the ODF. In order to obtain the full ODF return_odf should be True. Before enabling this option make sure that you have enough memory. Finally lets try to visualize the orientation distribution functions of a small rectangular area around the middle of our datasets. """ i,j,k,w = np.array(data.shape) / 2 data_small = data[i-5:i+5, j-5:j+5, k-2:k+2] from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.viz import fvtk r = fvtk.ren() fvtk.add(r, fvtk.sphere_funcs(csamodel.fit(data_small).odf(sphere), sphere, colormap='jet')) print('Saving illustration as csa_odfs.png') fvtk.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) """ .. figure:: csa_odfs.png :align: center **Constant Solid Angle ODFs**. .. include:: ../links_names.inc """
""" """ For the ODF simulation we will need a sphere. Because we are interested in a simulation of only a single voxel, we can use a sphere with very high resolution. We generate that by subdividing the triangles of one of Dipy's cached spheres, which we can read in the following way. """ sphere = get_sphere('symmetric724') sphere = sphere.subdivide(2) odf = multi_tensor_odf(sphere.vertices, mevals, angles, fractions) from dipy.viz import fvtk ren = fvtk.ren() odf_actor = fvtk.sphere_funcs(odf, sphere) odf_actor.RotateX(90) fvtk.add(ren, odf_actor) print('Saving illustration as multi_tensor_simulation') fvtk.record(ren, out_path='multi_tensor_simulation.png', size=(300, 300)) """ .. figure:: multi_tensor_simulation.png :align: center **Simulating a MultiTensor ODF** """
ax1 = fig.add_subplot(312, sharex=ax1) ax1.plot(x, l2_dists) ax2 = fig.add_subplot(313, sharex=ax1) ax2.plot(x, w1_dists) fig.tight_layout() plt.savefig(plots_file) #plt.show() l_labels = mf.mdims['l_labels'] uniform_odf = np.ones((l_labels, 1), order='C') / l_labels odfs = (fin[:, 0:1], ) for i in range(1, fin.shape[1], 2): odfs += (uniform_odf, fin[:, i:(i + 1)]) plotdata = np.hstack(odfs)[:, :, np.newaxis] plotdata = plotdata[:, :, :, np.newaxis].transpose(1, 2, 3, 0) # plot upd and fin as q-ball data sets r = fvtk.ren() fvtk.add( r, fvtk.sphere_funcs(plotdata, qball_sphere, colormap='jet', norm=False, scale=11.0)) fvtk.snapshot(r, size=(2000, 1000), offscreen=True, fname=odfplot_file) #fvtk.show(r, size=(1500, 500))
proj = np.dot(b_vector, sphere.vertices.T) #proj[np.abs(proj) < 0.1] = 0 #proj = proj * (bnorm[:, None] / 5.) gqi_vector = np.real(H(proj * model.Lambda / np.pi)) return np.dot(data, gqi_vector), proj odf, proj = optimal_transform(gqi_model, data, sphere) from dipy.viz import fvtk r = fvtk.ren() fvtk.add(r, fvtk.sphere_funcs(gqi_odf, sphere)) fvtk.show(r) dsi_model = DiffusionSpectrumDeconvModel(gtab) dsi_odf = dsi_model.fit(data).odf(sphere) fvtk.clear(r) fvtk.add(r, fvtk.sphere_funcs(dsi_odf, sphere)) fvtk.show(r) fvtk.clear(r) fvtk.add(r, fvtk.sphere_funcs(odf, sphere)) fvtk.show(r) def investigate_internals():
qball_sphere = dipy.core.sphere.Sphere(xyz=b_sph.v.T, faces=b_sph.faces.T) maskdata, mask = median_otsu(S_data, 3, 1, True, vol_idx=range(10, 50), dilate=2) S_data = maskdata[20:30, 61, 28] #u = solve_shm({ 'S': S_data, 'gtab': gtab, 'sph': qball_sphere }) u = solve_cvx({'S': S_data, 'gtab': gtab, 'sph': b_sph}) plotdata = u.copy() if len(plotdata.shape) < 3: plotdata = plotdata[:, :, np.newaxis, np.newaxis].transpose(0, 2, 3, 1) else: plotdata = plotdata[:, :, :, np.newaxis].transpose(0, 1, 3, 2) plot_scale = 2.4 plot_norm = True r = fvtk.ren() fvtk.add( r, fvtk.sphere_funcs(plotdata, qball_sphere, colormap='jet', norm=plot_norm, scale=plot_scale)) fvtk.show(r, size=(1024, 768))
filename = os.path.join(os.getcwd(), 'test_data', filename) plt.style.use('ggplot') # Create a render object ren = fvtk.ren() # Define values for fODF reconstruction evals = np.array([2, 2, 5]) evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) # Set a shpere sphere = get_sphere('symmetric642') # Assign responses response_odf = single_tensor_odf(sphere.vertices, evals, evecs) response_actor = fvtk.sphere_funcs(response_odf, sphere) # Render the spherical function fvtk.add(ren, response_actor) print('[ OK ]\t Saving illustration: ' + filename) fvtk.record(ren, out_path=filename, size=size) print('[ OK ] DONE!') # Visualise the output img = plt.imread(filename) plt.imshow(img) plt.axis('off') plt.show()
def draw_adc(D_noisy, D, threeD=False): # 3D Plot if threeD == True: amound = 50 alpha = np.linspace(0, 2 * np.pi, amound) theta = np.linspace(0, 2 * np.pi, amound) vector = np.empty((amound**2, 3)) vector[:, 0] = (np.outer(np.sin(theta), np.cos(alpha))).reshape( (-1, 1))[:, 0] vector[:, 1] = (np.outer(np.sin(theta), np.sin(alpha))).reshape( (-1, 1))[:, 0] vector[:, 2] = (np.outer(np.cos(theta), np.ones(amound))).reshape( (-1, 1))[:, 0] adc_noisy = np.empty((vector.shape[0], 3)) shape_noisy = np.empty((vector.shape[0], 1)) shape = np.empty((vector.shape[0], 1)) for i in range(vector.shape[0]): adc_noisy[i] = np.dot( vector[i], np.dot(vector[i], np.dot(D_noisy, vector[i].T))) shape_noisy[i] = np.dot(vector[i], np.dot(D_noisy, vector[i].T)) shape[i] = np.dot(vector[i], np.dot(D, vector[i].T)) ren = fvtk.ren() # noisy sphere new_sphere = sphere.Sphere(xyz=vector) sf1 = fvtk.sphere_funcs(shape_noisy[:, 0], new_sphere, colormap=None, norm=False, scale=0.0001) sf1.GetProperty().SetOpacity(0.35) sf1.GetProperty().SetColor((1, 0, 0)) fvtk.add(ren, sf1) # ideal sphere sf2 = fvtk.sphere_funcs(shape[:, 0], new_sphere, colormap=None, norm=False, scale=0.0001) sf2.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf2) #point_actor_bad = fvtk.point(adc_noisy, fvtk.colors.red, point_radius=0.00003) #fvtk.add(ren, point_actor_bad) fvtk.show(ren) # 2D Plot in XY-Plane alpha = np.linspace(0, 2 * np.pi, 100) vector = np.empty((100, 3)) vector[:, 0] = np.cos(alpha) vector[:, 1] = np.sin(alpha) vector[:, 2] = 0.0 adc_noisy_2d = np.empty((vector.shape[0], 3)) adc_2d = np.empty((vector.shape[0], 3)) for i in range(vector.shape[0]): adc_noisy_2d[i] = np.dot( vector[i], np.dot(vector[i], np.dot(D_noisy, vector[i].T))) adc_2d[i] = np.dot(vector[i], np.dot(vector[i], np.dot(D, vector[i].T))) # Change Axis so that there is 20% room on each side of the plot x = np.concatenate((adc_noisy_2d, adc_2d), axis=0) minimum = np.min(x, axis=0) maximum = np.max(x, axis=0) plt.plot(adc_noisy_2d[:, 0], adc_noisy_2d[:, 1], 'r') plt.plot(adc_2d[:, 0], adc_2d[:, 1], 'b') plt.axis([ minimum[0] * 1.2, maximum[0] * 1.2, minimum[1] * 1.2, maximum[1] * 1.2 ]) plt.xlabel('ADC (mm2*s-1)') plt.ylabel('ADC (mm2*s-1)') red_patch = mpatches.Patch(color='red', label='Noisy ADC') blue_patch = mpatches.Patch(color='blue', label='Ideal ADC') plt.legend(handles=[red_patch, blue_patch]) plt.show()
dsid_odf = dsid_model.fit(signal).odf(sphere) """ Finally, we can visualize the ground truth ODF, together with the DSI and DSI with deconvolution ODFs and observe that with the deconvolved method it is easier to resolve the correct fiber directions because the ODF is sharper. """ from dipy.viz import fvtk ren = fvtk.ren() odfs = np.vstack((odf_gt, dsi_odf, dsid_odf))[:, None, None] odf_actor = fvtk.sphere_funcs(odfs, sphere) odf_actor.RotateX(90) fvtk.add(ren, odf_actor) fvtk.record(ren, out_path='dsid.png', size=(300, 300)) """ .. figure:: dsid.png :align: center **Ground truth ODF (left), DSI ODF (middle), DSI with Deconvolution ODF(right)** .. [Canales10] Canales-Rodriguez et al., Deconvolution in Diffusion Spectrum Imaging, Neuroimage, vol 50, no 1, 136-149, 2010. """
def draw_adc(D_noisy, D, threeD = False): # 3D Plot if threeD == True: amound = 50 alpha = np.linspace(0, 2*np.pi, amound) theta = np.linspace(0, 2*np.pi, amound) vector = np.empty((amound**2, 3)) vector[:, 0] = (np.outer(np.sin(theta), np.cos(alpha))).reshape((-1,1))[:,0] vector[:, 1] = (np.outer(np.sin(theta), np.sin(alpha))).reshape((-1,1))[:,0] vector[:, 2] = (np.outer(np.cos(theta), np.ones(amound))).reshape((-1,1))[:,0] adc_noisy = np.empty((vector.shape[0],3)) shape_noisy = np.empty((vector.shape[0],1)) shape = np.empty((vector.shape[0],1)) for i in range(vector.shape[0]): adc_noisy[i] = np.dot(vector[i], np.dot(vector[i], np.dot(D_noisy, vector[i].T))) shape_noisy[i] = np.dot(vector[i], np.dot(D_noisy, vector[i].T)) shape[i] = np.dot(vector[i], np.dot(D, vector[i].T)) ren = fvtk.ren() # noisy sphere new_sphere = sphere.Sphere(xyz=vector) sf1 = fvtk.sphere_funcs(shape_noisy[:, 0], new_sphere, colormap=None, norm=False, scale=0.0001) sf1.GetProperty().SetOpacity(0.35) sf1.GetProperty().SetColor((1, 0, 0)) fvtk.add(ren, sf1) # ideal sphere sf2 = fvtk.sphere_funcs(shape[:, 0], new_sphere, colormap=None, norm=False, scale=0.0001) sf2.GetProperty().SetOpacity(0.35) fvtk.add(ren, sf2) #point_actor_bad = fvtk.point(adc_noisy, fvtk.colors.red, point_radius=0.00003) #fvtk.add(ren, point_actor_bad) fvtk.show(ren) # 2D Plot in XY-Plane alpha = np.linspace(0, 2*np.pi, 100) vector = np.empty((100, 3)) vector[:, 0] = np.cos(alpha) vector[:, 1] = np.sin(alpha) vector[:, 2] = 0.0 adc_noisy_2d = np.empty((vector.shape[0],3)) adc_2d = np.empty((vector.shape[0],3)) for i in range(vector.shape[0]): adc_noisy_2d[i] = np.dot(vector[i], np.dot(vector[i], np.dot(D_noisy, vector[i].T))) adc_2d[i] = np.dot(vector[i], np.dot(vector[i], np.dot(D, vector[i].T))) # Change Axis so that there is 20% room on each side of the plot x = np.concatenate((adc_noisy_2d, adc_2d), axis=0) minimum = np.min(x, axis=0) maximum = np.max(x, axis=0) plt.plot(adc_noisy_2d[:,0],adc_noisy_2d[:,1], 'r') plt.plot(adc_2d[:,0],adc_2d[:,1],'b') plt.axis([minimum[0]*1.2, maximum[0]*1.2, minimum[1]*1.2, maximum[1]*1.2]) plt.xlabel('ADC (mm2*s-1)') plt.ylabel('ADC (mm2*s-1)') red_patch = mpatches.Patch(color='red', label='Noisy ADC') blue_patch = mpatches.Patch(color='blue', label='Ideal ADC') plt.legend(handles=[red_patch, blue_patch]) plt.show()
ratio = l01[1] / l01[0] #ratio = 0.2 from dipy.data import get_sphere sphere = get_sphere('symmetric724') # csd_model = ConstrainedSphericalDeconvModel(gtab, (evals, S0), regul_sphere = sphere) # csd_fit = csd_model.fit(data[25 - 10:25 + 10, 25 - 10:25 + 10, 25]) # csd_odf = csd_fit.odf(sphere) # from dipy.viz import fvtk # r = fvtk.ren() # fvtk.add(r, fvtk.sphere_funcs(csd_odf, sphere)) # fvtk.show(r) csdt_model = ConstrainedSDTModel(gtab, ratio, regul_sphere = sphere) csdt_fit = csdt_model.fit(data[25 - 10:25 + 10, 25 - 10:25 + 10, 25]) csdt_odf = csdt_fit.odf(sphere) from dipy.viz import fvtk r = fvtk.ren() fvtk.clear(r) fvtk.add(r, fvtk.sphere_funcs(csdt_odf, sphere)) fvtk.show(r)
scms.append(scm) smoments = [0, 6] lambdas = [0, 0.001, 0.01, 0.1, 1, 2] for smoment in smoments: for (k, lambd) in enumerate(lambdas): for (i, radial_order) in enumerate(radial_orders): scm = scms[i] scm.lambd = lambd for (j, angle) in enumerate(angles): print(radial_order, angle) odfs[i + 1, j] = scm.fit(sim_data[j]).odf(sphere, smoment=smoment) odfs = odfs[:, None, :] ren = fvtk.ren() fvtk.add(ren, fvtk.sphere_funcs(odfs, sphere)) fvtk.camera(ren, [0, -5, 0], [0, 0, 0], viewup=[-1, 0, 0]) #fvtk.show(ren) fname = 'shore_cart_odfs_snr_' + str(SNR) + '_s_' + str(smoment) + '_' + str(k) + '_l_' + str(lambd) + '.png' fvtk.record(ren, n_frames=1, out_path=fname, size=(1000, 1000)) odfs = np.squeeze(odfs)
sphere = get_sphere('symmetric724') """ Compute the ODFs The radial order s can be increased to sharpen the results, but it might also make the odfs noisier. Always check the results visually. """ odf = mapfit_both_iso.odf(sphere, s=2) print('odf.shape (%d, %d, %d, %d)' % odf.shape) """ Display the ODFs """ r = fvtk.ren() sfu = fvtk.sphere_funcs(odf, sphere, colormap='jet') sfu.RotateX(-90) fvtk.add(r, sfu) fvtk.record(r, n_frames=1, out_path='odfs.png', size=(600, 600)) """ .. figure:: odfs.png :align: center **Orientation distribution functions**. .. [Ozarslan2013]_ Ozarslan E. et. al, "Mean apparent propagator (MAP) MRI: A novel diffusion imaging method for mapping tissue microstructure", NeuroImage, 2013. .. [Fick2016]_ Fick, Rutger HJ, et al. "MAPL: Tissue microstructure estimation using Laplacian-regularized MAP-MRI and its application to HCP
img = nb.load(img_filename) gtab = gr.gradient_table(bval_filename, bvec_filename) data = img.get_data() n = 100 data = data[:, :, :, 1:n] gtab.bvals = gtab.bvals[1:n] gtab.bvecs = gtab.bvecs[1:n, :] gtab.gradients = gtab.gradients[1:n, :] log.warning('Extracting response and ratio') response, ratio = auto_response(gtab, data, roi_radius=5, fa_thr=0.7) log.warning('Calculating CSD model...') csd_model = ConstrainedSphericalDeconvModel(gtab, response) log.warning('Initialising a sphere...') sphere = get_sphere('symmetric642') ren = fvtk.ren() log.warning('Fitting ODF') data_small = data[30:60, 60:90, 38:39] csd_fit = csd_model.fit(data_small) csd_odf = csd_fit.odf(sphere) fodf_spheres = fvtk.sphere_funcs(csd_odf, sphere, scale=1.2, norm=False) fvtk.add(ren, fodf_spheres) log.warning('Saving illustration as csd_odfs.png') fvtk.record(ren, out_path='csd_odfs.png', size=(600, 600))