Is there any sort of "batch" segment statistics?

Hello everyone,

I performed semi-automated segmentation of muscles on many CT-scan of patients. The data base is organized this way : patients \ slice \ segmentation. For each patients, there is 2 or 3 slice at different time points (its only one slice for the measurements, not a volume). I would like to compute the mean area + mean density in a first step (and eventually apply a pyradiomics pipeline further on). Here is the structure of the data :

Is there anyway to compute a batch script (or maybe it already exists?) that would create a single table with patients name and corresponding “segment statistic output” ? I have more >100 and must admit I’m afraid I’ll have to do everything manually…

I haven’t done this myself, but if you are able to do a little bit of python programming this is certainly doable. Have you gone through the tutorials enough that you are comfortable with doing some scripting? If so we can give you some specific suggestions for this task.

Hello,

Thank you very much for your answer. The problem is I am a complete beginner in programming language…currently starting with R for PhD purposes but never done python or matlab…

I went through the tutorial but did not find any pre-set option/tools to get the segment statistic output in a table with patient’s name (as organized in the DICOM)…

Is there anyone here who has done something similar and is able to step up with some code?

100 cases is on that borderline where you might just be more efficient to do it by hand, although you will benefit much more in the long term by learning the python scripting.

You might start by looking at the Case Iterator.

Thank you for your quick feedback.

My main issue is that I already performed all segmentations and it seems that Case Iterator would have required me to start with it beforehand…

I already tried manually but this is a nightmare as I have ± 100 patients with 1 to 3 studies per patients (hence >200) and when I go to segment statistics, the lists of studies are not sorted by patients name but by slice names, which makes almost impossible to match each slice names with each .DICOM files :

Help^^

You can find example scripts for processing a single case script repository and module tests). Once you have a code snippet that works for a single file, you can iterate through all the files in a folder.

Dear @Maxnach

Can you try something like the following (iterate through all the segmentation MRML modes in your slicer scene and generate the statistics…)? here is a code snippet to demonstrate this for mean intensity

for segmentationNode in slicer.util.getNodesByClass('vtkMRMLSegmentationNode'):
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolumeSegmentStatisticsPlugin.mean.enabled", str(True)) 
    segStatLogic.computeStatistics()
    stats = segStatLogic.getStatistics()
    for segmentId in stats['SegmentIDs']:
        mean = np.array(stats[segmentId,"ScalarVolumeSegmentStatisticsPlugin.mean"])
        print(mean)

Andinet

Dear Andinet,

Many thanks for your suggestion, I’m a proper beginner and maybe I did it wrong, but here is the outcome in the python command prompt :

Also, maybe that could help, I read a bit since your mentionned MRML and it seems indeed that every segmentation has its MRML ref, however the labelling (numbers) does not make any sense to me :

The magical solution would be some script that measures the segment.stat from the MRML-ref segmentation/scalar volume and could “match” it with DICOM name/date… which I guess is what you did with this code snippet… but tried everything cannot launch it properly… any ideas where I could have go wrong ?

Many thanks in advance, I feel a solution is not far but my 0 background in coding is probably hiding it :confused:

Here is a little bit of a more complete code snippet

import SegmentStatistics
import numpy as np

segStatLogic = SegmentStatistics.SegmentStatisticsLogic()

#Scalar Volume MRML Node List ( You will need this to generate image intensity statistics )
scalarVolumeNode = slicer.util.getNodesByClass('vtkMRMLScalarVolumeNode')

#WARNING: Assuming all segmentations were done on the same master volume, in this case the first one
segStatLogic.getParameterNode().SetParameter("ScalarVolume", scalarVolumeNode[0].GetID())
segStatLogic.getParameterNode().SetParameter("ScalarVolumeSegmentStatisticsPlugin.mean.enabled", str(True))

for segmentationNode in slicer.util.getNodesByClass('vtkMRMLSegmentationNode'):
    print(segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.computeStatistics()
    stats = segStatLogic.getStatistics()
    for segmentId in stats['SegmentIDs']:
        mean = np.array(stats[segmentId,"ScalarVolumeSegmentStatisticsPlugin.mean"])
        print(mean)

Andinet

Thank you so much, it seems it loader the segmentation, but there were an error at some point. Of note, each master volume has its own segmentation (actually each master volume = 1 slice of 1 patient at 1 time point)

import SegmentStatistics

import numpy as np

segStatLogic = SegmentStatistics.SegmentStatisticsLogic()

#Scalar Volume MRML Node List ( You will need this to generate image intensity statistics )

scalarVolumeNode = slicer.util.getNodesByClass(‘vtkMRMLScalarVolumeNode’)

#WARNING: Assuming all segmentations were done on the same master volume, in this case the first one

segStatLogic.getParameterNode().SetParameter(“ScalarVolume”, scalarVolumeNode[0].GetID())

segStatLogic.getParameterNode().SetParameter(“ScalarVolumeSegmentStatisticsPlugin.mean.enabled”, str(True))

for segmentationNode in slicer.util.getNodesByClass(‘vtkMRMLSegmentationNode’):

… print(segmentationNode.GetID())

vtkMRMLSegmentationNode10

vtkMRMLSegmentationNode11

vtkMRMLSegmentationNode12

vtkMRMLSegmentationNode13

vtkMRMLSegmentationNode14

vtkMRMLSegmentationNode15

vtkMRMLSegmentationNode16

vtkMRMLSegmentationNode17

vtkMRMLSegmentationNode18

vtkMRMLSegmentationNode19

vtkMRMLSegmentationNode20

vtkMRMLSegmentationNode21

vtkMRMLSegmentationNode22

vtkMRMLSegmentationNode23

vtkMRMLSegmentationNode24

vtkMRMLSegmentationNode25

vtkMRMLSegmentationNode26

vtkMRMLSegmentationNode27

vtkMRMLSegmentationNode28

vtkMRMLSegmentationNode29

vtkMRMLSegmentationNode30

vtkMRMLSegmentationNode31

vtkMRMLSegmentationNode32

vtkMRMLSegmentationNode33

vtkMRMLSegmentationNode34

vtkMRMLSegmentationNode35

vtkMRMLSegmentationNode36

vtkMRMLSegmentationNode37

vtkMRMLSegmentationNode38

vtkMRMLSegmentationNode39

vtkMRMLSegmentationNode40

vtkMRMLSegmentationNode41

vtkMRMLSegmentationNode42

vtkMRMLSegmentationNode43

vtkMRMLSegmentationNode44

vtkMRMLSegmentationNode45

vtkMRMLSegmentationNode46

vtkMRMLSegmentationNode47

vtkMRMLSegmentationNode48

vtkMRMLSegmentationNode49

vtkMRMLSegmentationNode50

vtkMRMLSegmentationNode51

vtkMRMLSegmentationNode52

vtkMRMLSegmentationNode53

vtkMRMLSegmentationNode54

vtkMRMLSegmentationNode55

vtkMRMLSegmentationNode56

vtkMRMLSegmentationNode57

vtkMRMLSegmentationNode58

vtkMRMLSegmentationNode59

vtkMRMLSegmentationNode60

vtkMRMLSegmentationNode61

vtkMRMLSegmentationNode62

vtkMRMLSegmentationNode63

vtkMRMLSegmentationNode64

vtkMRMLSegmentationNode65

vtkMRMLSegmentationNode66

vtkMRMLSegmentationNode67

vtkMRMLSegmentationNode68

vtkMRMLSegmentationNode69

vtkMRMLSegmentationNode70

vtkMRMLSegmentationNode71

vtkMRMLSegmentationNode72

vtkMRMLSegmentationNode73

vtkMRMLSegmentationNode74

vtkMRMLSegmentationNode75

vtkMRMLSegmentationNode76

vtkMRMLSegmentationNode77

vtkMRMLSegmentationNode78

vtkMRMLSegmentationNode79

vtkMRMLSegmentationNode80

vtkMRMLSegmentationNode81

vtkMRMLSegmentationNode82

vtkMRMLSegmentationNode83

vtkMRMLSegmentationNode84

vtkMRMLSegmentationNode85

vtkMRMLSegmentationNode86

vtkMRMLSegmentationNode87

vtkMRMLSegmentationNode88

vtkMRMLSegmentationNode89

vtkMRMLSegmentationNode90

vtkMRMLSegmentationNode91

vtkMRMLSegmentationNode92

vtkMRMLSegmentationNode93

vtkMRMLSegmentationNode94

vtkMRMLSegmentationNode95

vtkMRMLSegmentationNode96

vtkMRMLSegmentationNode97

vtkMRMLSegmentationNode98

vtkMRMLSegmentationNode99

vtkMRMLSegmentationNode100

vtkMRMLSegmentationNode101

vtkMRMLSegmentationNode102

vtkMRMLSegmentationNode103

vtkMRMLSegmentationNode104

vtkMRMLSegmentationNode105

vtkMRMLSegmentationNode106

vtkMRMLSegmentationNode107

vtkMRMLSegmentationNode108

vtkMRMLSegmentationNode109

vtkMRMLSegmentationNode110

vtkMRMLSegmentationNode111

vtkMRMLSegmentationNode112

vtkMRMLSegmentationNode113

vtkMRMLSegmentationNode114

vtkMRMLSegmentationNode115

vtkMRMLSegmentationNode116

vtkMRMLSegmentationNode117

vtkMRMLSegmentationNode118

vtkMRMLSegmentationNode119

vtkMRMLSegmentationNode120

vtkMRMLSegmentationNode121

vtkMRMLSegmentationNode122

vtkMRMLSegmentationNode123

vtkMRMLSegmentationNode124

vtkMRMLSegmentationNode125

vtkMRMLSegmentationNode126

vtkMRMLSegmentationNode127

vtkMRMLSegmentationNode128

vtkMRMLSegmentationNode129

vtkMRMLSegmentationNode130

vtkMRMLSegmentationNode131

vtkMRMLSegmentationNode132

vtkMRMLSegmentationNode133

vtkMRMLSegmentationNode134

vtkMRMLSegmentationNode135

vtkMRMLSegmentationNode136

vtkMRMLSegmentationNode137

vtkMRMLSegmentationNode138

vtkMRMLSegmentationNode139

vtkMRMLSegmentationNode140

vtkMRMLSegmentationNode141

vtkMRMLSegmentationNode142

vtkMRMLSegmentationNode143

vtkMRMLSegmentationNode144

vtkMRMLSegmentationNode145

vtkMRMLSegmentationNode146

vtkMRMLSegmentationNode147

vtkMRMLSegmentationNode148

vtkMRMLSegmentationNode149

vtkMRMLSegmentationNode150

vtkMRMLSegmentationNode151

vtkMRMLSegmentationNode152

vtkMRMLSegmentationNode153

vtkMRMLSegmentationNode154

vtkMRMLSegmentationNode155

vtkMRMLSegmentationNode156

vtkMRMLSegmentationNode157

vtkMRMLSegmentationNode158

vtkMRMLSegmentationNode159

vtkMRMLSegmentationNode160

vtkMRMLSegmentationNode161

vtkMRMLSegmentationNode162

vtkMRMLSegmentationNode163

vtkMRMLSegmentationNode164

vtkMRMLSegmentationNode165

vtkMRMLSegmentationNode166

vtkMRMLSegmentationNode167

vtkMRMLSegmentationNode168

vtkMRMLSegmentationNode169

vtkMRMLSegmentationNode170

vtkMRMLSegmentationNode171

vtkMRMLSegmentationNode172

vtkMRMLSegmentationNode173

vtkMRMLSegmentationNode174

vtkMRMLSegmentationNode175

vtkMRMLSegmentationNode176

vtkMRMLSegmentationNode177

vtkMRMLSegmentationNode178

vtkMRMLSegmentationNode179

vtkMRMLSegmentationNode180

vtkMRMLSegmentationNode181

segStatLogic.getParameterNode().SetParameter(“Segmentation”, segmentationNode.GetID())

File “”, line 1

segStatLogic.getParameterNode().SetParameter(“Segmentation”, segmentationNode.GetID())

^

IndentationError: unexpected indent

segStatLogic.computeStatistics()

File “”, line 1

segStatLogic.computeStatistics()

^

IndentationError: unexpected indent

stats = segStatLogic.getStatistics()

File “”, line 1

stats = segStatLogic.getStatistics()

^

IndentationError: unexpected indent

for segmentId in stats[‘SegmentIDs’]:

File “”, line 1

for segmentId in stats[‘SegmentIDs’]:

^

IndentationError: unexpected indent

mean = np.array(stats[segmentId,“ScalarVolumeSegmentStatisticsPlugin.mean”])

File “”, line 1

mean = np.array(stats[segmentId,“ScalarVolumeSegmentStatisticsPlugin.mean”])

^

IndentationError: unexpected indent

print(mean)

Python is very sensitive to indentation.

Indentation error is most likely due to how you copy-paste the code into the console (extra line breaks may interfere with the parser). Copy-pasting the code in smaller chunks or putting the code into a Python scripted module should fix the issue.