Volume rendering


Before starting this lesson, you should be familiar with:

Learning Objectives

After completing this lesson, learners should be able to:
  • Understand the concepts and some methodes of 3-D rendering.

  • Appreciate that 3-D rendering can be challenging for some data.

  • Perform basic volume rendering using a software tool.


Intuitively grasping 3-D shapes requires visualisation of the whole object. This is not possible when just looking at one or several slices of a 3-D data set. Thus is it important about different volume rendering techniques that can create a 3-D appearance of the whole image. This is especially useful for sparse data, where individual 2-D slices only contain a small subset of the relevant information.

Concept map

graph TD D("3-D image data") --> R("Volume rendering") R --> A("2-D image with 3-D appearance") R -->|VR| AA("Two 2-D images (one per eye)") R ---|has| M("Many methods and settings...")


Volume rendering examples.


Show activity for:  

skimage napari

# To create an animation of the volume the napari-animation plugin is needed.
# pip install napari-animation

import numpy as np
from skimage.io import imread
import napari

# Read the image
# image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyzt_8bit__starfish_chromosomes.tif')
# image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyzc_8bit__em_synapses_and_labels.tif')
image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyz_8bit_calibrated__mri_full_head.tif')
# image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyz_8bit_calibrated__organoid_nuclei.tif')
# image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyz_8bit_calibrated__fib_sem_crop.tif')
# image = imread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyz_8bit_calibrated_labels__platy_tissues.tif')

# Check image type and values
print(np.min(image), np.max(image))

# Instantiate the napari viewer
viewer = napari.Viewer()

# View the intensity image as grayscale
viewer.add_image(image, name='image', colormap='gray')
# Napari GUI: choose a colormap according to the data type

# Napari GUI: change viewer from 2D to 3D, zoom in and out and rotate the volume
# Note: these values are optimized for xyz_8bit_calibrated__mri_full_head.tif
viewer.dims.ndisplay = 3
viewer.camera.zoom = 2
viewer.camera.angles = (0, -60, 90)

# Napari GUI: use rendering (and attenuation) modes
# Parameters can be changed for reproducibility
viewer.layers['image'].rendering = 'attenuated_mip'
viewer.layers['image'].attenuation = 1.

# Take a screenshot of the scene created
from napari.utils import nbscreenshot

# Acquire the frame as numpy array and add it to the napari GUI
screenshot = viewer.screenshot()
viewer.add_image(screenshot, name='screenshot')
viewer.dims.ndisplay = 2

# Napari GUI: realize this is a 2D RGBA image and can be saved as a PNG for presentations
print(np.min(screenshot), np.max(screenshot))

# Napari GUI: use napari-animation (https://github.com/napari/napari-animation) to create an animation of the volume


True or False


  • TODO


Volume rendering software

Software Multi-Channel Time-lapse Max-Projection Volume Iso-Surface
ImageJ 3Dscript                  
ImageJ 3D viewer N N N Y Y        
ImageJ ClearVolume (Upate Site) Y Y Y N N        
ImageJ Volume Viewer N N Y Y N        

Follow-up material

Recommended follow-up modules:

Learn more: