Segmentation Concepts

Summary

 

Segmentation is a process whereby voxels in the dataset are assigned to one of a range of different transfer functions. The segmentation state is represented by a data structure called the label volume. The label volume consists of a structure containing one byte per voxel. Each byte in the label volume stores the identifier of the transfer function that is used to render that voxel. The various segmentation techniques supported by the F.A.S.T. Cloud SDK apply segmentation by setting values in the label volume.

 

By using segmentation, various structural components of a dataset may be rendered using different transfer function settings. This may be done to highlight a structural feature, such as a specific tissue or material type, or to hide such structures to improve the visibility of other dataset components. Refer to the Transfer Functions section for more information on configuring transfer functions.

 

Segmentation makes use of the octree data structure, and is therefore only available in adaptive rendering modes. These include Transfer Function, Maximum Intensity Projection (MIP), Faded MIP, and Minimum Intensity Projection (MinIP). Segmentation is not available in any of the brute force modes, including the brute force versions of the MIP, Faded MIP, and MinIP render modes.

 

Activating segmentation will consume an amount of memory equivalent to 50% of the dataset size, because each voxel in the dataset must be allocated a 1-byte value in order to designate the transfer function that will render the voxel. It is possible to segment a dataset into 256 different regions, however in practice fewer than 8 are typically required.

 

The F.A.S.T. Cloud SDK supports two built-in segmentation methods. The first method is Region Selection, in which a polygonal region is designated that includes all voxels to be segmented to the active label volume. The second segmentation method is Region Growth. This segmentation method automatically segments a material or tissue type based on parameters set in the Region Growth SDK methods. Real-time interactive segmentaion may be performed with the methods described in the Interactive Segmentation section.

Segmentation
A dataset with segmentation applied.

Enabling Segmentation

 

Segmentation is enabled and applied using a VolumeSegmentationContext object. An IVolumeSegmentationContext object is created using the ServerContext.createVolumeSegmentationContext() method. This method takes an an input parameter the address of an OctreeContext object that has been previously associated with the VolumeDataContext object of interest.

 

Once segmentation has been enabled target label volume must be set. This is the label volume that voxels will be associated with when segmentation is actually applied to the dataset. The active label volume is set with the VolumeSegmentationContext.setSegLabelIndex() method. This method takes as an input parameter an integer in the range of 0 to 7. These associate with transfer functions 0 - 7. Note that calling VolumeSegmentationContext.setSegLabelIndex() does not actually apply a segmentation, it only sets the label volume to be associated with the segmented voxels once segmentation is later applied.

 

After segmentation has been enabled and an active transfer function is set using IVolumeSegmentationContext::SetSegLabelIndex(), actual segmentation operations may then be applied. Segmentation can be applied using techniques discussed in the Region Selection, Region Growth, and Interactive Segmentation sections.

 

The VolumeSegmentationContext class supports two different segmentation types, additive and subtractive. Additive segmentation causes voxels in the segmented region to be applied to the label volume designated with the VolumeSegmentationContext.setSegLabelIndex() method. Subtractive segmentation causes voxels in the segmented region to be applied to label volume 0. Subtractive segmentation can be used to un-segment previous segmented data. The segmentation type is set with the VolumeSegmentationContext.setSegType() method. This method takes as an input parameter a member of the SegmentationType enumeration.

 

If a Region Growth or Interactive Segmentation operation is to be applied, the user can control what label volumes the segmentation algorithm is allowed to consider as the segmented region expands. Previously segmented regions can be designated as 'off limits' to the growth operation. This feature is controlled with the VolumeSegmentationContext.setSegLabelMask() method. This method takes four 64 bit integers as input parameters. Each integer acts as a bitmask for a given label volume. If a given bit is set to 1, that label volume will be considered during the segmentation growth operation. If a given bit is 0, that label volume will not be considered. In versions of the F.A.S.T. Cloud SDK supporting 8 transfer functions, only the first 8 bits of the first parameter will be considered. The remaining bits are only applicable to versions of the F.A.S.T. Cloud SDK supporting 256 transfer functions.

 

Saving and Restoring Segmentation States

 

The segmentation state stored in an IVolumeSegmentationContext object can be saved to disk as a GIPL file. This file can then be loaded and applied at a later time to restore a saved segmentation state. To save a GIPL file, use the VolumeSegmentationContext.saveSegStateAsGIPL() method. This method takes a file path and name to save the GIPL file to. Note that GIPL files are only saved by, and relative to the F.A.S.T. Cloud SDK server's working directory. To load a GIPL file use the VolumeSegmentationContext.loadSegStateFromGIPL() method.

 

 

Undoing Segmentation Operations

 

The F.A.S.T. Cloud SDK supports an undo feature on the segmentation operations discussed in the Region Selection, Region Growth, and Interactive Segmentation sections. The undo feature allows one to save the segmentation state in a buffer capable of storing 10 segmentation states. These saved segmentation states can then be restored from the buffer. To save the current segmentation state call the VolumeSegmentationContext.saveForUndo() method. This method takes two parameters. The first is an input parameter designating which label volume to save to the undo buffer. The second parameter is the address of an integer which stores the number of previously saved undo states available in the buffer. When this value reaches 10, additional calls to VolumeSegmentationContext.saveForUndo() will push out the oldest saved state to make room for the newest. To restore a saved segmentation state from the undo buffer, call the VolumeSegmentationContext.undoLast() method. This method will restore the segmentation state most recently saved to the undo buffer, and then delete it from the buffer, increasing the count of available buffer slots by one. IVolumeSegmentationContext.undoLast() method takes as an output parameter the address of a variable that will be assigned the number of remaining saved undo states. When this value reaches 0, no more undo operations can be performed until new states are saved with the VolumeSegmentationContext.saveForUndo() method.

 

Segmentation Modifiers

 

The IVolumeSegmentationContext class supports a number of utility methods for manipulating the label volume state. These are described in the table below.

 

clearLabels()

Clears one or more label volumes according to the input bitmask. Voxels in cleared label volumes become part of label volume 0.

combineLabels()

Takes two label volumes and merges them together.

copyLabel()

Copies one label volume to another.

swapLabels()

Swaps the contents of two label volumes.

dilateOneObject()

Expands a segmented region by adding layers to the exterior surface.

erodeOneObject()

Contracts a segmented region by removing layers from the exterior surface.

colorizeTF()

Take a 3D Transfer Function and make it all a solid color (useful for visualizing the results of segmentation)

makeColorLabeledTFsfromWindowLevel()

Fill in the upper TF's with colorized version of the W/L transfer function.

makeColorLabelsFromMainTF()

Fill in the upper TF's with colorized version of the main (0) transfer function

makeTFfromWindowLevel()

To display segmentation on 2D Thin display we utilize a fully opaque TF with a Parallel render instead of MPR render Type. This function will create that TF. for unsegmented data use (0,0,0) to (255,255,255) to get a TF which looks a a W/L display on a normal MPR 2D display. It is suggested for the segmented labels to use (r/2,g/2,b/2) to (r,g,b) for a given color for that label because then you will still see the different shades of the 2D image below the color.

 

Region Growth

The F.A.S.T. Cloud SDK supports segmentation using region growing algorithms. This technique supports several different methods for automatically segmenting volume material based on voxel segmentation criteria. This can be used to highlight or hide a structural feature, such as a specific tissue or material type, to improve the visibility of specific dataset components. In general, the region growth techniques work by first selecting an individual 'seed' voxel in the dataset, and then recursively sampling each of the voxel's 27 neighbor voxels to test if they meet the segmentation criteria. The segmentation growth region propagates outward from the seed voxel until adjacent voxels no longer meet the segmentation criteria.

 

The region growth technique supports four separate algorithms for generating a segmented region. The first is Min/Max, in which voxels are analyzed by comparing their individual values to an input min/max range of dataset values. The remaining algorithms, Min/Max Gradient, Min/Max Gradient Expand, and Min/Max Bone use gradient analysis of dataset values to determine the tissue type to select.

 

For more information about preparing a dataset for segmentation, and setting an active transfer function, see Enabling Segmentation. A seed point within the dataset can be selected for region growth segmentation, either programmatically using SDK methods, or with mouse selection.

 

RegionGrowth

Liver and gall bladder segmented with region growth

 

Segmentation by region growth is implemented using the VolumeSegmentationContext.segment() method. This method automatically segments the volume based on criteria set in the input SegmentationParameters structure. Some other VolumeSegmentationContext methods can affect how the VolumeSegmentationContext::Segment() method operates. These are discussed in the Enabling Segmentation section.

 

The IVolumeSegmentationContext::Segment() method takes a input SegmentationParameters structure that contains all the parameters upon which the segmentation operation will be based. The method returns in its callback function the size of the segmented region in voxels and cubic millimeters.

 

 

The SegementationParameters member fields are described in the table below.

 

connectivityMax

The maximum voxel value to grow into. Only voxels with values less than or equal this will be considered.

connectivityMin

The minimum voxel value to grow into. Only voxels with values greater than or equal this will be considered.

connectivityOrigin

The seed coordinate from which the segmented region will grow. This coordinate can be entered manually, or determined from a call to the shootRay() method.

connectivityRadius

Maximum distance from the seed point that the segmentation will grow.

customKernelParamArray

If a custom kernel is used, this will contain data that can be set by caller for the custom kernel to use.

gradientNeighborhoodSize

Size of subcube used to calculate average gradient over. For example, if this is 3, then a 3x3x3 subcube centered around the current voxel will be considered.

gradientThreshold

Unitless parameter controlling strength of gradient that the growing will cross over. Valid values are -1 to +1. A smaller value will include less, a greater value will include more.

postCloseSize

This parameter can be used to close holes in the segmented volume by applying successive dilate and erode passes. For example, if this is set to 5, then the segmented region will be dilated 5 times, then eroded 5 times. Some smoothing of the segmentation volume surface will result.

postDilateCount

Number of layers to dilate after the segmentation operation completes. This is applied before any erode operations.

postErodeCount

Number of layers to erode after the segmentation operation completes. This is applied after any dilate operations.

postOpenSize

This parameter can be used to remove small objects at the segmentation boundary by applying successive erode and dilate passes. For example, if this is set to 5, then the segmented region will be eroded 5 times, then dilated 5 times. Some smoothing of the segmentation volume surface will result.

segAlgoKernel

A value from the SegmentationAlgorithm enumeration that determines the segmentation kernel to apply.

stepSize

The number of voxels to jump in each direction for each step. Values of 1 and above may be used. Poor segmentation may result if large values are used.

 

Segmentation Kernels

 

The F.A.S.T. Cloud SDK supports a number of different segmentation kernels, or algorithms, for performing segmentation operations. The segmentation kernels are defined by the SegmentationAlgorithm enumeration. These segmentation kernels are set in the SEGMENTATION_PARAMS.SegAlgoKernel field. The supported kernels are described in the table below.

 

minMax

The simplest Kernel algorithm, voxels are included if they are connected to the origin within the radius and the voxel value is between the min and max

minMaxGradient

This Kernel algorithm will also evaluate a local subcube of gradients to determine if the growing should continue.

minMaxGradientExpand

As the subcube size gets larger the above algorithm tends to under-estimate the object, this algorithm expands near the edges.

minMaxBone

This Kernel algorithm looks for tiny partial volume spaces between dense bones and so tries to separate almost-touching bones.

custom

This will run a user-defined custom kernel. See the Custom Segmentation Kernel section for more information.


Interactive Segmentation

 

The F.A.S.T. Cloud SDK supports a real-time segmentation method called Interactive Segmentation. This technique allows one to manipulate the segmentation state interactively in real-time. Users may change multiple segmentation parameters in quick succession and view the changes on-screen as they happen. The Interactive Segmentation functions can be connected to a user interface device, such as a mouse, allowing the user to manipulate one or more segmentation parameters simultaneously in an intuitive fashion. Visually manipulating segmentation state in this manner can provide for much easier and faster segmentation of complex regions and material types than hand tuning numbers in a user interface dialog. 

 

InteractiveSegmentation
Segmentation of the airway using Interactive Segmentation

 

Before Interactive Segmentation can be used it must first be enabled. This is done with the VolumeSegmentationContext.enableInteractiveSeg() method. This method is used to designate which render engines will be used to visualize the segmentation state as it is altered by the Interactive Segmentation methods. The VolumeSegmentationContext.enableInteractiveSeg() method takes an array of pointers to RenderEngineContext objects. These engines will be updated as the segmentation state changes during the Interactive Segmentation cycle.

 

After the Interactive Segmentation algorithm is enabled, an Interactive Segmentation cycle is begun with a call to VolumeSegmentationContext.interactiveSegInit(). This method takes a SegmentationParameters structure containing the segmentation parameters to be applied. The method returns in its callback function the size of the segmented region in voxels and cubic millimeters.

 

When using Interactive Segmentation, label volume 7 cannot be used as a segmentation target as it is used as a workspace buffer by the Interactive Segmentation algorithm.

 

Once an Interactive Segmentation cycle has been started with the VolumeSegmentationContext.interactiveSegInit() method, the label volume may be continuously re-segmented in real time with successive calls to theVolumeSegmentationContext.interactiveSegReSegment() method. This method takes the same input parameter as the VolumeSegmentationContext.interactiveSegInit() method. The VolumeSegmentationContext.interactiveSegReSegment() method may be called successively as many times as desired, with the values in the input SegmentationParameters structure being changed each time by a user interface device or component.

 

When an Interactive Segmentation cycle is complete, it is ended with a call to the VolumeSegmentationContext.interactiveSegEnd() method. The segmentation state is then permanently applied to the label volume. If the user is not satisfied with the segmentation state applied during an Interactive Segmentation cycle, the segmentation state may be restored to the state it was in before the initial call to VolumeSegmentationContext.interactiveSegInit() with a call to VolumeSegmentationContext.interactiveSegCancel(). This method will abort and undo the changes applied during the Interactive Segmentation cycle.

 

Region Selection (Freehand Cut)

 

One of the segmentation techniques supported by the F.A.S.T. Cloud SDK is region selection. This technique involves outlining a 2D polygonal overlay region on a rendered image of the dataset. This 2D overlay is then projected into 3D space through the volume, as rendered from the perspective of an RenderEngineContext object passed to the region selection SDK method. The non-transparent voxels inside the selected region are then segmented to the active transfer function.

 

For more information on preparing a dataset for segmentation and setting an active transfer function, see Enabling Segmentation. An area of the dataset can be selected for region selection segmentation programmatically using SDK methods.


At least one image must be rendered before Region Selection can be applied.


FHC_Pre
Region selected with Freehand Cut
FHC_Post
Selected region after segmentation

Segmentation by region selection is implemented by the VolumeSegmentationContext.freeHandCut() method. This method takes six input parameters. The first is a a RenderEngineContext object that will be used to render the 2D image upon which the region selection points will be projected. The second parameter is an array of Point structures defining the points that make up the polygonal selection region. The third parameter is a value from the FreeHandCutMode enumeration that controls which voxels within the outlined selection region will be captured by the segmentation operation. wholeVolume will cause all non-transparent (visible) voxels within a 3 dimensional projection of the outlined selection region into the volume to be segmented. surfaceOnly will segment only voxels in the top layer of the perceived volume surface. firstLayer is similar to wholeVolume will, but the segmentation will penetrate only until it first reaches a non-visible voxel. Therefore, visible voxels behind the transparent region will not be segmented as they would be when using wholeVolume will mode. completeVolume will segment all voxels, visible or not. The fourth parameter is the index of the label volume to segment the voxels into. The final two parameters are the width and height of the image upon which the region selection points will be projected. All voxels inside the outlined region are then segmented according to the region selection mode.

FreehandCutEx3