# Automating thresholding of existing segments

**URL:** https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229
**Category:** Development
**Created:** [April 21, 2020, 11:27am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229 "2020-04-21T11:27:07Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)
#### Post date: [April 21, 2020, 11:27am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/1 "2020-04-21T11:27:07Z")

</div>

Dear Andras, all,

Thanks again for helping me with extraction segment cross-sectional area.  
I was wondering if you could help me with something else.

As I said earlier, I’m trying to find the cross sectional area of total muscle in a single cross-sectional image on CT.

I can create a segment (for instance “muscle”) and manually/rougly draw or paint the area of interest.  
After that, I use the thresholding option to select only the area that has hounsfield units between -29 and + 150. In the “masking” menu I select “Inside muscle”, so that Slicer only “subtracts” the irrelevant area from what I manually delineated. I can then use the segment cross-section area option you provided to calculate the area.

I want to try to use the python scripting to do the thresholding step. I am trying to use the script over here [https://gist.github.com/lassoan/5ad51c89521d3cd9c5faf65767506b37](https://gist.github.com/lassoan/5ad51c89521d3cd9c5faf65767506b37) as a basis but I can’t seem to edit it so that it does what I need. (It will only create new segmentations in the entire scan, but will not change the segmentation that I created)

Can you help me to automate this step?

Thanks so much in advance,  
Justin

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [April 22, 2020, 3:53am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/2 "2020-04-22T03:53:21Z")

</div>

If you don’t want to create new segments but update existing ones then instead of using `AddEmptySegment`, switch to an existing segment by calling `setCurrentSegmentID` (see complete example [here](https://gist.github.com/lassoan/2f5071c562108dac8efe277c78f2620f)).

---

<div class="post-metadata">

### Author: ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)
#### Post date: [April 28, 2020, 9:37am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/3 "2020-04-28T09:37:59Z")

</div>

Dear Andras,

Thanks for your suggestion, I have started working with your suggestion and the example that you show.  
Right now I have two “phases”, one creates the three segments that I will be painting by hand.

After painting the segment, the second one applies the thresholding to the existing segments using  
setCurrentSegmentID. However it wil then apply the threshold to the entire scan and not just the selected segment. When I manually perform this part i select the “Masking \> select editable area \> inside **segmentname** ” option separately for each segment.  
Can you help me with the code that sets the masking settings within each segment?  
I’m sure the code I’m using below will contain redundant steps, but at least this way I got it to work…

Best, Justin

```
## part 1: creating segments
# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

# Create temporary segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

# Create segments by thresholding
segmentsFromHounsfieldUnits = [
    ["Pec L", -29, 150],
    ["Pec R", -29, 150],
    ["Back muscle", -29, 150] ]
for segmentName, thresholdMin, thresholdMax in segmentsFromHounsfieldUnits:
    # Create segment
    addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(segmentName)
    segmentEditorNode.SetSelectedSegmentID(addedSegmentID)

# Delete temporary segment editor
segmentEditorWidget = None
slicer.mrmlScene.RemoveNode(segmentEditorNode)

## part 2: auto thresholding the hand-painted segments
# Create temporary segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

# Create segments by thresholding
segmentsFromHounsfieldUnits = [
    ["Pec L", -29, 150],
    ["Pec R", -29, 150],
    ["Back muscle", -29, 150] ]
for segmentName, thresholdMin, thresholdMax in segmentsFromHounsfieldUnits:
    # Fill by thresholding
    segmentEditorWidget.setCurrentSegmentID(addedSegmentID)
    segmentEditorWidget.setActiveEffectByName("Threshold")
    effect = segmentEditorWidget.activeEffect()
    effect.setParameter("MinimumThreshold",str(thresholdMin))
    effect.setParameter("MaximumThreshold",str(thresholdMax))
    effect.self().onApply()

# Delete temporary segment editor
segmentEditorWidget = None
slicer.mrmlScene.RemoveNode(segmentEditorNode)

```

 ![editable area selection](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/0/c086b5102ba5fbc53a61cb2ffed928408dae1661.png)

---

<div class="post-metadata">

### Author: ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)
#### Post date: [April 29, 2020, 7:51am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/4 "2020-04-29T07:51:37Z")

</div>

I have looked up some more information and found that I can use  
slicer.vtkMRMLSegmentEditorNode.PaintAllowedInsideSingleSegment

This segment should be defined in SetMaskSegmentID

So I have changed the script to this:

```
# Create temporary segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)
segmentEditorNode.PaintAllowedInsideSingleSegment

# Create segments by thresholding
segmentsFromHounsfieldUnits = [
    ["Pec L", -29, 150],
    ["Pec R", -29, 150],
    ["Back muscle", -29, 150] ]
for segmentName, thresholdMin, thresholdMax in segmentsFromHounsfieldUnits:
    # Fill by thresholding
    segmentEditorWidget.setCurrentSegmentID(addedSegmentID)
    segmentEditorWidget.setActiveEffectByName("Threshold")
    segmentEditorNode.SetMaskSegmentID(addedSegmentID)
    effect = segmentEditorWidget.activeEffect()
    effect.setParameter("MinimumThreshold",str(thresholdMin))
    effect.setParameter("MaximumThreshold",str(thresholdMax))
    effect.self().onApply()

# Delete temporary segment editor
segmentEditorWidget = None
slicer.mrmlScene.RemoveNode(segmentEditorNode)

```

Unfortunately, this still has the same effect in that it still applies the effect on the entire scan. Do you have suggestions?

Justin

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [April 30, 2020, 1:59am UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/5 "2020-04-30T01:59:15Z")

</div>

`segmentEditorNode.PaintAllowedInsideSingleSegment` is just a named constant. You can use this constant as an input in [SetMaskMode](http://apidocs.slicer.org/master/classvtkMRMLSegmentEditorNode.html#a451836bc25febd5d1101f0c09ae6a558) method. If you use this mode then you also need to [set a mask segment ID](http://apidocs.slicer.org/master/classvtkMRMLSegmentEditorNode.html#a852187ef0aad1f680280a0c268e01452).

---

<div class="post-metadata">

### Author: ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)
#### Post date: [April 30, 2020, 8:02pm UTC](https://discourse.slicer.org/t/automating-thresholding-of-existing-segments/11229/6 "2020-04-30T20:02:43Z")

</div>

Thanks for your help Andras! I finally got the script working as it should.

Best regards, Justin
