Converting SegmentationNode to Labelmap takes a long time through Python

Hello,

I am using Slicer to convert RT structs to binary label maps. I am able to do it via Python, but it takes much longer than using the Segmentations module and doing it by hand (under the representations section). For some files it takes a few minutes, and for some it hangs for hours. I have tested this both via the Jupyter Extension, as well as running a script via the command line.

The line that causes the issue is:
classvtkMRMLSegmentationNode. CreateBinaryLabelmapRepresentation()

OS: Windows 10
Slicer versions: 4.11 (Jupyter + python script) and 5.1 (python script only, Jupyter not tested)

I suspect that this issue arises because the Segmentations module is using a different function call, though I have not been able to find more details to support this.

Thanks for your help!
Edward

Please read more.about this.class :slight_smile:
https://apidocs.slicer.org/master/classvtkSegmentation.html

I thimkmit may help

Hi Mauro,

Thanks for your response. Is there a particular function that you suggest I look at? I’ve double checked that the conversion parameters are the same when running it through Python as well as using the Segmentations module.

I have also tried first converting my planar contours to closed surfaces, then to binary label maps (because it has a much lower estimated cost than planar contour → ribbon model → binary label map), but it is still taking a long time.

Thanks,
Edward

I think you should read about this

Hope it helps

1 Like

I use this code snippet and it works fine:

segmentationNode = getNode(“Segmentation”)
labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLLabelMapVolumeNode”)
slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(segmentationNode, labelmapVolumeNode, referenceVolumeNode)

https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html?highlight=snippet#export-labelmap-node-from-segmentation-node

3 Likes

Thanks for the response! Using the code you provided, I was able to narrow down my problem to a few problematic contours/segmentations. Once I get that figured out, I am confident that I will get everything working.

1 Like

After playing around with the Segmentation modules some more, I think I’ve discovered the source of my issue. Some of the contours that I exported from our radiation contour planning software are improperly converted to closed surfaces when I import their DICOM into Slicer. Therefore, the conversion of planar contour → closed surface → binary label map doesn’t work.

Using the Segmentation module, I can choose the higher cost option of converting planar contour → ribbon model → binary label map, and this appears to work. Previously when I converted the contours manually in Slicer, I must have chosen this path. So it appears that I can convert everything using the Slicer app, but I would like to do this via a script, as I have a lot patients to convert.

I tried to use the BatchStructureSetConversion.py script in the SlicerRT extension and that didn’t work either, I think because it also tries to use closed surface as an intermediate step. Looking at the code, it calls CreateBinaryLabelmapRepresentation(), which is what I did in my original script.

Looking at the Python API for vtkMRMLSegmentationNode and vtkSegmentation, there does not appear to be a way to use a ribbon model as an intermediary. My next step is try and create a C++ extension that can make use of the relevant Conversion Rules in SlicerRT - but before I get to deep in this, I wonder if anyone has any alternate suggestions.

All features are available via the Python interface, so you don’t need to switch to C++ if you don’t want to. It is possible that in some cases we missed wrapping some structures into Python-compatible types - if you find one then let us know and we’ll fix it.

You can see how conversion is done with custom conversion path in the icdr GUI: Slicer/qMRMLSegmentationConversionParametersWidget.cxx at master · Slicer/Slicer · GitHub

There are some related Python code snippets that you may find useful.

Hi Andras,

Thanks for your response. I took a look at the Python code examples, and it seems like there aren’t any examples using a custom conversion path, just ones that use a custom conversion parameter.

I also took a look at the C++ code that you linked. There is a snippet that I would like to use:

  vtkSegmentation* segmentation = d->SegmentationNode->GetSegmentation();
  vtkSegmentationConverter::ConversionPathAndCostListType pathsCosts;
  segmentation->GetPossibleConversions(d->TargetRepresentationName.toUtf8().constData(), pathsCosts);

but it seems like the method:

GetPossibleConversions()

is not available to the Python object of vtkSegmentation (I checked this using the dir() function in Python).

Furthermore, looking at vtkSegmentationConverter, it appears there is no equivalent to: GetBinaryLabelmapRepresentationName () or
GetSegmentationBinaryLabelmapRepresentationName ()
for a Ribbon Model, which is the intermediate representation that I want to use. I would be curious to see if

segmentation.GetPossibleConversions()

would include it in one if its paths.

Thanks

1 Like