iblviewer.volume
Functions
Blend color maps |
Classes
This class might look slightly convoluted but it's actually simple. |
|
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. |
|
Wrapper class that handles both the volume and its slices |
|
- 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'
- 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
- 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_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
- 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
- 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_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_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
- 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
- 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.
- 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
- 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
- enable_shading(ambient=0.6, diffuse=0.8, specular=0.9)[source]
Enable volume shading TODO: See if this method is useful
- 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
- 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
- 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_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
- class SlicerView(plot, volume_view, slicer_model, standalone=True)[source]
Bases:
object
- slices = {}
- 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
- 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