Hello! I’m trying to alter an existing python script which converts segmentations from an RT Struct dataset to binary labelmaps for export as stls. I’ve found that when I do this manually through the GUI, I get the best result when I use “Advanced Create” in Segmentations, choose the Planar Contour > Closed Surface > Binary Labelmap path, and click “Specify geometry” (it doesn’t matter whether I select the source geometry or not - as long as the spacing is set to 1mm on all axes).
I am trying to replicate this in my script but have had no luck primarily because I have no idea what I’m doing. The current script does this, but it gives me a large stl with a rough surface:
seg = getNode('*RTSTRUCT*')
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
slicer.mrmlScene.AddNode(segmentEditorNode)
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(seg)
# export segmentation to a model
shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
exportFolderItemId = shNode.CreateFolderItem(shNode.GetSceneItemID(), "Segments")
log_info("Export all segments to models")
slicer.modules.segmentations.logic().ExportAllSegmentsToModels(seg, exportFolderItemId)
Would anyone be able to point me in the direction of what I might do to modify this to use the conversion path/parameters as described above? I’ve spent a long time going through documentation but I’m not quite sure what I’m looking for. I tried using this:
If you want to skip the direct Planar contour → Closed surface conversion path so that the Planar contour → Ribbon model → Binary labelmap path is used, you can do this:
Thank you! The main issue is that I can’t find a way to specify the reference image geometry when creating the binary label map. I have noticed that when I click “specify geometry”, I don’t need to choose a segment, as long as it populates the reference image geometry with generic values like this:
then the conversion works as expected. I haven’t been able to find a way to replicate this with my python script however. I tried making a dummy volume node, adding spacing values to this and setting reference geometry of the segment I’m trying to convert, but it still doesn’t work. Do you have any suggestions for this?
Thank you so much, I really appreciate the help! I tried using that but am still getting output that is different to what happens when clicking specify geometry on the UI:
This is what I used:
extent = [0,1,0,1,0,1]
matrix = vtk.vtkMatrix4x4()
referenceGeometryMatrix = matrix.Identity()
geometryString = slicer.vtkSegmentationConverter.SerializeImageGeometry(referenceGeometryMatrix, extent)
segmentationNode = getNode(‘RTSTRUCT’)
segmentationNode.GetSegmentation().SetConversionParameter(slicer.vtkSegmentationConverter.GetReferenceImageGeometryParameterName(), geometryString)
segmentationNode.CreateBinaryLabelmapRepresentation()
the console output was:
[VTK] CalculateOutputGeometry: No image geometry specified, default geometry is calculated (0.366345130101627;0;0;-83.49600219726562;0;0.366345130101627;0;355.9289855957031;0;0;0.366345130101627;-47.14999771118164;0;0;0;1;0;299;0;215;0;241;)
[VTK] CalculateOutputGeometry: No image geometry specified, default geometry is calculated (0.8751702253519644;0;0;-128.906005859375;0;0.8751702253519644;0;200.16799926757812;0;0;0.8751702253519644;-114.75;0;0;0;1;0;232;0;253;0;265;)
The resulting representation was still very stepped (it is smooth when specifying geometry with the button on the ui). Do you have any suggestions?
The problem is that you don’t actually set a geometry.
After the call
referenceGeometryMatrix = matrix.Identity()
referenceGeometryMatrix is None. I strongly suggest that you try to run these lines in the Python console and see the output. It is very easy but super important to see the content of the variables, and unfortunately the Identity() function has no return value.