Transform single segment in python module

Hi all,

I have a segmentation node (vtkMRMLSegmentationNode) that contains several segments (in this case, they represent organs) and I would like to apply a different linear transform (computed locally to the same reference fixed volume) to each of these segments and then combine the transformed segments in a new segmentation node.
So to achieve this, I export each single segment into a segmentation node (with GetSegment and AddSegment functions) that I transform with SetAndObserveTransformNodeID, and then export the transformed segment and add it to a final transformed segmentation node (with all the other transformed segments).
I don’t know if it is the right way to do this or if there is any easier solution, but it seems that the segments are not transformed, as if the transformation was not harden. Also, the segmentation nodes created do not seem accessible in the Slicer views, the eye icon is shaded.

Thanks for your help,

Eloïse

You can only apply transformation to an entire segmentation, so moving out each each segment to a separate segmentation node is the right way.

If you apply a linear transform to a segmentation then hardening a transform does not need resampling. Hardening can be fully represented in change of segmentation origin, spacing, and axis directions.

If you want all your transformed segments in the same grid you can move back all the segments into the same segmentation node and then export to merged labelmap.

Thanks for your answer!
The problem is that the segments are not transformed when I use SetAndObserveTransformNodeID

#create the output/merged transformed segmentation node that will contain all transformed segments
outputTransformedSegmentationNode = slicer.vtkMRMLSegmentationNode()
outputTransformedSegmentationNode.SetName('TransformedSegmentationMask')
slicer.mrmlScene.AddNode(outputTransformedSegmentationNode)

then for each given segment :

#Get organ segment from its Id
organSegment = segmentationNode.GetSegmentation().GetSegment(segmentId)
        
 #Export segment to segmentation node 
organSegmentationNode = slicer.vtkMRMLSegmentationNode()
organSegmentationNode.SetName('OrganSegmentationTransformed' + segmentId)
organSegmentationNode.GetSegmentation().AddSegment(organSegment)
slicer.mrmlScene.AddNode(organSegmentationNode)

#apply local transform
organSegmentationNode.SetAndObserveTransformNodeID(localTransformLabelmapNode.GetID())

#Extract transformed segment 
transformedSegment = organSegmentationNode.GetSegmentation().GetSegment(segmentId)
        
#And add the transformedSegment to the outputTransformedSegmentationNode
outputTransformedSegmentationNode.GetSegmentation().AddSegment(transformedSegment)

At last :

mergedTransformedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
slicer.mrmlScene.AddNode(mergedTransformedLabelmapNode)
slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(outputTransformedSegmentationNode, visibleSegmentIds, mergedTransformedLabelmapNode, inputM1LocalVolume)

But the segments in the output label map are not transformed. Is there anything I am missing or not doing correctly?

After your set the parent transform you also need to harden it.

Thanks, works great!
One last thing : I iterate through the segments of the input segmentation node and apply the strategy described above, and both the input segmentation node and the output segmentation node (both containing all segments) are transformed at last. how can I keep the input segmentation node the same (and prevent the transformation of the segments it contains) ?

Keep the original segmentation node as is (untransformed), and move back all transformed segments back to this segmentation node.

I made a deep copy of the segments before applying the transformation to their segmentation nodes, in order to put them back untransformed in the original merged segmentation node and it works.
Thanks a lot for your answers.

1 Like

Good Morning,

I found this topic very helpful. I just have one question regarding segment selector widget of my python module. The code line to add the segment to the new segmentation node (organSegmentationNode.GetSegmentation().AddSegment(organSegment)) makes the selector widget to return to the first segment of the segmentation. Thus, I need to click twice in the desired segment and unnecessary data is added to the mrml scene.

I don’t know if I’m doing something wrong so I would appreciate someone’s help.

# input segmentation node and segment selector
self.inputContourSelector = slicer.qMRMLSegmentSelectorWidget()
self.inputContourSelector.setMRMLScene(slicer.mrmlScene)
parametersFormLayout.addRow("Desired Contour: ", self.inputContourSelector)
self.inputContourSelector.connect('currentSegmentChanged(QString)', self.onContourChange)

def onContourChange(self, targetContour):
    segmentations = slicer.util.getNodesByClass('vtkMRMLSegmentationNode')
    segmentationNode = segmentations[0]
    organSegment = segmentationNode.GetSegmentation().GetSegment(targetContour)
       
    organSegmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(organSegmentationNode)
    organSegmentationNode.SetName('OrganSegmentationTransformed' + targetContour)
    organSegmentationNode.GetSegmentation().AddSegment(organSegment)

Output when I select the segmentation

image

Output when I select the desired contour (CTV1) for the first time:

image

Output when I select the desired contour (CTV1) for the second time:

image

Thanks,
Mariana

This is a bug, I’ve entered a bug report - qMRMLSegmentSelectorWidget loses current segment selection if segment is added · Issue #5287 · Slicer/Slicer · GitHub. Until it is fixed, you can store the currently selected segment ID before you add a new segment and then restore the selection after the new segment is added.

1 Like

Thank you for your response and for report the bug! I will follow your advice.

Hi Andras,

I noticed that the bug was fixed, but I am having exactly the same problem. I tried to used the setCurrentNodeID and setCurrentSegmentID of the SegmentSelectorWidget in order to maintain the segmentID after add the segment to the new segmentationNode but without success.

Any idea why this continues to happen? Thank you very much!

You need to use the latest Slicer Preview Release. I’ve tested it and it works well for me, selection in the widget is preserved when new segment is added.

1 Like

Sorry I was using the 3.11.20200930 3D Slicer version. I tried to used the latest Slicer Preview Release and it worked for me too. Thank you a lot.

1 Like

A post was merged into an existing topic: 3D Slicer for virtual reality using Oculus Quest