Skip to content

Instantly share code, notes, and snippets.

@pieper
Last active October 4, 2023 22:48
Show Gist options
  • Save pieper/e37d8756b091d97ef5ed340518f6d5f7 to your computer and use it in GitHub Desktop.
Save pieper/e37d8756b091d97ef5ed340518f6d5f7 to your computer and use it in GitHub Desktop.
RGBA volume rendering in 3D Slicer from segmentation
import numpy
dataDir = "/opt/data/SlicerMorph/20231003-ColorizedVR"
segName = "Segmentation"
ctFullName = "deep_snail_2_14.9um_2k__rec1100"
ctName = "deep_snail_2_14"
try:
slicer.util.getNode(segName)
except slicer.util.MRMLNodeNotFoundException:
slicer.util.loadVolume(f"{dataDir}/{ctFullName}.nrrd")
slicer.util.loadSegmentation(f"{dataDir}/{segName}.seg.nrrd")
ctNode = slicer.util.getNode(ctName)
segNode = slicer.util.getNode(segName)
ijkToRAS = vtk.vtkMatrix4x4()
ctNode.GetIJKToRASMatrix(ijkToRAS)
ctArray = slicer.util.arrayFromVolume(ctNode)
rgbaArray = numpy.zeros(shape=ctArray.shape + (4,), dtype='uint8')
rgbaArray[:,:,:,3] = 255 * ( (ctArray + ctArray.min()) / (ctArray.max() - ctArray.min()) )
for segmentID in segNode.GetSegmentation().GetSegmentIDs():
segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segNode, segmentID, ctNode)
segmentColor = segNode.GetDisplayNode().GetSegmentColor(segmentID)
rgbaArray[..., :3][segmentArray==1] = 255 * numpy.array(segmentColor)
# Bug: VTK uses the red channel to calculate gradient, but it should use alpha.
# - here we put the CT data into the alpha channel as a workaround
rgbaArray[:,:,:,0] = 255 * ( (ctArray + ctArray.min()) / (ctArray.max() - ctArray.min()) )
vectorNode = slicer.util.addVolumeFromArray(rgbaArray, ijkToRAS=ijkToRAS, name="rgba", nodeClassName="vtkMRMLVectorVolumeNode")
volumeRenderingLogic = slicer.modules.volumerendering.logic()
volumeRenderingDisplayNode = volumeRenderingLogic.CreateDefaultVolumeRenderingNodes(vectorNode)
volumeRenderingDisplayNode.SetVisibility(True)
# Enable direct RGBA color mapping
volumeRenderingDisplayNode.GetVolumePropertyNode().GetVolumeProperty().SetIndependentComponents(False)
volumeRenderingDisplayNode.GetVolumePropertyNode().GetVolumeProperty().SetShade(True)
shaderPropertyNode = slicer.vtkMRMLShaderPropertyNode()
shaderPropertyNode.SetName("VectorVolumeShaderProperty")
slicer.mrmlScene.AddNode(shaderPropertyNode)
volumeRenderingDisplayNode.SetAndObserveShaderPropertyNodeID(shaderPropertyNode.GetID())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment