Segment / BinaryLabelMap to numpy array

Operating system:Windows 10
Slicer version: 4.7.0-2017-07-19

Hello All,

I’m trying to get a numpy array out of a segment or binarylabelmap and I can’t find a way to do that currently. I’m sure it’s right in front of me…

I’m just trying to use it to mask my grayscale data array so if there’s a better way to go about this I’m all ears!

What I hoped to do:
grayDataArray = arrayFromVolume(grayscaleVolume)
segmentArray = arrayFromVolume(segment) # this obviously doesn’t work :slight_smile:
maskedData = grayDataArray * segmentArray

Thanks for any help and advice!

Colin

1 Like

Segmentation node -> labelmap node: https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Export_labelmap_node_from_segmentation_node

Labelmap node -> numpy array: https://www.slicer.org/wiki/Documentation/Nightly/Developers/Python_scripting#Accessing_Volume_data_as_numpy_array

2 Likes

This works for me, if your Segmentation is named “Seg” and Volume is named “Vol”. If they are named differently, you would just change the parameters to ‘getNode’ in the first two lines

volumeNode = slicer.util.getNode('Vol')  # Get the volume node
seg = slicer.util.getNode('Seg') # Get the segmentation node

# Create a binary label volume from segmentation
labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
#To export specific segments instead, edit the following line with the one in the bottom
slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(seg, labelmapVolumeNode) 

# Export data as numpy arrays
dicomData = arrayFromVolume(volumeNode)
mask = arrayFromVolume(labelmapVolumeNode)

Edit: to export specific segments instead of all of the segmentation, use the following code:

slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode(seg,segmentsToExport, labelMapVolumeNode)

The segmentsToExport value has to be a vtkStringArray containing all the segment ID’s that you would like to be exported (note, I noticed that this overrides the label map), which is conceptually a fancy string array. To initialize it you have to run the following:

#To get the segment ID of the first segment on the list (named Segment_1 below):
segmentId = seg.GetSegmentation().GetNthSegmentID(0)

image

import vtk
segmentsToExport = vtk.vtkStringArray()
segmentsToExport.InsertNextValue(segmentId)
1 Like

I’m assuming the following code converts all of the segments onto a single labelmap?

So If I wanted this for one or multiple segments (but not all) I can just use:

slicer.modules.segmentations.logic().ExportSegmentsToLabelMapNode(seg,segmentNameArray,labelMapVolumeNode)

Now, I’m not entirely sure what I’m getting from this because now I have an error that the volume array (volumeNode) and the segmentation array (labelmapVolumeNode) have different sizes

1 Like

Try the edit that I made, does that still give you an error?

You can resample the label to match the volume geometry, for example as done here: SlicerRadiomics/SlicerRadiomics.py at master · AIM-Harvard/SlicerRadiomics · GitHub

The option of matching geometry is exposed in the Segmentations module GUI (specified by the “Reference volume” node), perhaps there is a corresponding API for that too, but I don’t have time to look for it now.

1 Like

Sorry I’m late to respond to this.
I think your link is incorrect, it looks like the solution you’re speaking of is a bit further down. I think I found it though:

I appreciate the help!

That’s probably because the code changed since I inserted the link, and I referred to the master instead of the specific commit.

Glad you found it anyway!

A neat GitHub trick is to press “y” to get a canonical link.
See https://help.github.com/articles/getting-permanent-links-to-files/

1 Like

Thanks @jcfr!

Here comes the permalink: https://github.com/Radiomics/SlicerRadiomics/blob/97bdf52df6ba40b911b4e5d9783a017be2d2bfe4/SlicerRadiomics/SlicerRadiomics.py#L383-L386

2 Likes