Volume Rendering & Processing

The Wolfram Language provides built-in support for volume rendering and processing of 3D datasets. Many built-in image processing algorithms, including pixel operations, local filtering, segmentation, and morphological operations, can be applied to 3D datasets.

Volume Creation and Representation

A 3D dataset can be imported from a file or series of files. Typically slices are stored as a stack of 2D images and can then be combined to create a 3D image. A 3D image can also be created from three- or four-dimensional data arrays, where by default the first three dimensions correspond to slices, rows, and columns of the 3D image.

Volume creation functions.

Create a volume from a data array:

Image3D[{(({{0, 8, 16}, {24, 32, 40}, {48, 56, 64}})),(({{72, 80, 88}, {96, 104, 112}, {120, 128, 136}})),(({{144, 152, 160}, {168, 176, 184}, {192, 200, 208}}))},"Byte",ColorFunction->GrayLevel]

Create a multichannel (RefLink[Image3D, paclet:ref/Image3D]) from a 4D array of data:

Image3D[{{{{1,0,0},{0,0,1}},{{1,1,0},{(1/2),1,1}}},{{{(1/2),(1/2),(1/2)},{0,1,1}},{{0,(1/2),1},{1,0,1}}}}]

Create a volume from a stack of 2D images:

Image3D[{,,,,}]

Import a stack of images stored in a TIFF file as an (RefLink[Image3D, paclet:ref/Image3D]):

engine=Import["ExampleData/CTengine.tiff","Image3D"]

Displaying 2D slices of a 3D volume is a convenient way to reveal the inside of a volume. (RefLink[Image3DSlices, paclet:ref/Image3DSlices]) extracts 2D slices of a volume along the specified dimension.

Slice a 3D dataset.

Extract three slices from a volume:

Image3DSlices[engine,{70,75,80},"XY"]

Properties of a 3D image can be obtained by calling the following functions.

Volume properties.

Extract properties of a volume:

ImageDimensions[engine]

ImageColorSpace[engine]

ImageType[engine]

ImageMeasurements[engine,"MeanIntensity"]

Volume Rendering

Important rendering options.

ColorFunction (Transfer Function)

In volume rendering, transfer functions translate voxel values into corresponding opacity and color values. In Wolfram Wolfram Language, a transfer function can be specified using the (RefLink[ColorFunction, paclet:ref/ColorFunction]) option.

Import a 3D dataset:

data=ExampleData[{"TestImage3D","CTengine"},"Data"];

Wolfram Language's default color function for single-channel volumes:

Image3D[data,"Byte"]

A gray color function with linear opacity is a commonly used color function:

Image3D[data,"Byte",ColorFunction->(GrayLevel[#,#]&)]

Use a predefined x-ray color function specification:

Image3D[data,"Byte",ColorFunction->"XRay"]

Use a rainbow color function with linear opacity:

Image3D[data,"Byte",ColorFunction->(Append[ColorData["Rainbow"][#],#]&)]

ClipRange

In order to see inside a volume, typically a portion of the volume is clipped away. The (RefLink[ClipRange, paclet:ref/ClipRange]) option can be used to specify the rectangle to be cut away from the view.

knee=;

Cut away a rectangle from the view:

Image3D[knee,ClipRange->{{50,128},All,{100,128}}]

Clip along the z dimension:

Manipulate[Image3D[,ClipRange->{All,All,{z,128}}],{{z,128},0,128}]

Background

By default, no background color is assumed when rendering a 3D volume, and thus the notebook background is used.

A black background is commonly used in volume rendering:

Image3D[knee,ColorFunction->"XRay",Background->Black]

BoxRatios

By default, each voxel in assumed to be a perfect cube. Therefore, the box ratios of the rendered volume are proportional to the ratios of its dimension.

head=ExampleData[{"TestImage3D","CThead"}]

If the data does not exhibit cubic voxels, the ratios of the box embedding the volume can be specified using the (RefLink[BoxRatios, paclet:ref/BoxRatios]) option.

Specify the box ratios:

Image3D[head,BoxRatios->1]

Volume Coordinate System

Data Embedding

When constructing a volume from an array of data, by default the first three dimensions correspond to slices, rows, and columns of the 3D image, respectively. Slices are enumerated from top to bottom, rows from back to front, and columns from left to right.

A way to remember this is to think about placing a book in the 3D space. Pages of the book correspond to image slices (going from top to bottom) and data corresponding to each page (image slice) is arranged so that rows run from back to front and read from left to right.

Create a list of color values from the temperature map:

colors=Table[List@@ColorData["BrightBands"][i/54],{i,0,26}];
Image[{colors},ImageSize->{Automatic,10}]

Reshape the created list into a three-cube structure and create an (RefLink[Image3D, paclet:ref/Image3D]) object:

data=ArrayReshape[colors,{3,3,3,3}];

cube=Image3D[data]

The (RefLink[Graphics3D, paclet:ref/Graphics3D]) primitive (RefLink[Raster3D, paclet:ref/Raster3D]) displays the slices from bottom to top, and the rows of each slice are displayed from front to back:

Graphics3D[Raster3D[data]]

Index Coordinates

For 3D images, similarly to 2D images, there is more than one coordinate system in use. The coordinate system used for embedding data arrays in 3D space is the same as the Wolfram Language's part specification.

The Wolfram Language commands that operate on both images and data arrays adhere to the index coordinate system. In 3D, these commands first list parameters that refer to the vertical slice coordinate going from top to bottom, then list the back-to-front row coordinate and then the left-to-right column coordinate.

Max filtering of a 3D image along the third dimension:

MaxFilter[,{0,0,3}]

Image Coordinates

The second coordinate system is not intrinsic to the data, but attached to the embedding space. The continuous image coordinate system, like the (RefLink[Graphics3D, paclet:ref/Graphics3D]) coordinate system, has its origin in the bottom-left front corner of an image with an x coordinate extending from left to right, a y coordinate running from front to back, and a z coordinate running from bottom to top. The image domain covers the 3D-interval [0,width]×[0,depth]×[0,height].

Image processing commands that are not applicable to arbitrary arrays render their results in standard image coordinates. These standard image coordinates can readily be used in (RefLink[Graphics3D, paclet:ref/Graphics3D]) primitives.

Compute the intensity centroid of a volume:

engine=;
ic=ImageMeasurements[engine,"IntensityCentroid"]

Superimpose the computed position on the volume:

Show[engine,Graphics3D[{Red,PointSize[.05],Point[ic]}]]