A labelmap imported to a segmentation using ImportLabelmapToSegmentationNode is transformed incorrectly if there are multiple parent transforms soft-applied. I have been using ImportLabelmapToSegmentationNode successfully for a long time with a transformed labelmap with no problem, but I just ran a case where there were multiple parent transforms (i.e. the parent transform had a parent transform applied) and the converted segmentation node put the segments in the wrong place. With a little testing, it appears that each transform is at least partially applied, but the total transformation is incorrect.
I reproduced this effect with SampleData and saved the scene, it is available here: https://drive.google.com/file/d/1fXu8EHHY4jzL3COEn8sjXXz1FmgdGdiq/view?usp=sharing
In that scene, I created a segmentation with 3 segments and exported that to a labelmap (these align perfectly). Then I created two transforms which each apply a rotation around the AP axis and a SI translation. Then I soft-applied the first transform to the labelmap and the original segmentation, and then soft-applied the second transform to the first transform. Lastly, I ran ImportLabelmapToSegmentationNode on the transformed labelmap, creating the segmentation node labeled SegmentationFromLabelMap in the scene. With both the SegmentationFromLabelMap and LabelMapFromSegmentation shown, you can see that they do not align the way they should. It looks like an equal amount of rotation has been applied, but not an equal total translation. So, it’s not the case that only the first parent transform has been applied, because then the rotation amounts would not be equal. If I combine the two transforms into one (clone the first, apply the second, and harden) and use that, then the output segmentation is aligned with the transformed labelmap (correct behavior). Is it possible that the parent transforms are being applied in the wrong order?
Using Slicer 5.10.0 on Windows 11. The conversion was carried out using the following convenience wrapper around ImportLabelmapToSegmentationNode
def labelMapToSeg(labelmapNode, createClosedSurfaces=True):
"""Converts an input labelmap node to a segmentation node"""
segNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode(
labelmapNode, segNode
)
if createClosedSurfaces:
segNode.CreateClosedSurfaceRepresentation()
return segNode
To recreate:
# Load scene linked above, then run
labelNode = getNode('LabelMapFromSegmentation')
segNode = labelMapToSeg(labelNode)
segNode.SetName('NewSegmentationFromLabelMap')
