iblviewer.volume

Functions

blend_maps

Blend color maps

Classes

LUTModel

This class might look slightly convoluted but it's actually simple.

SlicerModel

SlicerView

Volume

Overwriting of vedo.Volume constructor that is ill-designed as it transposes the given numpy array without us knowing about it, not giving us the option to choose about that.

VolumeController

Wrapper class that handles both the volume and its slices

VolumeModel

class VolumeModel(name: str = <factory>, file_path: str = None, scalars: iblviewer.collection.Collection = <factory>, axes: List = <factory>, data_min: float = None, data_max: float = None, data_map_step: float = 1.0, data: numpy.ndarray = None, data_type: str = 'raw', resolution: int = 1, units: float = 1e-06, base_color_map: Any = None, mapping_name: str = None, lateralized: bool = False, mapping: Any = None, luts: iblviewer.collection.Collection = <factory>, slicers: iblviewer.collection.Collection = <factory>, isosurfaces: iblviewer.collection.Collection = <factory>, interactive_subsampling: bool = True, volume_visible: bool = True, slices_visible: bool = True, transpose_shape: Any = None, dimensions: numpy.ndarray = array([0., 0., 0.]), center: numpy.ndarray = array([0., 0., 0.]))[source]

Bases: object

RAW = 'raw'
SEGMENTED = 'segmented'
NORMALIZED_SUFFIX = '_norm'
DATA_TYPE = {'raw': 0, 'segmented': 1}
PREFIX = 'Volume'
unique_name()[source]
name: str
file_path: str = None
scalars: iblviewer.collection.Collection
axes: List
data_min: float = None
data_max: float = None
data_map_step: float = 1.0
data: numpy.ndarray = None
data_type: str = 'raw'
resolution: int = 1
units: float = 1e-06
base_color_map: Any = None
mapping_name: str = None
lateralized: bool = False
mapping: Any = None
luts: iblviewer.collection.Collection
slicers: iblviewer.collection.Collection
isosurfaces: iblviewer.collection.Collection
interactive_subsampling: bool = True
volume_visible: bool = True
slices_visible: bool = True
transpose_shape: Any = None
dimensions: numpy.ndarray = array([0., 0., 0.])
center: numpy.ndarray = array([0., 0., 0.])
compute_size()[source]

Compute volume size

compute_range(force=False)[source]

Compute min and max range in the volume :return: Min and max values

guess_volume_type()[source]

Infer the volume type when it was not specified by the user. We assume here that typical values between -1 and 1 are raw volumes.

is_segmented(auto_guess=True)[source]

Get whether current volume/image is segmented :return: Boolean

read_volume(file_path)[source]

Read local volume. Downloads the file first if it’s remote.

Parameters

file_path – Volume path

Returns

3D array

load_volume(file_path, remap_scalars=False, mapping=None, make_current=True)[source]

Load a volume data file. Supports NRRD and many other formats thanks to vedo/VTK

Parameters
  • file_path – Volume file path. Could support other file types easily.

  • remap_scalars – Whether scalar values in the volume are replaced by their row id from a mapping that stores. This is necessary in the case of segmented volumes with regions that have a discontinuous id.

  • mapping – Pandas Series or a Dictionary

  • make_current – Set the volume data as the current one

Returns

3D array

transpose(shape=None)[source]

Transpose the volume for visualization in VTK

Parameters

shape – The new shape. If None, will default to self.transpose_shape

remap_slow(data, mapping=None, write_path=None)[source]

Reassign volume values (slow on large volumes!) so that they’re continuous

Parameters
  • data – Volume ndarray

  • write_path – Where the modified volume will be stored (to spare going through this method next time)

  • mapping – Pandas Series or a Dictionary that maps raw volume scalars to new ones

Returns

Modified volume data

build_lut(scalar_map=None, scalar_range=None, color_map=None, alpha_map=None, zero_is_transparent=True, noise_amount=0.0, nan_rgba=None, make_active=True)[source]

Build a look-up table (LUT, sometimes known as transfer function) for the volume

Parameters
  • scalar_map – A 2D list with values in first column from the volume itself and values from the second column being your scalar values that correspond to such region

  • scalar_range – Min and max values in a list

  • color_map – Color map name to apply

  • alpha_map – Alpha map, either None or a list of values the same length as scalar_map, that says how transparent a scalar value should be

  • zero_is_transparent – Whether zero values are made transparent, True by default

  • noise_amount – Whether a noise value is applied on the colors

  • nan_rgba – Color and transparency (RGBA) to assign to invalid (out of range or None) scalar values

  • make_active – Whether this one is made active (you still have to update the views after that)

Returns

LUTModel

blend_maps(map1, map2, time, total_time)[source]

Blend color maps

class Volume(inputobj=None, c='RdBu_r', alpha=(0.0, 0.0, 0.2, 0.4, 0.8, 1.0), alphaGradient=None, alphaUnit=1, mode=0, shade=False, spacing=None, dims=None, origin=None, mapper='smart')[source]

Bases: vedo.volume.Volume

Overwriting of vedo.Volume constructor that is ill-designed as it transposes the given numpy array without us knowing about it, not giving us the option to choose about that.

class LUTModel(name: str = <class 'NotImplementedError'>, color_map_function: Optional[Any] = None, scalar_map: Optional[numpy.ndarray] = None, scalar_min: float = 0.0, scalar_max: float = 1.0, scalar_lut: Optional[vtkmodules.vtkCommonCore.vtkLookupTable] = None, mapped_lut: Optional[vtkmodules.vtkCommonCore.vtkLookupTable] = None, color_map: Optional[numpy.ndarray] = None, alpha_map: Optional[numpy.ndarray] = None, base_color_map: Optional[numpy.ndarray] = None)[source]

Bases: object

This class might look slightly convoluted but it’s actually simple.

We use double mapping here in order to enable live/interactive visualization of volumetric data. Instead of replacing values in a 3D volume, we only replace the colors in the 1D LUT list.

The point is that it’s too slow to update a given data, like a segmented volume with custom values. Instead, we map such custom values to a 1D array (our LUT) that maps colors to raw volume values.

This is much faster in terms of rendering and it enables interactive visualization. The scalar_lut is the original LUT for the given scalars (custom values) and the mapped_lut is the LUT assigned to the surfaces (like slices) that have copied data from the volume. The volume is given color_map and alpha_map through vedo methods.

You might say “ok for double mapping, it’s the only way for interactive rendering of a volume, but what about color_map and mapped_lut? Aren’t they the same?”. The answer is: they’re the same but VTK does not accept a vtkLookupTable for a volume. Instead, it wants a vtkColorTransferFunction and a vtkPiecewiseFunction for alpha. There’s no way around it. The color_map will be computed as a vtkColorTransferFunction and the alpha_map as the vtkPiecewiseFunction.

name

alias of NotImplementedError

color_map_function: Any = None
scalar_map: numpy.ndarray = None
scalar_min: float = 0.0
scalar_max: float = 1.0
scalar_lut: vtkmodules.vtkCommonCore.vtkLookupTable = None
mapped_lut: vtkmodules.vtkCommonCore.vtkLookupTable = None
color_map: numpy.ndarray = None
alpha_map: numpy.ndarray = None
base_color_map: numpy.ndarray = None
build(scalar_map=None, scalar_range=None, color_map=None, alpha_map=None, zero_is_transparent=True, noise_amount=0.0, nan_rgba=None)[source]

Build several look-up tables (LUT, sometimes known as transfer function) for the volume. This is where double-mapping occurs for segmented volumes that have values from 0 to n where each value defines a sub-volume or region. If we want to assign values (say from another model) to these regions, we’d have to change the volume values and it would be too slow iterating over each voxel in 3D. Instead we define colors that represent these values and assign them to segmented regions in a 1D list.

Parameters
  • scalar_map – A 2D list with values in first column from the volume itself and values from the second column being your scalar values that correspond to such region

  • scalar_range – Min and max values in a list

  • color_map – Color map name to apply

  • alpha_map – Alpha map, either None or a list of values the same length as scalar_map, that says how transparent a scalar value should be

  • zero_is_transparent – Whether zero values are made transparent, True by default

  • noise_amount – Whether a noise value is applied on the colors

  • nan_rgba – Color and alpha values to assign to invalid (out of range or None) scalar values

Returns

LUTModel

get_sorted_scalars()[source]

Get a numpy 2D array of key-value pairs sorted by value :return: 2D array

class VolumeController(plot, model, initialize=True, clipping=True, slicer_box=True, center_on_edges=False, alpha_unit_upper_offset=0.0, add_to_scene=True)[source]

Bases: object

Wrapper class that handles both the volume and its slices

Get all 3D actors related to this view (for registering it in the application) :return: List of VTK objects

initialize(clipping=True, slicer_box=True, center_on_edges=False, add_to_scene=True)[source]

Set the volume actor for visualization in VTK

Parameters
  • clipping – Whether clipping is enabled

  • slicer_box – Whether the slicer box mode is enabled (6 clipping planes)

  • center_on_edges – Whether the volume’s center is aligned to its edges rather than the voxel center

  • add_to_scene – Whether the object is added to the scene

set_volume_visibility(on=True)[source]

Set volume visibility

Parameters

on – Visibility boolean

set_slices_visibility(on=True)[source]

Set the visibility of slices

Parameters

on – Visibility boolean

get_slices_opacity()[source]

Get the opacity of slices (should be the same value for all slices) A mean calculation is performed on all slices alpha, just in case :return: Alpha value

set_slices_opacity(value)[source]

Set the opacity of slices

Parameters

value – Alpha value

get_opacity()[source]

Get the relative opacity unit :return: Float

get_relative_opacity_unit()[source]

Get the alpha unit relative value :return: Float

set_opacity(value)[source]

Set the opacity of the volume like in set_opacity_unit()

Parameters

value – Opacity value between 0.0 and 1.0

Returns

Resulting alpha unit

set_opacity_unit(value)[source]

Set the opacity of the volume by modifying its alpha unit (a VTK thing). The alpha unit defines how much a voxel is transparent to incoming ray. This method normalizes the range between 0.0 and 1.0 as it depends on the resolution of the volume

Parameters

value – Opacity value between 0.0 and 1.0

Returns

Resulting alpha unit

get_spacing()[source]

Get the spacing/resolution of the volume

build_actor(center_on_edges=False, add_to_scene=True)[source]

Set the volume actor for visualization in VTK

Parameters
  • center_on_edges – Whether alignment by one voxel is applied

  • add_to_scene – Whether the object is added to the scene

set_position(position)[source]

Set the position of the volume

mirror_volume(axes)[source]

Mirror the volume on given axes

Parameters

mirror_axes – A list of axes (either 0, 1, 2 or ‘x’, ‘y’, ‘z’) on which the volume will be mirrored. Optional

initialize_picker(opacity_iso_value=0.0001)[source]

Initialize the volume picker

Parameters

opacity_iso_value – Threshold that defines at what accumulated opacity the picker hits the volume. In the case of a segmented volume, you want to keep this value very low as the default one.

initialize_slicer_box()[source]

Initialize 6 slicing planes as a box.

update_slicer(slicer_id, value=None, normal=None)[source]

Update a given slicer with the given value

Parameters
  • slicer_id – SlicerView id

  • value – Value or 3D point

  • normal – Normal

initialize_clipping_planes()[source]

Initialize X, Y and Z clipping planes with two planes per axis for positive and negative slicing

get_clipping_planes(except_axis=None)[source]

Get the current clipping planes except the ones on the given axis

Parameters

except_axis – Axis id to ignore. If None, all clipping planes will be returned

Returns

vtkPlaneCollection

reset_clipping_planes()[source]

Reset clipping planes

clip_on_axis(position=None, axis=None, normal=None)[source]

Apply clipping on a single axis

Parameters
  • position – Position

  • axis – Clipping axis, defaults to 0 (X axis)

  • thickness – Whether a thickness (so two clipping planes) are applied

set_volume_clipping(on=None)[source]

Set volume clipping on or off.

Parameters

on – Whether clipping is enabled or disabled. If None, then

the state is toggled.

clip_to_bounds(bounds)[source]

Clip the volume and move the slicing planes according to 6 boundary points

Parameters

bounds – Six values in a list (xmin, xmax, ymin, ymax, zmin, zmax)

box_widget_update(widget=None, event=None)[source]

Clip the volume with the current box widget

Parameters
  • widget – vtkBoxCutter

  • event – vtkEvent

set_clipping_planes(planes, flip_normals=False)[source]

Clip the volume and move the slicing planes according the given planes

Parameters

planes – vtkPlanes

set_alpha_map(alpha_map, alpha_factor=None)[source]

Set alpha map to the volume view

Parameters
  • alpha_map – 2D list of scalar values and alpha values

  • alpha_factor – Alpha factor

set_color_map(color_map=None, alpha_map=None)[source]

Set the color and alpha map to the view objects

Parameters
  • color_map – Nested list of scalar values and rgb colors like [[0, [0.0, 0.0, 0.0]], [8, [0.5, 0.8, 0.3]], …]

  • alpha_map – 2D list of scalar values and alpha values

disable_shading()[source]

Disable volume shading

enable_shading(ambient=0.6, diffuse=0.8, specular=0.9)[source]

Enable volume shading TODO: See if this method is useful

toggle_slices_visibility()[source]

Toggle slices visibility

toggle_hollow()[source]

Toggle hollow mode for volume rendering. This is intended to work only on segmented (annotated) volumes.

get_value_from_xyz(position, normal_step=None, avoid_values=0, cast_to_int=True, none_as_zero=False)[source]

Get a scalar value from the volume with respect to XYZ coordinates and a optionally a normal step, that is the normal on which to probe multiplied by the distance you want to travel further into the volume to pick a correct value. Often the “surface point” on a volume with non uniform transparency is at the boundary between transparent (let’s say a 0 value is transparent) and more opaque parts. So you need to go further into the “cloud” so to speak, in order to find the values you want.

Parameters
  • position – 3D array

  • normal_step – A vector normal multiplied by the lookup distance, in case the raw position yields bad or unwanted results

  • avoid_values – Try and find other values than this

  • cast_to_int – Whether the value should be cast to integer

Returns

Scalar value

raycast(origin, screen_position)[source]

Shorthand for pick() method

pick(origin, screen_position)[source]

Find the nearest intersection – even on sliced volume – with the ray formed by an origin and a screen-space position (given by VTK when you click on an actor)

Parameters
  • origin – Origin of the vector

  • screen_position – 2D position on screen. This is given by vtk events like MouseRelease

Returns

The nearest position and its related value queried in the volume image

add_probe(origin, destination, resolution=40, radius=10, color_map=None, screen_space=True, min_v=None, max_v=None, add_to_scene=True)[source]

Add a series of points along a line probe

Parameters
  • origin – Probe origin

  • destination – Probe destination point

  • resolution – Number of (equidistant) points that will be probed along that line

  • radius – Radius of the points

  • color_map – Scalars color map

  • screen_space – Whether the points are screen space or spheres

  • min_v – Min scalar value

  • max_v – Max scalar value

  • add_to_scene – Whether the new probe is added to scene

Returns

Points

update_probe(origin, destination, points_obj)[source]

Update a probe with given start and end points

Parameters
  • origin – Start point

  • destination – End point

  • points_obj – Points object

probe(origin, destination, resolution=40)[source]

Probe a volume with a line

Parameters
  • origin – Origin of the line probe

  • destination – Destination of the line probe

  • resolution – Number of point samples along the probe

Returns

Positions and values

set_interactive_subsampling(on=False)[source]

Set volume subsampling on or off. This is enabled by default in VTK and we disable it by default in IBLViewer

Parameters

on – Whether volume subsampling in interactive mode is on or off

isosurface(label, exceptions=[0], force_rebuild=False, set_current=True, to_int=True, split_meshes=True)[source]

Creates a surface mesh (isosurface) of a segmented/labelled volume for the given value. Unlike general isosurfacing, this method extracts only the surface mesh of the desired region/label/segmentation, not of all values from 0 to label.

Parameters
  • label – Label (scalar) value found in the volume

  • exceptions – If the label is found in the exceptions list, isosurfacing will not occur

  • force_rebuild – Whether rebuilding is forced in case we find an existing mesh for the given label

  • set_current – Whether the label is set as the current one in the model

  • to_int – Whether the label is cast to integer

  • split_meshes – Whether we split meshes when multiple ones are found

Returns

A list of all manifold meshes for the given label

class SlicerModel(name: str = <factory>, axis: int = None, value: float = 0.0, bounds: numpy.ndarray = None, origin: numpy.ndarray = array([0., 0., 0.]), normal: numpy.ndarray = array([1., 0., 0.]), clipping_planes: vtkmodules.vtkCommonDataModel.vtkPlaneCollection = None)[source]

Bases: object

PREFIX = '[Slicer]_'
MIN_SLAB_THICKNESS = 1.0
unique_name()[source]
name: str
axis: int = None
value: float = 0.0
bounds: numpy.ndarray = None
origin: numpy.ndarray = array([0., 0., 0.])
normal: numpy.ndarray = array([1., 0., 0.])
clipping_planes: vtkmodules.vtkCommonDataModel.vtkPlaneCollection = None
get_box_plane_id()[source]

Get the plane id :return: Int

get_axis_aligned_info(vtk_axis)[source]

VTK stores box clipping planes in the order: -X to +X: 0, 1 -Y to +Y: 2, 3 -Z to +Z: 4, 5 This method retrieves what is the XYZ axis (0, 1 or 2) and its orientation sign :return: Int axis and float orientation

align_to_axis(axis, dimensions=None)[source]

Set the axis of the slicer

Parameters
  • axis – See parameter vtk_axis in SlicerModel.get_axis_aligned_info()

  • dimensions – Dimensions of the volume

flip_normal()[source]

Flip the normal of the slicer

check_normal()[source]

Check if the normal is axis-aligned. If not, the axis is set to None.

update(value=None, normal=None, axis=None)[source]

Update slicer

Parameters
  • value – Origin of the slicing plane

  • normal – Normal of the slicing plane

  • axis – Axis, if the plane is axis-aligned

Returns

True if model changed, False if it didn’t

class SlicerView(plot, volume_view, slicer_model, standalone=True)[source]

Bases: object

slices = {}
initialize(render=False)[source]

Initialize the slicer object

initialize_mapper()[source]

Initialize the object mapper

set_color_map(color_map, alpha_map=None)[source]

Set a color map to the slice

Parameters

color_map – Color map, can be a string, a list of colors or more. See vedo documentation.

set_slice_type(slice_type)[source]

Set the slice type. 0 for axial, 1 for free slicing

Parameters

slice_type – Int value

slice_on_normal(origin, normal)[source]

Slice a volume with a plane oriented by the given normal. This allows slicing in all directions.

Parameters
  • origin – Origin of the slicing plane

  • normal – Normal of the slicing plane

Returns

Mesh object with the slice as an image texture

x_slice(i)[source]

Extract the slice at index i of volume along x-axis.

Parameters

i – I index

y_slice(j)[source]

Extract the slice at index j of volume along y-axis.

Parameters

j – J index

z_slice(k)[source]

Extract the slice at index k of volume along z-axis.

Parameters

k – K index

slice_on_axis(value=None, normal=None, axis=None, use_reslice=False)[source]

Slice on standard X, Y or Z axis

Parameters
  • value – Value on the given axis

  • normal – Axis normal, can be either +1.0 or -1.0 along that axis

  • axis – Axis integer, 0 for X, 1 for Y, 2 for Z

  • use_reslice – if True, this enables vtkImageReslice which is useful when the normal is not aligned to either X, Y or Z. If you use it on an axis-aligned normal, some color inaccuracies will appear if you don’t tweak the vtkImageResliceMapper. This is why the default is False.

Returns

Result boolean, whether slice occured or not

update()[source]

Update slice object according to data in the model

apply_lut(lut=None)[source]

Apply a LUT to the volume

Parameters
  • lut – vtkLookupTable

  • actor – The actor to receive this