Beispiel #1
0
def calculate_fodf(gtab,
                   images,
                   name,
                   sphere=default_sphere,
                   radius=10,
                   fa_threshold=0.7):
    response, ratio = auto_response(gtab,
                                    images,
                                    roi_radius=radius,
                                    fa_thr=fa_threshold)

    csd_model = ConstrainedSphericalDeconvModel(gtab, response)
    csd_fit = csd_model.fit(images)
    csd_odf = csd_fit.odf(sphere)
    fodf_spheres = actor.odf_slicer(csd_odf,
                                    sphere=sphere,
                                    scale=0.9,
                                    norm=False,
                                    colormap='plasma')

    ren = window.Scene()
    ren.add(fodf_spheres)

    print('Saving illustration as csd_odfs_{}.png'.format(name))
    window.record(ren,
                  out_path='results/csd_odfs_{}.png'.format(name),
                  size=(600, 600))
    return csd_fit
Beispiel #2
0
def visualize_pdf(pdf, gtab=None):
    signal = pdf
    s = signal.shape
    grid_s = math.ceil((signal.shape[-1])**(1 / 3))
    signal = signal.reshape(*s[:-1], grid_s, grid_s, grid_s)

    sphere = get_sphere('repulsion724')

    if gtab:
        dsmodel = DiffusionSpectrumModel(gtab)
        signal_xq = np.fft.fftn(signal, axes=[-3, -2, -1])
        dsfit = dsmodel.fit(signal_xq.reshape(*s[:2], -1))
        odfs = dsfit.odf(sphere)
    else:
        signal = signal.reshape(-1, grid_s, grid_s, grid_s)
        odfs = np.stack([
            get_odf(signal[vid], sphere) for vid in range(signal.shape[0])
        ]).reshape(*s[:-1], -1)

    if len(odfs.shape) == 3:
        odfs = odfs[:, :, np.newaxis]

    # visualize
    r = window.Scene()
    sfu = actor.odf_slicer(odfs, sphere=sphere, colormap='plasma', scale=0.5)
    sfu.display(z=0)
    r.add(sfu)
    window.show(r)
Beispiel #3
0
def print_peaks(sh_signal, mask=None):
    if has_fury:
        data_small = sh_signal[:, :, 50:51]
        ren = window.Renderer()

        sh_order = order_from_ncoef(data_small.shape[-1])
        theta = default_sphere.theta
        phi = default_sphere.phi
        sh_params = SIGNAL_PARAMETERS['processing_params']['sh_params']
        basis_type = sh_params['basis_type']
        sph_harm_basis = sph_harm_lookup.get(basis_type)
        sampling_matrix, m, n = sph_harm_basis(sh_order, theta, phi)
        odfs = np.dot(data_small, sampling_matrix.T)

        odfs = np.clip(odfs, 0, np.max(odfs, -1)[..., None])
        odfs_actor = actor.odf_slicer(odfs,
                                      sphere=default_sphere,
                                      colormap='plasma',
                                      scale=0.4)
        odfs_actor.display(z=0)

        ren.add(odfs_actor)
        print('Saving illustration as csa_odfs.png')
        window.record(ren,
                      n_frames=1,
                      out_path='csa_odfs.png',
                      size=(600, 600))
        window.show(ren)
Beispiel #4
0
def plot_response(response_src, out_png=False):

    # start virtual display
    print("starting Xvfb");
    vdisplay = Xvfb()
    vdisplay.start()

    response_src = np.loadtxt(src_txt)
    if len(response_src.shape) > 1:
        response_src = response_src[1]
    sphere = get_sphere('symmetric724')
    sh_resp = AxSymShResponse(0, response_src)
    sig_resp = sh_resp.on_sphere(sphere)
    sig_resp = sig_resp[None, None, None, :]

    ren = window.Renderer()
    sphere_actor = actor.odf_slicer(sig_resp, sphere=sphere,colormap='blues')
    ren.add(sphere_actor)
    my_camera = ren.camera()
    my_camera.SetPosition(1.62, -9.19, 4.01)
    my_camera.SetFocalPoint(0.01, -0.46, -0.19)
    my_camera.SetViewUp(0.24, 0.46, 0.86)

    if out_png != False:
        window.record(ren, out_path=out_png, magnification=10, size=(60, 60))
    else:
        window.show(ren, reset_camera=False)
        print('Camera Settings')
        print('Position: ', '(%.2f, %.2f, %.2f)' % my_camera.GetPosition())
        print('Focal Point: ', '(%.2f, %.2f, %.2f)' % my_camera.GetFocalPoint())
        print('View Up: ', '(%.2f, %.2f, %.2f)' % my_camera.GetViewUp())

    vdisplay.stop()
Beispiel #5
0
def vis_2d_field(odf, sphere):
    """
    Visualize a 2D ODF field.
    """

    r = window.Renderer()
    sfu = actor.odf_slicer(odf.reshape(1, *odf.shape),
                           sphere=sphere,
                           colormap='plasma',
                           scale=0.5)
    sfu.display(x=0)
    r.add(sfu)
    window.show(r)
Beispiel #6
0
    def calculate_fod(self, model):

        sphere = get_sphere(name='symmetric724').subdivide()
        print("calculating fod")
        fods = model.fod(sphere.vertices, visual_odi_lower_bound=0.18)
        print("finsih fod calculation. Start odf splicer")
        fod_spheres = actor.odf_slicer(fods,
                                       sphere=sphere,
                                       scale=1.0,
                                       norm=False,
                                       opacity=1.0)
        print("finish splicer")

        return fod_spheres
Beispiel #7
0
def show_odf_slicer(mcsd_model, data, slice):
    mcsd_fit = mcsd_model.fit(data[:, :, slice])
    mcsd_odf = mcsd_fit.odf(sphere)
    fodf_spheres = actor.odf_slicer(mcsd_odf,
                                    sphere=sphere,
                                    scale=0.01,
                                    norm=False,
                                    colormap='plasma')

    interactive = False
    ren = window.Renderer()
    ren.add(fodf_spheres)
    ren.reset_camera_tight()

    print('Saving illustration as msdodf.png')
    window.record(ren, out_path='msdodf.png', size=(600, 600))

    if interactive:
        window.show(ren)
Beispiel #8
0
def qball(gtab, data, name, sh_order=4):
    qballmodel = QballModel(gtab, sh_order)

    data_small = data[:, :, 39:40]
    qball_fit = qballmodel.fit(data_small)
    qball_odf = qball_fit.odf(default_sphere)
    odf_spheres = actor.odf_slicer(qball_odf,
                                   sphere=default_sphere,
                                   scale=0.9,
                                   norm=False,
                                   colormap='plasma')

    ren = window.Scene()
    ren.add(odf_spheres)

    print('Saving illustration as qball_odfs_{}.png'.format(
        name))  #data.shape[-1] - 1))
    window.record(ren,
                  out_path='results/qball_odfs_{}.png'.format(name),
                  size=(600, 600))
    return qball_odf, qball_fit.shm_coeff
Beispiel #9
0
def calculate_odf(gtab, data, sh_order=4):
    csamodel = CsaOdfModel(gtab, sh_order)

    data_small = data[30:65, 40:75, 39:40]
    csa_odf = csamodel.fit(data_small).odf(default_sphere)
    csa_odf = np.clip(csa_odf, 0, np.max(csa_odf, -1)[..., None])
    odf_spheres = actor.odf_slicer(csa_odf,
                                   sphere=default_sphere,
                                   scale=0.9,
                                   norm=False,
                                   colormap='plasma')

    ren = window.Scene()
    ren.add(odf_spheres)

    print('Saving illustration as csa_odfs_{}.png'.format(data.shape[-1] - 1))
    window.record(ren,
                  out_path='results/csa_odfs_{}.png'.format(data.shape[-1] -
                                                            1),
                  size=(600, 600))
    return csa_odf
Beispiel #10
0
def test_odf_slicer(interactive=False):

    sphere = get_sphere('symmetric362')

    shape = (11, 11, 11, sphere.vertices.shape[0])

    fid, fname = mkstemp(suffix='_odf_slicer.mmap')
    print(fid)
    print(fname)

    odfs = np.memmap(fname, dtype=np.float64, mode='w+',
                     shape=shape)

    odfs[:] = 1

    affine = np.eye(4)
    renderer = window.Renderer()

    mask = np.ones(odfs.shape[:3])
    mask[:4, :4, :4] = 0

    odfs[..., 0] = 1

    odf_actor = actor.odf_slicer(odfs, affine,
                                 mask=mask, sphere=sphere, scale=.25,
                                 colormap='jet')
    fa = 0. * np.zeros(odfs.shape[:3])
    fa[:, 0, :] = 1.
    fa[:, -1, :] = 1.
    fa[0, :, :] = 1.
    fa[-1, :, :] = 1.
    fa[5, 5, 5] = 1

    k = 5
    I, J, K = odfs.shape[:3]

    fa_actor = actor.slicer(fa, affine)
    fa_actor.display_extent(0, I, 0, J, k, k)
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()

    odf_actor.display_extent(0, I, 0, J, k, k)
    odf_actor.GetProperty().SetOpacity(1.0)
    if interactive:
        window.show(renderer, reset_camera=False)

    arr = window.snapshot(renderer)
    report = window.analyze_snapshot(arr, find_objects=True)
    npt.assert_equal(report.objects, 11 * 11)

    renderer.clear()
    renderer.add(fa_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    mask[:] = 0
    mask[5, 5, 5] = 1
    fa[5, 5, 5] = 0
    fa_actor = actor.slicer(fa, None)
    fa_actor.display(None, None, 5)
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='jet',
                                 norm=False, global_cm=True)
    renderer.clear()
    renderer.add(fa_actor)
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    renderer.clear()
    renderer.add(odf_actor)
    renderer.add(fa_actor)
    odfs[:, :, :] = 1
    mask = np.ones(odfs.shape[:3])
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='jet',
                                 norm=False, global_cm=True)

    renderer.clear()
    renderer.add(odf_actor)
    renderer.add(fa_actor)
    renderer.add(actor.axes((11, 11, 11)))
    for i in range(11):
        odf_actor.display(i, None, None)
        fa_actor.display(i, None, None)
        if interactive:
            window.show(renderer)
    for j in range(11):
        odf_actor.display(None, j, None)
        fa_actor.display(None, j, None)
        if interactive:
            window.show(renderer)
    # with mask equal to zero everything should be black
    mask = np.zeros(odfs.shape[:3])
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='plasma',
                                 norm=False, global_cm=True)
    renderer.clear()
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    report = window.analyze_renderer(renderer)
    npt.assert_equal(report.actors, 1)
    npt.assert_equal(report.actors_classnames[0], 'vtkLODActor')

    del odf_actor
    odfs._mmap.close()
    del odfs
    os.close(fid)

    os.remove(fname)
Beispiel #11
0
from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()
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)
# transform our data from 1D to 4D
response_odf = response_odf[None, None, None, :]
response_actor = actor.odf_slicer(response_odf, sphere=sphere, colormap='jet')
ren.add(response_actor)
print('Saving illustration as csd_response.png')
window.record(ren, out_path='csd_response.png', size=(200, 200))
if interactive:
    window.show(ren)
"""
.. figure:: csd_response.png
   :align: center

   Estimated response function.

"""

ren.rm(response_actor)
"""
Beispiel #12
0
hcp_fod_pkl_path = r'/nfs/masi/nathv/hcp_fod_sig.pkl'

with open(hcp_sig_pkl_path, 'rb') as fin:
    dw_signal = pickle.load(fin)

with open(hcp_fod_pkl_path, 'rb') as fin2:
    fod_signal = pickle.load(fin2)

#sh_slice = dw_signal[:, :, 0, 0]
#plt.imshow(rotate(np.squeeze(dw_signal[:, :, 0, 1]), 90))
#plt.show()

dw_slice = dw_signal[44:60, 120:136, :, :]
fod_slice = fod_signal[44:60, 120:136, :, :]

dw_spheres = actor.odf_slicer(dw_signal, sphere=sph, scale=0.9, norm=True)
ren = window.Renderer()
ren.add(dw_spheres)
window.show(ren)

#slice = dw_sig_full_sphere[rand_indx, :]
#slice_re = slice.reshape([8, 8, 1, 200])
dw_spheres = actor.odf_slicer(dw_slice, sphere=sph, scale=0.9, norm=False)
ren = window.Renderer()
ren.add(dw_spheres)
window.show(ren)

fod_spheres = actor.odf_slicer(fod_slice, sphere=sph, scale=0.9, norm=False)
ren = window.Renderer()
ren.add(fod_spheres)
window.show(ren)
Beispiel #13
0
"""
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 = actor.odf_slicer(sf_odf, sphere=sphere, scale=1.3, colormap='plasma')

ren = window.Renderer()
ren.add(fodf_spheres)

print('Saving illustration as sf_odfs.png')
window.record(ren, out_path='sf_odfs.png', size=(1000, 1000))
if interactive:
    window.show(ren)

"""
We can extract the peaks from the ODF, and plot these as well
"""

sf_peaks = dpp.peaks_from_model(sf_model,
                                data_small,
Beispiel #14
0
def show_odfs_and_fa(fa, pam, mask, affine, sphere, ftmp='odf.mmap',
                     basis_type=None, norm_odfs=True, scale_odfs=0.5):
    
    renderer = window.Renderer()
    renderer.background((1, 1, 1))
    
    slice_actor = actor.slicer(fa) #, value_range)
    
    odf_shape = fa.shape + (sphere.vertices.shape[0],)
    odfs = np.memmap(ftmp, dtype=np.float32, mode='w+',
                     shape=odf_shape)
    
    sph_harm_basis = sph_harm_lookup.get(basis_type)

    if sph_harm_basis is None:
        raise ValueError("Invalid basis name.")
    B, m, n = sph_harm_basis(8, sphere.theta, sphere.phi)

    odfs[:] = np.dot(pam.shm_coeff.astype('f4'), B.T.astype('f4'))
    
    odf_slicer = actor.odf_slicer(odfs, mask=mask,
                                  sphere=sphere, scale=scale_odfs,
                                  norm=norm_odfs, colormap='magma')
        
    renderer.add(odf_slicer)
    renderer.add(slice_actor)
    
    show_m = window.ShowManager(renderer, size=(2000, 1000))
    show_m.initialize()
    
    """
    We'll start by creating the panel and adding it to the ``ShowManager``
    """
    
    label_position = ui.TextBlock2D(text='Position:')
    label_value = ui.TextBlock2D(text='Value:')
    
    result_position = ui.TextBlock2D(text='')
    result_value = ui.TextBlock2D(text='')
    line_slider_z = ui.LineSlider2D(min_value=0,
                                    max_value=shape[2] - 1,
                                    initial_value=shape[2] / 2,
                                    text_template="{value:.0f}",
                                    length=140)
    
    def change_slice_z(i_ren, obj, slider):
        z = int(np.round(slider.value))
        slice_actor.display(z=z)
        odf_slicer.display(z=z)
        show_m.render()
    
    line_slider_z.add_callback(line_slider_z.slider_disk,
                               "LeftButtonReleaseEvent",
                               change_slice_z)
    
    panel_picking = ui.Panel2D(center=(200, 120),
                               size=(250, 225),
                               color=(0, 0, 0),
                               opacity=0.75,
                               align="left")
    
    # panel_picking.add_element(label_position, 'relative', (0.1, 0.55))
    # panel_picking.add_element(label_value, 'relative', (0.1, 0.25))
    
    # panel_picking.add_element(result_position, 'relative', (0.45, 0.55))
    # panel_picking.add_element(result_value, 'relative', (0.45, 0.25))
    
    panel_picking.add_element(line_slider_z, 'relative', (0.5, 0.9))
    
    show_m.ren.add(panel_picking)
    
    def left_click_callback(obj, ev):
        """Get the value of the clicked voxel and show it in the panel."""
        event_pos = show_m.iren.GetEventPosition()
    
        obj.picker.Pick(event_pos[0],
                        event_pos[1],
                        0,
                        show_m.ren)
    
        i, j, k = obj.picker.GetPointIJK()
        print(i,j,k)
        result_position.message = '({}, {}, {})'.format(str(i), str(j), str(k))
        result_value.message = '%.3f' % fa[i, j, k]
    
    slice_actor.SetInterpolate(True)
    slice_actor.AddObserver('LeftButtonPressEvent', left_click_callback, 1.0)
        
    show_m.start()
    
    odfs._mmap.close()
    del odfs
    os.remove(ftmp)
Beispiel #15
0
"""
Compute the ODFs
"""

odf = asmfit.odf(sphere)
print('odf.shape (%d, %d, %d)' % odf.shape)
"""
Display the ODFs
"""

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()
sfu = actor.odf_slicer(odf[:, None, :],
                       sphere=sphere,
                       colormap='jet',
                       scale=0.5)
sfu.RotateX(-90)
sfu.display(y=0)
ren.add(sfu)
window.record(ren, out_path='odfs.png', size=(600, 600))
if interactive:
    window.show(ren)
"""
.. figure:: odfs.png
   :align: center

   Orientation distribution functions.

References
----------
Beispiel #16
0
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.
"""

# Enables/disables interactive visualization
interactive = False

r = window.Renderer()
sfu = actor.odf_slicer(odf, sphere=sphere, colormap='plasma', scale=0.5)
sfu.display(y=0)
sfu.RotateX(-90)
r.add(sfu)
window.record(r, out_path='odfs.png', size=(600, 600))
if interactive:
    window.show(r)

"""
.. figure:: odfs.png
   :align: center

   Orientation distribution functions (ODFs).

References
----------
Beispiel #17
0
.. figure:: tensor_ellipsoids.png
   :align: center

   Tensor Ellipsoids.
"""

window.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)

odf_actor = actor.odf_slicer(tensor_odfs, sphere=sphere, scale=0.5, colormap=None)
ren.add(odf_actor)
print('Saving illustration as tensor_odfs.png')
window.record(ren, n_frames=1, out_path='tensor_odfs.png', size=(600, 600))
if interactive:
    window.show(ren)

"""
.. 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
"""

sphere = get_sphere('symmetric724')
sphere = sphere.subdivide(2)

odf = multi_tensor_odf(sphere.vertices, mevals, angles, fractions)

from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()

odf_actor = actor.odf_slicer(odf[None, None, None, :],
                             sphere=sphere,
                             colormap='plasma')
odf_actor.RotateX(90)

ren.add(odf_actor)

print('Saving illustration as multi_tensor_simulation')
window.record(ren, out_path='multi_tensor_simulation.png', size=(300, 300))
if interactive:
    window.show(ren)
"""
.. figure:: multi_tensor_simulation.png
   :align: center

   Simulating a MultiTensor ODF.
Beispiel #19
0
from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()

csaodfs = csamodel.fit(data_small).odf(default_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])
csa_odfs_actor = actor.odf_slicer(csaodfs,
                                  sphere=default_sphere,
                                  colormap='plasma',
                                  scale=0.4)
csa_odfs_actor.display(z=0)

ren.add(csa_odfs_actor)
print('Saving illustration as csa_odfs.png')
window.record(ren, n_frames=1, out_path='csa_odfs.png', size=(600, 600))
if interactive:
    window.show(ren)
"""
.. figure:: csa_odfs.png
   :align: center

   Constant Solid Angle ODFs.

.. include:: ../links_names.inc
Beispiel #20
0
from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

r = window.Renderer()

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])
csa_odfs_actor = actor.odf_slicer(csaodfs,
                                  sphere=sphere,
                                  colormap='jet',
                                  scale=0.4)
csa_odfs_actor.display(z=0)

r.add(csa_odfs_actor)
print('Saving illustration as csa_odfs.png')
window.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600))
if interactive:
    window.show(r)
"""
.. figure:: csa_odfs.png
   :align: center

   Constant Solid Angle ODFs.

.. include:: ../links_names.inc
def dMRI2ODF_DTI(PATH):
    '''
    Input the dMRI data
    return the ODF
    '''
    dMRI_path = PATH + 'data.nii.gz'
    mask_path = PATH + 'nodif_brain_mask.nii.gz'
    dMRI_img = nib.load(dMRI_path)
    dMRI_data = dMRI_img.get_fdata()
    mask_img = nib.load(mask_path)
    mask = mask_img.get_fdata()

    ########## subsample ##########
    # dMRI_data = dMRI_data[45:-48,50:-65,51:-54,...]
    # mask = mask[45:-48,50:-65,51:-54]
    # breakpoint()
    dMRI_data = dMRI_data[:, 87, ...]
    mask = mask[:, 87, ...]

    for cnt in range(10):
        fig = plt.imshow(dMRI_data[:, :, cnt].transpose(1, 0),
                         cmap='Greys',
                         interpolation='nearest')
        plt.axis('off')
        # plt.imshow(dMRI_data[:,15,:,cnt].transpose(1,0),cmap='Greys')
        plt.savefig(str(cnt) + '.png',
                    bbox_inches='tight',
                    dpi=300,
                    transparent=True,
                    pad_inches=0)

    # breakpoint()
    bval = PATH + "bvals"
    bvec = PATH + "bvecs"

    radial_order = 6
    zeta = 700
    lambdaN = 1e-8
    lambdaL = 1e-8

    gtab = gradient_table(bvals=bval, bvecs=bvec)
    asm = ShoreModel(gtab,
                     radial_order=radial_order,
                     zeta=zeta,
                     lambdaN=lambdaN,
                     lambdaL=lambdaL)
    asmfit = asm.fit(dMRI_data, mask=mask)
    sphere = get_sphere('symmetric362')
    dMRI_odf = asmfit.odf(sphere)
    dMRI_odf[dMRI_odf <= 0] = 0

    tenmodel = dti.TensorModel(gtab)
    tenfit = tenmodel.fit(dMRI_data, mask)
    dMRI_dti = tenfit.quadratic_form

    FA = fractional_anisotropy(tenfit.evals)
    FA[np.isnan(FA)] = 0
    FA = np.clip(FA, 0, 1)
    RGB = color_fa(FA, tenfit.evecs)

    evals = tenfit.evals + 1e-20
    evecs = tenfit.evecs
    cfa = RGB + 1e-20
    cfa /= cfa.max()

    evals = np.expand_dims(evals, 2)
    evecs = np.expand_dims(evecs, 2)
    cfa = np.expand_dims(cfa, 2)

    ren = window.Scene()
    sphere = get_sphere('symmetric362')
    ren.add(
        actor.tensor_slicer(evals,
                            evecs,
                            scalar_colors=cfa,
                            sphere=sphere,
                            scale=0.5))
    window.record(ren,
                  n_frames=1,
                  out_path='../data/tensor.png',
                  size=(5000, 5000))

    odf_ = dMRI_odf

    ren = window.Scene()
    sfu = actor.odf_slicer(np.expand_dims(odf_, 2),
                           sphere=sphere,
                           colormap="plasma",
                           scale=0.5)

    ren.add(sfu)
    window.record(ren,
                  n_frames=1,
                  out_path='../data/odfs.png',
                  size=(5000, 5000))

    return None
    asmfit = asm.fit(one_vox)

    sphere = get_sphere('symmetric724')

    odf = asmfit.odf(sphere)
    odf = np.reshape(odf, [10, 1, 1, 724])

    odf_stack[i, :, :, :] = odf[0, :, :, :]
    print('odf.shape (%d, %d, %d, %d)' % odf.shape)
    zeta = zeta + 200

# Enables/disables interactive visualization
interactive = True
ren = window.Renderer()
sfu = actor.odf_slicer(odf_stack[0:5, None, 0],
                       sphere=sphere,
                       colormap='plasma',
                       scale=4,
                       norm=False,
                       radial_scale=True)
sfu.RotateX(-1)
sfu.RotateY(90)
sfu.display(z=0)
ren.add(sfu)
out_path_name = 'odfs_b6k' + str(zeta) + '.png'
window.record(ren, out_path=out_path_name, size=(200, 20))

#scale_val = scale_val + 0.5
if interactive:
    window.show(ren)
Beispiel #23
0
Load an odf reconstruction sphere
"""

sphere = get_sphere('symmetric724')
"""
Compute the fODFs.
"""

odf = f_fit.odf(sphere)
print('fODF.shape (%d, %d, %d, %d)' % odf.shape)
"""
Display a part of the fODFs
"""

odf_actor = actor.odf_slicer(odf[16:36, :, 30:45],
                             sphere=sphere,
                             colormap='plasma',
                             scale=0.6)
odf_actor.display(y=0)
odf_actor.RotateX(-90)
ren = window.Renderer()
ren.add(odf_actor)
window.record(ren, out_path='fODFs.png', size=(600, 600), magnification=4)
"""
.. figure:: fODFs.png
   :align: center

   **Fiber Orientation Distribution Functions, in a small ROI of the brain**.

.. [Anderson2005] Anderson A. W., "Measurement of Fiber Orientation Distributions
       Using High Angular Resolution Diffusion Imaging", Magnetic
       Resonance in Medicine, 2005.
Beispiel #24
0
"""
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 = actor.odf_slicer(sf_odf,
                                sphere=sphere,
                                scale=1.3,
                                colormap='jet')

ren = window.Renderer()
ren.add(fodf_spheres)

print('Saving illustration as sf_odfs.png')
window.record(ren, out_path='sf_odfs.png', size=(1000, 1000))
if interactive:
    window.show(ren)
"""
We can extract the peaks from the ODF, and plot these as well
"""

sf_peaks = dpp.peaks_from_model(sf_model,
                                data_small,
Beispiel #25
0
from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()
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)
# transform our data from 1D to 4D
response_odf = response_odf[None, None, None, :]
response_actor = actor.odf_slicer(response_odf, sphere=sphere, colormap='plasma')
ren.add(response_actor)
print('Saving illustration as csd_response.png')
window.record(ren, out_path='csd_response.png', size=(200, 200))
if interactive:
    window.show(ren)

"""
.. figure:: csd_response.png
   :align: center

   Estimated response function.

"""

ren.rm(response_actor)
Beispiel #26
0
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 window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()

odf_actor = actor.odf_slicer(odf[None, None, None, :], sphere=sphere, colormap='plasma')
odf_actor.RotateX(90)

ren.add(odf_actor)

print('Saving illustration as multi_tensor_simulation')
window.record(ren, out_path='multi_tensor_simulation.png', size=(300, 300))
if interactive:
    window.show(ren)


"""
.. figure:: multi_tensor_simulation.png
   :align: center

   Simulating a MultiTensor ODF.
Beispiel #27
0
data_masked, mask = median_otsu(data, 2, 1, vol_idx=np.arange(1, 11), dilate=1)
print('Finished masking')

print('Started DTI processing ...')
tenmodel = TensorModel(gtab)
tenfit = tenmodel.fit(data, mask=mask)
print('Finished DTI processing ...')

shape = mask.shape

odf = tenfit.odf(sphere)
ren = window.Renderer()
#odf_slicer
odf_slicer_actor = actor.odf_slicer(odfs=odf,
                                    mask=mask,
                                    sphere=sphere,
                                    scale=.5)
ren.add(odf_slicer_actor)
slider(odf_slicer_actor, None)

data_small = data[:, :, 38:39]
dti_wls = dti.TensorModel(gtab)
fit_wls = dti_wls.fit(data_small)

fa1 = fit_wls.fa
evals1 = fit_wls.evals
evecs1 = fit_wls.evecs
cfa1 = dti.color_fa(fa1, evecs1)
ren = fvtk.ren()
fvtk.add(ren, fvtk.tensor(evals1, evecs1, cfa1, sphere))
#fvtk.record(ren, n_frames=1, out_path='tensor_ellipsoids.png',
Beispiel #28
0
"""

sphere = get_sphere('symmetric724')

"""
Compute the fODFs.
"""

odf = f_fit.odf(sphere)
print('fODF.shape (%d, %d, %d, %d)' % odf.shape)

"""
Display a part of the fODFs
"""

odf_actor = actor.odf_slicer(odf[16:36, :, 30:45], sphere=sphere,
                             colormap='plasma', scale=0.6)
odf_actor.display(y=0)
odf_actor.RotateX(-90)
ren = window.Renderer()
ren.add(odf_actor)
window.record(ren, out_path='fODFs.png', size=(600, 600), magnification=4)

"""
.. figure:: fODFs.png
   :align: center

   **Fiber Orientation Distribution Functions, in a small ROI of the brain**.

References
----------
Beispiel #29
0
def show_odfs_and_fa(fa,
                     pam,
                     mask,
                     affine,
                     sphere,
                     ftmp='odf.mmap',
                     basis_type=None,
                     norm_odfs=True,
                     scale_odfs=0.5):

    renderer = window.Renderer()
    renderer.background((1, 1, 1))

    slice_actor = actor.slicer(fa)  #, value_range)

    odf_shape = fa.shape + (sphere.vertices.shape[0], )
    odfs = np.memmap(ftmp, dtype=np.float32, mode='w+', shape=odf_shape)

    sph_harm_basis = sph_harm_lookup.get(basis_type)

    if sph_harm_basis is None:
        raise ValueError("Invalid basis name.")
    B, m, n = sph_harm_basis(8, sphere.theta, sphere.phi)

    odfs[:] = np.dot(pam.shm_coeff.astype('f4'), B.T.astype('f4'))

    odf_slicer = actor.odf_slicer(odfs,
                                  mask=mask,
                                  sphere=sphere,
                                  scale=scale_odfs,
                                  norm=norm_odfs,
                                  colormap='magma')

    renderer.add(odf_slicer)
    renderer.add(slice_actor)

    show_m = window.ShowManager(renderer, size=(2000, 1000))
    show_m.initialize()
    """
    We'll start by creating the panel and adding it to the ``ShowManager``
    """

    label_position = ui.TextBlock2D(text='Position:')
    label_value = ui.TextBlock2D(text='Value:')

    result_position = ui.TextBlock2D(text='')
    result_value = ui.TextBlock2D(text='')
    line_slider_z = ui.LineSlider2D(min_value=0,
                                    max_value=shape[2] - 1,
                                    initial_value=shape[2] / 2,
                                    text_template="{value:.0f}",
                                    length=140)

    def change_slice_z(i_ren, obj, slider):
        z = int(np.round(slider.value))
        slice_actor.display(z=z)
        odf_slicer.display(z=z)
        show_m.render()

    line_slider_z.add_callback(line_slider_z.slider_disk,
                               "LeftButtonReleaseEvent", change_slice_z)

    panel_picking = ui.Panel2D(center=(200, 120),
                               size=(250, 225),
                               color=(0, 0, 0),
                               opacity=0.75,
                               align="left")

    # panel_picking.add_element(label_position, 'relative', (0.1, 0.55))
    # panel_picking.add_element(label_value, 'relative', (0.1, 0.25))

    # panel_picking.add_element(result_position, 'relative', (0.45, 0.55))
    # panel_picking.add_element(result_value, 'relative', (0.45, 0.25))

    panel_picking.add_element(line_slider_z, 'relative', (0.5, 0.9))

    show_m.ren.add(panel_picking)

    def left_click_callback(obj, ev):
        """Get the value of the clicked voxel and show it in the panel."""
        event_pos = show_m.iren.GetEventPosition()

        obj.picker.Pick(event_pos[0], event_pos[1], 0, show_m.ren)

        i, j, k = obj.picker.GetPointIJK()
        print(i, j, k)
        result_position.message = '({}, {}, {})'.format(str(i), str(j), str(k))
        result_value.message = '%.3f' % fa[i, j, k]

    slice_actor.SetInterpolate(True)
    slice_actor.AddObserver('LeftButtonPressEvent', left_click_callback, 1.0)

    show_m.start()

    odfs._mmap.close()
    del odfs
    os.remove(ftmp)
Beispiel #30
0
mcsd_pred = mcsd_fit.predict()
mcsd_pred = mcsd_model.predict(mcsd_fit.all_shm_coeff)
"""
From the fit obtained in the previous step, we generate the ODFs which can be
visualized as follows:
"""

mcsd_odf = mcsd_fit.odf(sphere)

print("ODF")
print(mcsd_odf.shape)
print(mcsd_odf[40, 40, 0])

fodf_spheres = actor.odf_slicer(mcsd_odf,
                                sphere=sphere,
                                scale=1,
                                norm=False,
                                colormap='plasma')

interactive = True
scene = window.Scene()
scene.add(fodf_spheres)
scene.reset_camera_tight()

print('Saving illustration as msdodf.png')
#window.record(scene, out_path='msdodf.png', size=(600, 600))

if interactive:
    window.show(scene)
"""
.. figure:: msdodf.png
Beispiel #31
0
from dipy.sims.voxel import multi_tensor_odf

mevals = np.array([[0.0015, 0.00015, 0.00015], [0.0015, 0.00015, 0.00015]])
angles = [(0, 0), (60, 0)]
odf = multi_tensor_odf(sph.vertices, mevals, angles, [50, 50])

from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

scene = window.Scene()
scene.SetBackground(1, 1, 1)

odf_actor = actor.odf_slicer(odf[None, None, None, :], sphere=sph)
odf_actor.RotateX(90)
scene.add(odf_actor)

print('Saving illustration as symm_signal.png')
window.record(scene, out_path='symm_signal.png', size=(300, 300))
if interactive:
    window.show(scene)
"""
.. figure:: symm_signal.png
   :align: center

   Illustration of the simulated signal sampled on a sphere of 64 points
   per hemisphere

We can now express this signal as a series of SH coefficients using
Beispiel #32
0
from dipy.viz import window, actor
from dipy.reconst.shm import sf_to_sh, sh_to_sf
scene = window.Scene()

# 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)

spike_sf_conv = sh_to_sf(spike_shm_conv, default_sphere, sh_order=8)
model_kernel = actor.odf_slicer(spike_sf_conv * 6,
                                sphere=default_sphere,
                                norm=False,
                                scale=0.4)
model_kernel.display(x=3)
scene.add(model_kernel)
scene.set_camera(position=(30, 0, 0), focal_point=(0, 0, 0), view_up=(0, 0, 1))
window.record(scene, out_path='kernel.png', size=(900, 900))
if interactive:
    window.show(scene)
"""
.. figure:: kernel.png
   :align: center

   Visualization of the contour enhancement kernel.
"""
"""
Shift-twist convolution is applied on the noisy data
Beispiel #33
0
def test_odf_slicer(interactive=False):

    sphere = get_sphere('symmetric362')

    shape = (11, 11, 11, sphere.vertices.shape[0])

    fid, fname = mkstemp(suffix='_odf_slicer.mmap')
    print(fid)
    print(fname)

    odfs = np.memmap(fname, dtype=np.float64, mode='w+',
                     shape=shape)

    odfs[:] = 1

    affine = np.eye(4)
    renderer = window.Renderer()

    mask = np.ones(odfs.shape[:3])
    mask[:4, :4, :4] = 0

    odfs[..., 0] = 1

    odf_actor = actor.odf_slicer(odfs, affine,
                                 mask=mask, sphere=sphere, scale=.25,
                                 colormap='jet')
    fa = 0. * np.zeros(odfs.shape[:3])
    fa[:, 0, :] = 1.
    fa[:, -1, :] = 1.
    fa[0, :, :] = 1.
    fa[-1, :, :] = 1.
    fa[5, 5, 5] = 1

    k = 5
    I, J, K = odfs.shape[:3]

    fa_actor = actor.slicer(fa, affine)
    fa_actor.display_extent(0, I, 0, J, k, k)
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()

    odf_actor.display_extent(0, I, 0, J, k, k)
    odf_actor.GetProperty().SetOpacity(1.0)
    if interactive:
        window.show(renderer, reset_camera=False)

    arr = window.snapshot(renderer)
    report = window.analyze_snapshot(arr, find_objects=True)
    npt.assert_equal(report.objects, 11 * 11)

    renderer.clear()
    renderer.add(fa_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    mask[:] = 0
    mask[5, 5, 5] = 1
    fa[5, 5, 5] = 0
    fa_actor = actor.slicer(fa, None)
    fa_actor.display(None, None, 5)
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='jet',
                                 norm=False, global_cm=True)
    renderer.clear()
    renderer.add(fa_actor)
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    renderer.clear()
    renderer.add(odf_actor)
    renderer.add(fa_actor)
    odfs[:, :, :] = 1
    mask = np.ones(odfs.shape[:3])
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='jet',
                                 norm=False, global_cm=True)

    renderer.clear()
    renderer.add(odf_actor)
    renderer.add(fa_actor)
    renderer.add(actor.axes((11, 11, 11)))
    for i in range(11):
        odf_actor.display(i, None, None)
        fa_actor.display(i, None, None)
        if interactive:
            window.show(renderer)
    for j in range(11):
        odf_actor.display(None, j, None)
        fa_actor.display(None, j, None)
        if interactive:
            window.show(renderer)
    # with mask equal to zero everything should be black
    mask = np.zeros(odfs.shape[:3])
    odf_actor = actor.odf_slicer(odfs, None, mask=mask,
                                 sphere=sphere, scale=.25,
                                 colormap='plasma',
                                 norm=False, global_cm=True)
    renderer.clear()
    renderer.add(odf_actor)
    renderer.reset_camera()
    renderer.reset_clipping_range()
    if interactive:
        window.show(renderer)

    report = window.analyze_renderer(renderer)
    npt.assert_equal(report.actors, 1)
    npt.assert_equal(report.actors_classnames[0], 'vtkLODActor')

    del odf_actor
    odfs._mmap.close()
    del odfs
    os.close(fid)

    os.remove(fname)
Beispiel #34
0
"""
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 = actor.odf_slicer(sf_odf,
                                sphere=sphere,
                                scale=0.8,
                                colormap='plasma')

ren = window.Renderer()
ren.add(fodf_spheres)

print('Saving illustration as sf_odfs.png')
window.record(ren, out_path='sf_odfs.png', size=(1000, 1000))
if interactive:
    window.show(ren)
"""
We can extract the peaks from the ODF, and plot these as well
"""

sf_peaks = dpp.peaks_from_model(sf_model,
                                data_small,
Beispiel #35
0
.. figure:: tensor_ellipsoids.png
   :align: center

   Tensor Ellipsoids.
"""

window.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)

odf_actor = actor.odf_slicer(tensor_odfs, sphere=sphere, scale=0.5, colormap=None)
ren.add(odf_actor)
print('Saving illustration as tensor_odfs.png')
window.record(ren, n_frames=1, out_path='tensor_odfs.png', size=(600, 600))
if interactive:
    window.show(ren)

"""
.. 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
"""
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 window, actor

# Enables/disables interactive visualization
interactive = False

ren = window.Renderer()

# concatenate data as 4D array
odfs = np.vstack((odf_gt, dsi_odf, dsid_odf))[:, None, None]
odf_actor = actor.odf_slicer(odfs, sphere=sphere, scale=0.5, colormap='plasma')

odf_actor.display(y=0)
odf_actor.RotateX(90)
ren.add(odf_actor)
window.record(ren, out_path='dsid.png', size=(300, 300))
if interactive:
    window.show(ren)
"""
.. 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, p. 136-149, 2010.
Beispiel #37
0
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 window, actor

# Enables/disables interactive visualization
interactive = False


ren = window.Renderer()

# concatenate data as 4D array
odfs = np.vstack((odf_gt, dsi_odf, dsid_odf))[:, None, None]
odf_actor = actor.odf_slicer(odfs, sphere=sphere, scale=0.5, colormap='plasma')

odf_actor.display(y=0)
odf_actor.RotateX(90)
ren.add(odf_actor)
window.record(ren, out_path='dsid.png', size=(300, 300))
if interactive:
    window.show(ren)

"""
.. 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,
Beispiel #38
0
from dipy.viz import window, actor
from dipy.sims.voxel import single_tensor_odf

# Enables/disables interactive visualization
interactive = False

scene = window.Scene()
evals = response[0]
evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T

response_odf = single_tensor_odf(default_sphere.vertices, evals, evecs)
# transform our data from 1D to 4D
response_odf = response_odf[None, None, None, :]
response_actor = actor.odf_slicer(response_odf,
                                  sphere=default_sphere,
                                  colormap='plasma')
scene.add(response_actor)
print('Saving illustration as csd_response.png')
window.record(scene, out_path='csd_response.png', size=(200, 200))
if interactive:
    window.show(scene)
"""
.. figure:: csd_response.png
   :align: center

   Estimated response function.

"""

scene.rm(response_actor)
Beispiel #39
0
from dipy.viz import window, actor

# Enables/disables interactive visualization
interactive = False

r = window.Renderer()

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])
csa_odfs_actor = actor.odf_slicer(csaodfs, sphere=sphere, colormap='plasma', scale=0.4)
csa_odfs_actor.display(z=0)

r.add(csa_odfs_actor)
print('Saving illustration as csa_odfs.png')
window.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600))
if interactive:
    window.show(r)

"""
.. figure:: csa_odfs.png
   :align: center

   Constant Solid Angle ODFs.

.. include:: ../links_names.inc
Beispiel #40
0
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.
"""

# Enables/disables interactive visualization
interactive = False

r = window.Renderer()
sfu = actor.odf_slicer(odf, sphere=sphere, colormap='plasma', scale=0.5)
sfu.display(y=0)
r.add(sfu)
window.record(r, out_path='odfs.png', size=(600, 600))
if interactive:
    window.show(r)

"""
.. figure:: odfs.png
   :align: center

   Orientation distribution functions (ODFs).

References
----------
Beispiel #41
0
from dipy.viz import window, actor
from dipy.data import get_sphere
from dipy.reconst.shm import sf_to_sh, sh_to_sf
ren = window.Renderer()

# 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 = actor.odf_slicer(spike_sf_conv * 6,
                                sphere=sphere,
                                norm=False,
                                scale=0.4)
model_kernel.display(x=3)
ren.add(model_kernel)
ren.set_camera(position=(30, 0, 0), focal_point=(0, 0, 0), view_up=(0, 0, 1))
window.record(ren, out_path='kernel.png', size=(900, 900))
if interactive:
    window.show(ren)

"""
.. figure:: kernel.png
   :align: center

   Visualization of the contour enhancement kernel.
"""