Hi! I have a VTK file (UnstructuredGrid) that I want to convert to a DICOM to share with my colleagues in medicine. I am familiar with VTKs but it is my first time doing anything with DICOM, so I would appreciate any help!
The VTK is of a 3D geometry and has a point data field (let’s call it P) that I want to project/show in the DICOM image.
I can import the VTK to Slicer as a Model and color it through “Scalars” by selecting the field P (see the top part of attached screenshot), but when I want to segment and turn it into a volume to later export as DICOM, I lose the coloring, and only the domain itself is colored by a single color (see lower part of screenshot)… I want to have the same coloring on the “slices” so I can have that as the DICOM…
Can anyone help me with this? Thank you very much!
I’m not aware of a really fitting format for this in DICOM. What I could imagine is to convert this “colored” mesh into a volume and export it as a conventional CT (or other image) modality. There is no module in Slicer to probe model into volume (only the other way around), but this function does this:
def probeMeshIntoVolume(self, inputMeshModel, currentMeshArrayName, inputVolume, outputVolume):
"""
Probe values of a certain array at voxels of a reference volume and copy the probed values to an output volume.
"""
# Get RAS to IJK transform of the input volume
ras2IjkMatrix = vtk.vtkMatrix4x4()
inputVolume.GetRASToIJKMatrix(ras2IjkMatrix)
ras2IjkTransform = vtk.vtkTransform()
ras2IjkTransform.SetMatrix(ras2IjkMatrix)
# Apply the transformation to the grid
transformFilter = vtk.vtkTransformFilter()
transformFilter.SetInputData(inputMeshModel.GetUnstructuredGrid())
transformFilter.SetTransform(ras2IjkTransform)
transformFilter.Update()
# Probe mesh with volume
probeFilter = vtk.vtkProbeFilter()
probeFilter.SetInputData(inputVolume.GetImageData())
probeFilter.SetSourceData(transformFilter.GetOutputDataObject(0)) # The mesh grid transformed to IJK
probeFilter.SetPassPointArrays(True) # Keep image points as scalars
probeFilter.Update()
# Create output volume from comparison
outputVolume.SetRASToIJKMatrix(ras2IjkMatrix)
outputVolume.SetName(f'Probed {inputMeshModel.GetName()} ({currentMeshArrayName}) with {inputVolume.GetName()}')
outputShape = tuple(reversed(probeFilter.GetOutput().GetDimensions()))
probeArray = vtk.util.numpy_support.vtk_to_numpy(probeFilter.GetOutput().GetPointData().GetArray(currentMeshArrayName))
outputArray = probeArray.reshape(outputShape)
slicer.util.updateVolumeFromArray(outputVolume, outputArray)
The only thing you need but don’t have is a reference volume. You can decide what resolution you need and either create a volume from scratch or load a sample volume and use it (after setting a different spacing if you want).