コード例 #1
0
ファイル: applications.py プロジェクト: sariths/vtkPlotter
def Slicer2d(volume, levels=(None, None), size=(900, 900), bg='k9', zoom=1.2):
    """
    Create a 2D window with a single slice of a Volume,
    wich can be oriented arbitrarily in space.

    :param list wl: window and color levels
    """
    vsl = vedo.volume.VolumeSlice(
        volume)  # reuse the same underlying data as in vol

    # no argument will grab the existing cmap in vol (or use buildLUT())
    vsl.colorize()

    if levels[0] and levels[1]:
        vsl.lighting(window=levels[0], level=levels[1])

    usage = Text2D(
        f"SHIFT+Left click   \rightarrow rotate camera for oblique slicing\n"
        f"SHIFT+Middle click \rightarrow slice perpendicularly through image\n"
        f"Left click & drag  \rightarrow modify luminosity and contrast\n"
        f"R                  \rightarrow Reset the Window/Color levels\n"
        f"X                  \rightarrow Reset to sagittal view\n"
        f"Y                  \rightarrow Reset to coronal view\n"
        f"Z                  \rightarrow Reset to axial view",
        font="Calco",
        pos="top-left",
        s=0.8,
        bg='yellow',
        alpha=0.25)

    custom_shape = [  # define here the 2 rendering rectangle spaces
        dict(bottomleft=(0.0, 0.0), topright=(1, 1),
             bg='k9'),  # the full window
        dict(bottomleft=(0.8, 0.8), topright=(1, 1), bg='k8', bg2='lb'),
    ]

    axes = 11
    if settings.vtk_version[0] == 9:
        axes = 0

    hist = cornerHistogram(volume.pointdata[0],
                           bins=25,
                           logscale=1,
                           pos=(0.02, 0.02),
                           s=0.175,
                           c='dg',
                           bg='k',
                           alpha=1)

    plt = vedo.show([(vsl, usage, hist), volume],
                    shape=custom_shape,
                    mode="image",
                    title=volume.filename[:80],
                    size=size,
                    bg=bg,
                    zoom=zoom,
                    axes=axes,
                    interactive=0)
    return plt
コード例 #2
0
ファイル: applications.py プロジェクト: yyeboah/vedo
def RayCaster(volume):
    """
    Generate a ``Plotter`` window for Volume rendering using ray casting.
    Returns the ``Plotter`` object.
    """
    vp = settings.plotter_instance
    if not vp:
        vp = Plotter(axes=4, bg='bb')

    volumeProperty = volume.GetProperty()
    img = volume.imagedata()

    if volume.dimensions()[2] < 3:
        print("Error in raycaster: not enough depth", volume.dimensions())
        return vp
    printc("GPU Ray-casting tool", c="b", invert=1)

    smin, smax = img.GetScalarRange()

    x0alpha = smin + (smax - smin) * 0.25
    x1alpha = smin + (smax - smin) * 0.5
    x2alpha = smin + (smax - smin) * 1.0

    ############################## color map slider
    # Create transfer mapping scalar value to color
    cmaps = [
        "jet",
        "viridis",
        "bone",
        "hot",
        "plasma",
        "winter",
        "cool",
        "gist_earth",
        "coolwarm",
        "tab10",
    ]
    cols_cmaps = []
    for cm in cmaps:
        cols = colorMap(range(0, 21), cm, 0, 20)  # sample 20 colors
        cols_cmaps.append(cols)
    Ncols = len(cmaps)
    csl = (0.9, 0.9, 0.9)
    if sum(getColor(vp.renderer.GetBackground())) > 1.5:
        csl = (0.1, 0.1, 0.1)

    def sliderColorMap(widget, event):
        sliderRep = widget.GetRepresentation()
        k = int(sliderRep.GetValue())
        sliderRep.SetTitleText(cmaps[k])
        volume.color(cmaps[k])

    w1 = vp.addSlider2D(
        sliderColorMap,
        0,
        Ncols - 1,
        value=0,
        showValue=0,
        title=cmaps[0],
        c=csl,
        pos=[(0.8, 0.05), (0.965, 0.05)],
    )
    w1.GetRepresentation().SetTitleHeight(0.018)

    ############################## alpha sliders
    # Create transfer mapping scalar value to opacity
    opacityTransferFunction = volumeProperty.GetScalarOpacity()

    def setOTF():
        opacityTransferFunction.RemoveAllPoints()
        opacityTransferFunction.AddPoint(smin, 0.0)
        opacityTransferFunction.AddPoint(smin + (smax - smin) * 0.1, 0.0)
        opacityTransferFunction.AddPoint(x0alpha, _alphaslider0)
        opacityTransferFunction.AddPoint(x1alpha, _alphaslider1)
        opacityTransferFunction.AddPoint(x2alpha, _alphaslider2)

    setOTF()

    def sliderA0(widget, event):
        global _alphaslider0
        _alphaslider0 = widget.GetRepresentation().GetValue()
        setOTF()

    vp.addSlider2D(sliderA0,
                   0,
                   1,
                   value=_alphaslider0,
                   pos=[(0.84, 0.1), (0.84, 0.26)],
                   c=csl,
                   showValue=0)

    def sliderA1(widget, event):
        global _alphaslider1
        _alphaslider1 = widget.GetRepresentation().GetValue()
        setOTF()

    vp.addSlider2D(sliderA1,
                   0,
                   1,
                   value=_alphaslider1,
                   pos=[(0.89, 0.1), (0.89, 0.26)],
                   c=csl,
                   showValue=0)

    def sliderA2(widget, event):
        global _alphaslider2
        _alphaslider2 = widget.GetRepresentation().GetValue()
        setOTF()

    w2 = vp.addSlider2D(sliderA2,
                        0,
                        1,
                        value=_alphaslider2,
                        pos=[(0.96, 0.1), (0.96, 0.26)],
                        c=csl,
                        showValue=0,
                        title="Opacity levels")
    w2.GetRepresentation().SetTitleHeight(0.016)

    # add a button
    def buttonfuncMode():
        s = volume.mode()
        snew = (s + 1) % 2
        volume.mode(snew)
        bum.switch()

    bum = vp.addButton(
        buttonfuncMode,
        pos=(0.7, 0.035),
        states=["composite", "max proj."],
        c=["bb", "gray"],
        bc=["gray", "bb"],  # colors of states
        font="",
        size=16,
        bold=0,
        italic=False,
    )
    bum.status(volume.mode())

    def CheckAbort(obj, event):
        if obj.GetEventPending() != 0:
            obj.SetAbortRender(1)

    vp.window.AddObserver("AbortCheckEvent", CheckAbort)

    # add histogram of scalar
    plot = cornerHistogram(
        volume.getPointArray(),
        bins=25,
        logscale=1,
        c=(.7, .7, .7),
        bg=(.7, .7, .7),
        pos=(0.78, 0.065),
        lines=True,
        dots=False,
    )

    # xbins = np.linspace(smin, smax, 25)
    # yvals = volume.histogram(bins=25, logscale=1)
    # plot = cornerPlot(np.c_[xbins, yvals],
    #     c=(.7,.7,.7), bg=(.7,.7,.7), pos=(0.78, 0.065), s=0.4,
    #     lines=True, dots=False,
    # )

    plot.GetPosition2Coordinate().SetValue(0.197, 0.20, 0)
    plot.GetXAxisActor2D().SetFontFactor(0.7)
    plot.GetProperty().SetOpacity(0.5)
    vp.add([plot, volume])
    return vp
コード例 #3
0
ファイル: applications.py プロジェクト: yyeboah/vedo
def Slicer(
    volume,
    alpha=1,
    cmaps=('gist_ncar_r', "hot_r", "bone_r", "jet", "Spectral_r"),
    map2cells=False,  # buggy
    clamp=True,
    useSlider3D=False,
    size=(850, 700),
    screensize="auto",
    title="",
    bg="white",
    bg2="lightblue",
    axes=7,
    showHisto=True,
    showIcon=True,
    draggable=False,
    verbose=True,
):
    """
    Generate a ``Plotter`` window with slicing planes for the input Volume.
    Returns the ``Plotter`` object.

    :param float alpha: transparency of the slicing planes
    :param list cmaps: list of color maps names to cycle when clicking button
    :param bool map2cells: scalars are mapped to cells, not intepolated.
    :param bool clamp: clamp scalar to reduce the effect of tails in color mapping
    :param bool useSlider3D: show sliders attached along the axes
    :param list size: rendering window size in pixels
    :param list screensize: size of the screen can be specified
    :param str title: window title
    :param bg: background color
    :param bg2: background gradient color
    :param int axes: axis type number
    :param bool showHisto: show histogram on bottom left
    :param bool showIcon: show a small 3D rendering icon of the volume
    :param bool draggable: make the icon draggable
    """
    global _cmap_slicer

    if verbose: printc("Slicer tool", invert=1, c="m")
    ################################
    vp = Plotter(
        bg=bg,
        bg2=bg2,
        size=size,
        screensize=screensize,
        title=title,
        interactive=False,
    )

    ################################
    box = volume.box().wireframe().alpha(0)

    vp.show(box, viewup="z", axes=axes)
    if showIcon:
        vp.addInset(volume,
                    pos=(.85, .85),
                    size=0.15,
                    c='w',
                    draggable=draggable)

    # inits
    la, ld = 0.7, 0.3  #ambient, diffuse
    dims = volume.dimensions()
    data = volume.getPointArray()
    rmin, rmax = volume.imagedata().GetScalarRange()
    if clamp:
        hdata, edg = np.histogram(data, bins=50)
        logdata = np.log(hdata + 1)
        # mean  of the logscale plot
        meanlog = np.sum(np.multiply(edg[:-1], logdata)) / np.sum(logdata)
        rmax = min(rmax, meanlog + (meanlog - rmin) * 0.9)
        rmin = max(rmin, meanlog - (rmax - meanlog) * 0.9)
        if verbose:
            printc('scalar range clamped to: (' + precision(rmin, 3) + ', ' +
                   precision(rmax, 3) + ')',
                   c='m',
                   bold=0)
    _cmap_slicer = cmaps[0]
    visibles = [None, None, None]
    msh = volume.zSlice(int(dims[2] / 2))
    msh.alpha(alpha).lighting('', la, ld, 0)
    msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax)
    if map2cells: msh.mapPointsToCells()
    vp.renderer.AddActor(msh)
    visibles[2] = msh
    addScalarBar(msh, pos=(0.04, 0.0), horizontal=True, titleFontSize=0)

    def sliderfunc_x(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.xSlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[0])
        if i and i < dims[0]: vp.renderer.AddActor(msh)
        visibles[0] = msh

    def sliderfunc_y(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.ySlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[1])
        if i and i < dims[1]: vp.renderer.AddActor(msh)
        visibles[1] = msh

    def sliderfunc_z(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.zSlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[2])
        if i and i < dims[2]: vp.renderer.AddActor(msh)
        visibles[2] = msh

    cx, cy, cz, ch = 'dr', 'dg', 'db', (0.3, 0.3, 0.3)
    if np.sum(vp.renderer.GetBackground()) < 1.5:
        cx, cy, cz = 'lr', 'lg', 'lb'
        ch = (0.8, 0.8, 0.8)

    if not useSlider3D:
        vp.addSlider2D(sliderfunc_x,
                       0,
                       dims[0],
                       title='X',
                       titleSize=0.5,
                       pos=[(0.8, 0.12), (0.95, 0.12)],
                       showValue=False,
                       c=cx)
        vp.addSlider2D(sliderfunc_y,
                       0,
                       dims[1],
                       title='Y',
                       titleSize=0.5,
                       pos=[(0.8, 0.08), (0.95, 0.08)],
                       showValue=False,
                       c=cy)
        vp.addSlider2D(sliderfunc_z,
                       0,
                       dims[2],
                       title='Z',
                       titleSize=0.6,
                       value=int(dims[2] / 2),
                       pos=[(0.8, 0.04), (0.95, 0.04)],
                       showValue=False,
                       c=cz)
    else:  # 3d sliders attached to the axes bounds
        bs = box.bounds()
        vp.addSlider3D(
            sliderfunc_x,
            pos1=(bs[0], bs[2], bs[4]),
            pos2=(bs[1], bs[2], bs[4]),
            xmin=0,
            xmax=dims[0],
            t=box.diagonalSize() / mag(box.xbounds()) * 0.6,
            c=cx,
            showValue=False,
        )
        vp.addSlider3D(
            sliderfunc_y,
            pos1=(bs[1], bs[2], bs[4]),
            pos2=(bs[1], bs[3], bs[4]),
            xmin=0,
            xmax=dims[1],
            t=box.diagonalSize() / mag(box.ybounds()) * 0.6,
            c=cy,
            showValue=False,
        )
        vp.addSlider3D(
            sliderfunc_z,
            pos1=(bs[0], bs[2], bs[4]),
            pos2=(bs[0], bs[2], bs[5]),
            xmin=0,
            xmax=dims[2],
            value=int(dims[2] / 2),
            t=box.diagonalSize() / mag(box.zbounds()) * 0.6,
            c=cz,
            showValue=False,
        )

    #################
    def buttonfunc():
        global _cmap_slicer
        bu.switch()
        _cmap_slicer = bu.status()
        for mesh in visibles:
            if mesh:
                mesh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax)
                if map2cells:
                    mesh.mapPointsToCells()
        vp.renderer.RemoveActor(mesh.scalarbar)
        mesh.scalarbar = addScalarBar(mesh,
                                      pos=(0.04, 0.0),
                                      horizontal=True,
                                      titleFontSize=0)
        vp.renderer.AddActor(mesh.scalarbar)

    bu = vp.addButton(
        buttonfunc,
        pos=(0.27, 0.005),
        states=cmaps,
        c=["db"] * len(cmaps),
        bc=["lb"] * len(cmaps),  # colors of states
        size=14,
        bold=True,
    )

    #################
    hist = None
    if showHisto:
        hist = cornerHistogram(data,
                               s=0.2,
                               bins=25,
                               logscale=1,
                               pos=(0.02, 0.02),
                               c=ch,
                               bg=ch,
                               alpha=0.7)

    comment = None
    if verbose:
        comment = Text2D(
            "Use sliders to slice volume\nClick button to change colormap",
            font='',
            s=0.8)

    vp.show(msh, hist, comment, interactive=False)
    vp.interactive = True
    if verbose:
        printc("Press button to cycle through color maps,", c="m")
        printc("Use sliders to select the slicing planes.", c="m")
    return vp
コード例 #4
0
ファイル: colorize_volume.py プロジェクト: zhDai/vedo
"""Custom color and transparency maps for Volumes"""
from vedo import load, dataurl, show
from vedo.pyplot import cornerHistogram

# Build a Volume object.
# A set of color/transparency values - of any length - can be passed
# to define the transfer function in the range of the scalar.
#  E.g.: setting alpha=[0, 0, 0, 1, 0, 0, 0] would make visible
#  only voxels with value close to center of the range (see histogram).
vol = load(dataurl+'embryo.slc') # returns a Volume
vol.color([(0,"green"), (49,"green"),
           (50,"blue"), (109,"blue"),
           (110,"red"), (180,"red"),
          ])
# vol.mode('max-projection')
vol.alpha([0., 1.])
vol.alphaUnit(8) # absorption unit, higher factors = higher transparency
vol.addScalarBar3D(title='color~\dot~alpha transfer function', c='k')

ch = cornerHistogram(vol, logscale=True, pos='bottom-left')

# show both Volume and Mesh
show(vol, ch, __doc__, axes=1, zoom=1.2)
コード例 #5
0
import numpy as np

npts = 500  # nr. of points of known scalar value
coords = np.random.rand(npts, 3)  # range is [0, 1]
scals = coords[:, 2]  # let the scalar be the z of the point itself

apts = Points(coords).addPointArray(scals, name='scals')

# Now interpolate these points to a full Volume
# Available interpolation kernels are: shepard, gaussian, voronoi, linear.
vol = interpolateToVolume(apts,
                          kernel='shepard',
                          radius=0.2,
                          dims=(90, 90, 90))

vol.c(["maroon", "g", "b"])  # set color   transfer function
vol.alpha([0.3, 0.9])  # set opacity transfer function
#vol.alpha([(0.3,0.3), (0.9,0.9)]) # alternative way, by specifying (xscalar, alpha)
vol.alphaUnit(0.5)  # make the whole object less transparent (default is 1)

# replace voxels of specific range with a new value
vol.threshold(above=0.3, below=0.4, replace=0.9)  #.printHistogram()
# Note that scalar range now has changed (you may want to reapply vol.c().alpha())

ch = cornerHistogram(vol, pos="bottom-left")

vol.addScalarBar3D(sy=1, title='Height is the voxel scalar')
vol.scalarbar.rotateX(90).pos(1.15, 1, 0.5)

show(apts, vol, ch, __doc__, axes=1, elevation=-90)