Any way to get the mean values for a 4D image ROI

Hi!!!

I’m trying to get and array with the mean values of a 4D volume based in a segmentation. I’ve been reading the plugins which use the module segment statistics but I couldn’t find anything helpful.

Thank you very much.

There is currently no automated module that would run Segment Statistics for each time point of a time sequence. If you are familiar with Python programming then it should be very easy to write a script or Slicer module for this (few-hour work for someone who already knows Slicer well; couple of days for a newcomer). You can use CropVolumeSequence module as a template.

Let us know if you are willing to try this. If not, then right now the only option is to do it manually (click Apply in Segment Statistics module to compute results, hit Ctr+Shift+Right to go to the next frame, hit Apply again, etc.).

Yes, I solved it.

I used qSlicerMultiVolumeExplorerModuleHelper.extracFrame to create a new scalar volume node for each frame and then used SegmentStatistics.SegmentStatisticsLogic() to extract the features which I wanted (Mean, Std) for each frame and segment.

1 Like

Would you mind sharing the script so that others can learn from it? Thank you!

from qSlicerMultiVolumeExplorerModuleHelper import qSlicerMultiVolumeExplorerModuleHelper as Helper
import SegmentStatistics
import numpy as np

self.bgMultiVolumeSelector = slicer.qMRMLNodeComboBox()
self.bgMultiVolumeSelector.nodeTypes = [‘vtkMRMLMultiVolumeNode’]

self.segmentationSelector = slicer.qMRMLNodeComboBox()
self.segmentationSelector.nodeTypes = [“vtkMRMLSegmentationNode”]

def GetStatisticsOfSegments(self):

Seg = self.segmentationSelector.currentNode()
self.logic = SegmentStatistics.SegmentStatisticsLogic()
self.parameterNode = self.logic.getParameterNode()
self.parameterNode.SetParameter("Segmentation", Seg.GetID())
self.parameterNode.SetParameter('ClosedSurfaceSegmentStatisticsPlugin.enabled','False')
self.parameterNode.SetParameter('LabelmapSegmentStatisticsPlugin.enabled','False')
### All the plugins are set as a default True.
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.enabled','True')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.max.enabled','False')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.mean.enabled','True')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.median.enabled','False')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.min.enabled','False')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.stdev.enabled','True')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.volume_cm3.enabled','False')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.volume_mm3.enabled','False')
self.parameterNode.SetParameter('ScalarVolumeSegmentStatisticsPlugin.voxel_count.enabled','False')

self.Stats = {}

if self.bgMultiVolumeSelector.currentNode():
  for Frame in range(self.bgMultiVolumeSelector.currentNode().GetNumberOfFrames()):
    self.FrameNode = Helper.extractFrame(self.FrameNode, self.bgMultiVolumeSelector.currentNode(), Frame)
    self.parameterNode.SetParameter("ScalarVolume", self.FrameNode.GetID())
    visibleSegmentIds = vtk.vtkStringArray()
    Seg.GetSegmentation().GetSegmentIDs(visibleSegmentIds)
    for segmentIndex in range(visibleSegmentIds.GetNumberOfValues()):
      segmentID = visibleSegmentIds.GetValue(segmentIndex)
      self.logic.updateStatisticsForSegment(segmentID)
    statistics = self.logic.getStatistics()
    keys = self.logic.getNonEmptyKeys()
    longname, names = self.logic.getHeaderNames(keys)
    for key in keys:
      measurements = [statistics[segmentID, key] for segmentID in statistics["SegmentIDs"] if
                      (segmentID, key) in statistics] 
      if not self.Stats.get(names[key],None):
        self.Stats[names[key]] = [measurements]
      else:
        if names[key] != 'Segment':
          self.Stats[names[key]].append(measurements)
      
  self.NumberOfSegments = len(self.Stats['Segment'][0])
  self.Mean = np.array(self.Stats['Mean'])
  self.Std = np.array(self.Stats['Standard Deviation'])

It is something like this