Identifying empty segments?

Hi, i’ve been using this code to grab a segment, but i found no way to check if it’s empty or not.

segmentation_node = getNode("Segmentation")
seg = segmentation_node.GetSegmentation()
seg0 = seg.GetNthSegment(0)

i tried using polydata = seg0.GetRepresentation("Closed surface") then polydata.GetNumberOfCells() but it only works if there is a closed surface representation of the segment, i’m looking for some approach that is independent of the existence of a closed surface if available, thanks for any inputs.

First of all, you can make your life a bit easier by using the utility functions to get representations:
https://apidocs.slicer.org/master/classvtkMRMLSegmentationNode.html#a71ebfa4439ec3ebdf57994888f572623

As for your question, you can check if the image data is empty by using the IsEmpty function
https://apidocs.slicer.org/master/classvtkOrientedImageData.html#a8ba73e835202dc5e05539a9e4441d70f

If it can occur in your use case that you have an image data with a valid extent but you’re wondering if there are only background voxels, you can use the vkImageAccumulate class
https://vtk.org/doc/nightly/html/classvtkImageAccumulate.html

You can also use slicer.util.arrayFromSegment(segmentation_node, segment_id).max() > 0 to see if the segment has any non-zero voxels.

1 Like

Thanks, that worked fine, only needed to make sure the binary label map extent was not empty(New and unedited segment), as arrayfromsegment returned an attribute error in that case

Thanks, indeed i need to check for the existence of foreground voxels, i could not get vtkImageAccumulate to work properly(result is always 0) im i doing it wrong?

segmentation = getNode(“Segmentation”)
seg = segmentation.GetSegmentation()
seg0 = seg.GetNthSegment(0)
segID = seg.GetSegmentIdBySegment(seg0)
stat = vtk.vtkImageAccumulate()
stat.SetInputData(segmentation.GetBinaryLabelmapRepresentation(segID))
print int(stat.GetVoxelCount())

I don’t quite understand. You marked @lassoan’s suggestion as solution still you try to use my suggestion for the exact same issue? I guess what solved your initial problem was the IsEmpty function, correct?

Anyway, you can use @lassoan’s simpler way to do the voxel counting.
As for your actual question, you need to call Update to have vtkImageAccumulate actually do the processing. also, if you just call GetVoxelCount like this, it will return the number of all voxels. Use SetIgnoreZero(True) to only get the number of foreground voxels.

1 Like

my issue is indeed solved, i tried vkImageAccumulate before but could not get it work, it’s interesting to have the voxel count rather than a boolean for future uses.

I actually did use both isEmpty to eliminate new segments (returned an error with arrayfromsegment) and then slicer.util.arrayFromSegment(segmentation_node, segment_id).max() to check for foregroud voxels existence, the final code is this:

if label.IsEmpty():
    full = False
elif not(label.IsEmpty()):
    if slicer.util.arrayFromSegment(segmentation, segmentID).max() > 0:
        full = True
    else:
        full = False

Thanks, that made it work.

You can use either VTK or numpy functions - for this very simple check they are about equally simple and efficient. If you use numpy then you can make things simpler and more pythonic like this:

try:
  full = slicer.util.arrayFromSegment(segmentation, segmentID).max() > 0
except AttributeError:
  # there is no labelmap in the segment
  full = False