Finding corresponding segments in segmentations

Hi, I haven’t found a way to change the segmentId on a SegmentationNode.
I can change the name of a segment, but not the ID.

segmentationNode.GetSegmentation().GetSegment('a_segment_id').SetName('segment_name')

Just wondering if I am missing some API, or it is just not possible.

Thanks!

I know there are calls from the widget:

a=slicer.modules.segmenteditor.widgetRepresentation().self().editor
a.setSegmentationNodeID("words")
# or
a.setCurrentSegmentId("words")

Why do you want to change the segment ID? Those are just identifiers that do not show up on the UI, they are just strings to uniquely identify the segments. The human readable identifier of the segments are their names. If you really want to, you can add a segment with an ID specified.

@jamesobutler As far as I understand he wants to set the ID for the segment, not the selected segment in Segment Editor.

My logic was using segmentId to compare segments (with same ID) between different subjects (each one represented with a SegmentationNode).

Creating a segmentation from a label map always give numerical segmentIds, usually 1, 2, .... However, when getting a segmentation from a model, the segmentId is the name of the model…

I wanted to change the segmentId generated from the model to be 1, for easy comparison with label maps.

But I can change my logic to use the segment name instead of ID, which makes more sense. Thanks!

Segment name could work for sure, however if you want to find corresponding segments, then I’d suggest making use of the terminologies feature.
Once you select a terminology for a segment, it fills a tag in the segment. You can then compare the values of these tags. The advantage of using terminologies is that it relies on a standard dictionary, which is unambiguous, and there is no room for human error when inputing the name for example.

1 Like

Changing segment ID of a segment that is already added to a segmentation node would cause many issues. When you create a segment but it is not yet added to the segmentation then you can still set the ID. However, for the described purpose teeminology seems to be a much better choice.

That sounds good! However, in my testing, it seems that not all the public members of vtkSegment are wrapped in python. Especially missing GetTags which uses a std::map as input.

slicer.mrmlScene.GetNodeByID('vtkMRMLSegmentationNode1').GetSegmentation().GetSegment('1')

Only GetTag(std::string, std::string&) is available, and it has a string reference, so it might be usable with s_ref = vtk.vtk.reference() for the second argument.

I am going to use names meanwhile, hopefully, will be enough for my needs. Thanks for the input, I will update if I find something else.

In Slicer you often find multiple interfaces for accessing the same features: some of them are more convenient to use from C++, while others are more accessible from Python.

Segment GetTag()/SetTag() is usable from Python, see for example here. You can find example of how to retrieve terminology for a segment here.

If you suggest specific python-accessible functions I can add them for you if this is the issue that prevents using terminologies.