# Segmentation using thresholding using Python

**URL:** <https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833>\
**Category:** Development\
**Tags:** segmentation\
**Created:** [July 31, 2019, 6:40pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833 "2019-07-31T18:40:52Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [July 31, 2019, 6:40pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/1 "2019-07-31T18:40:52Z")

</div>

Hey there,  
I’m back with more silly questions  
using the examples of using segment editor have been really helpful, the issue I have been running into, however, is using an image that is not the sample image.

Just dragging in an image and avoiding anything that uses ‘masterVolumeNode’ was my original plan, but I am unable to apply the threshold on the image of interest if I do it that way.Same with pulling in the image and setting it as the master volume manually on segment editor. So I did some digging to try and find out how to load in my own image the correct way and found this:

masterVolumeNode = slicer.util.loadVolume('C:/Users/m222222/Dropbox/BRAIN\_MASK.nii.gz’, returnNode=True)

(the path is similar to my actual path)  
and it doesn’t complain at me, but it also doesn’t open the file, and when I tried to run things anyways, after  
‘segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)’  
I got an error that I needed a VTK object, and after  
‘segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)’  
it also said that I needed a VTK object

if I run it without those 2 lines, it complains at the end on ‘effect.self().onApply()’ and says…

Traceback (most recent call last):  
File “”, line 1, in   
File “/Applications/Slicer.app/Contents/lib/Slicer-4.10/qt-scripted-modules/SegmentEditorEffects/SegmentEditorEffects/SegmentEditorThresholdEffect.py”, line 351, in onApply  
modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix)  
AttributeError: ‘NoneType’ object has no attribute ‘GetImageToWorldMatrix’

To be honest, I really don’t know what I’m doing on the coding front, so even simple things like loading images are rough, which is why I’m here.

I’m just confused and would like to know the correct way to load a master volume so the sample works with a novel image.

Thank you,  
Jazlynn

---

<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:** [August 1, 2019, 4:25am UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/2 "2019-08-01T04:25:05Z")

</div>

[This](https://gist.github.com/lassoan/1673b25d8e7913cbc245b4f09ed853f9) example should work as is, just replace this line:

```
masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

```

by this, if you use recent 4.11 version of Slicer:

```
masterVolumeNode = slicer.util.loadVolume('C:/Users/m222222/Dropbox/BRAIN_MASK.nii.gz')

```

by this, if you use 4.10 version:

```
[success, masterVolumeNode] = slicer.util.loadVolume('C:/Users/m222222/Dropbox/BRAIN_MASK.nii.gz', returnNode=True)
```

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 1, 2019, 5:31pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/3 "2019-08-01T17:31:21Z")

</div>

that makes a lot of sense, thank you

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 1, 2019, 6:40pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/4 "2019-08-01T18:40:03Z")

</div>

I replaced the first line with

[success, masterVolumeNode] = slicer.util.loadVolume(“C:/Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN\_MASK.nii.gz”, returnNode=True)

because it gave a syntax error the ran with one quote, and everything seemed to work until I got to that apply line

effect.self().onApply()

Where the callback was:

Traceback (most recent call last):  
File “”, line 1, in   
File “/Applications/Slicer.app/Contents/lib/Slicer-4.10/qt-scripted-modules/SegmentEditorEffects/SegmentEditorEffects/SegmentEditorThresholdEffect.py”, line 351, in onApply  
modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix)  
AttributeError: ‘NoneType’ object has no attribute ‘GetImageToWorldMatrix’

I’m really not sure why or what it going on internally in slicer when this happens, but it runs with the sample

sorry for all of the questions

best,  
Jazlynn

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 1, 2019, 6:44pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/5 "2019-08-01T18:44:05Z")

</div>

I think it may have something to do with the fact that in the sample, slicer actually opens the file, and you can see it in your 3 colored windows, but when I set my master volume, the file doesn’t come up visibly in slicer. I’m not sure if that could be the issue or not.

---

<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:** [August 1, 2019, 6:50pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/6 "2019-08-01T18:50:09Z")

</div>

Does the example that I linked above works? If yes then try to follow that example more closely, make modifications step-by-step, and see which change causes the problem.

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 1, 2019, 8:23pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/7 "2019-08-01T20:23:55Z")

</div>

The sample that is provided works without an issue, and slicer doesn’t throw up an error until the thresholding line (after going through the code step by step)

effect.self().onApply()

So there must be an issue earlier although there was no complaint from slicer. I believe that is has to do with loading the master image; when I set the master image to be my novel image, the image is not shown in the colored ‘slices’ windows. However, when the sample image is loaded, it appears in the colored ‘slices’ windows.

The exact code I have been running is:  
The master volume is a mask, saved as a nifty file.

[success, masterVolumeNode] = slicer.util.loadVolume(“C:/Users/m22222/Dropbox/BRAIN\_MASK.nii.gz”, returnNode=True)

segmentationNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLSegmentationNode”)  
segmentationNode.CreateDefaultDisplayNodes() # only needed for display  
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)  
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(“skin”)

segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()  
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)  
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLSegmentEditorNode”)  
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)  
segmentEditorWidget.setSegmentationNode(segmentationNode)  
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

segmentEditorWidget.setActiveEffectByName(“Threshold”)  
effect = segmentEditorWidget.activeEffect()  
effect.setParameter(“MinimumThreshold”,“1”)  
effect.setParameter(“MaximumThreshold”,“1”)  
effect.self().onApply()

segmentEditorWidget = None  
slicer.mrmlScene.RemoveNode(segmentEditorNode)

segmentationNode.CreateClosedSurfaceRepresentation()

---

<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:** [August 1, 2019, 9:14pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/8 "2019-08-01T21:14:14Z")

</div>

What is the output of `print(master VolumeNode)`?

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 1, 2019, 9:26pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/9 "2019-08-01T21:26:57Z")

</div>

The output is just ‘none’

---

<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:** [August 2, 2019, 1:59am UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/10 "2019-08-02T01:59:23Z")

</div>

It means the image loading has failed. The application log may contain more details (menu: Help / Report a bug). Is the file path correct? Can you load the image by using “Add data”?

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 2, 2019, 5:21pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/11 "2019-08-02T17:21:01Z")

</div>

When I use the ‘add data’ option I get

[INFO][VTK] 02.08.2019 10:18:59 [vtkMRMLVolumeArchetypeStorageNode (0x7f9436777de0)] (/Volumes/Dashboards/Stable/Slicer-4102/Libs/MRML/Core/vtkMRMLVolumeArchetypeStorageNode.cxx:465) - Loaded volume from file: /Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN\_MASK.nii.gz. Dimensions: 270x320x76. Number of components: 1. Pixel type: float.  
[DEBUG][Qt] 02.08.2019 10:18:59 [] (unknown:0) - “Volume” Reader has successfully read the file “/Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN\_MASK.nii.gz” “[0.29s]”

in the application log

When I enter it using the CLI I get

[DEBUG][Qt] 02.08.2019 10:18:00 [] (unknown:0) - Python console user input: [success, masterVolumeNode] = slicer.util.loadVolume(“C:/Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN\_MASK.nii.gz”, returnNode=True)

---

<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:** [August 2, 2019, 5:26pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/12 "2019-08-02T17:26:36Z")

</div>

Path looks different:  
`/Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN_MASK.nii.gz`  
is not the same as  
`C:/Users/m214492/Dropbox/CNV Modeling/Brain for Gustavo/BRAIN_MASK.nii.gz`

Drive name (such as `C:`) is only used on Windows machines.

---

<div class="post-metadata">

**Author:** ![jazlynn21100](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jazlynn21100](https://discourse.slicer.org/u/jazlynn21100)\
**Post date:** [August 2, 2019, 5:28pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/13 "2019-08-02T17:28:37Z")

</div>

Oh my goodness you have just saved my life, thank you so much

---

<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:** [August 2, 2019, 9:20pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/14 "2019-08-02T21:20:04Z")

</div>

A post was split to a new topic: [Change segment color and opacity](https://discourse.slicer.org/t/change-segment-color-and-opacity/7855)

---

<div class="post-metadata">

**Author:** ![xavier\_bouquin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/xavier_bouquin/32/14620_2.png) [@xavier\_bouquin](https://discourse.slicer.org/u/xavier_bouquin)\
**Post date:** [March 15, 2022, 1:14pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/15 "2022-03-15T13:14:42Z")

</div>

Hello  
I am new to 3DS Slicer.  
I would like to automate 3D mesh generation with 3DSlicer from dcm serie and save it as obj file.  
the idea is to open obj files in hololens afterwards.

I can open my dcm files like this.

```python
dicomDataDir = "C:/Users/xbouq/Downloads/Anonymized/dcm"
loadedNodeIDs = [] # this list will contain the list of all loaded node IDs

from DICOMLib import DICOMUtils
with DICOMUtils.TemporaryDICOMDatabase() as db:
  DICOMUtils.importDicom(dicomDataDir, db)
  patientUIDs = db.patients()
  for patientUID in patientUIDs:
    loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

```

But after i dont understand how make a link with segmentatioNodes

```python
segmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode')
segmentationNode.CreateDefaultDisplayNodes()
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment('skin')

segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentEditorNode')
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

segmentEditorWidget.setActiveEffectByName('Threshold')
effect = segmentEditorWidget.activeEffect()
effect.setParameter('MinimumThreshold','135') // for bones
effect.setParameter('MaximumThreshold','294')
effect.self().onApply()

```

Can you help me ?  
maybe there is a plugin for 3DSlicer?

---

<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:** [March 18, 2022, 2:36pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/16 "2022-03-18T14:36:20Z")

</div>

You can get the volume node object from `loadedNodeIDs` by using `masterVolumeNode = slicer.mrmlScene.GetNodeByID(nodeID)`.

If you import a complete DICOM study then the loaded nodes include scout scans, dose report, etc., so you may want to filter out images that have only one or few slices.

---

<div class="post-metadata">

**Author:** ![xavier\_bouquin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/xavier_bouquin/32/14620_2.png) [@xavier\_bouquin](https://discourse.slicer.org/u/xavier_bouquin)\
**Post date:** [April 26, 2022, 3:22pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/17 "2022-04-26T15:22:34Z")

</div>

Thank’s very lot Andras  
But now i have another problem.

```auto
dicomDataDir = "C:/Users/xbouq/Downloads/Anonymized/dcm"
loadedNodeIDs = [] # this list will contain the list of all loaded node IDs

from DICOMLib import DICOMUtils
with DICOMUtils.TemporaryDICOMDatabase() as db:
  DICOMUtils.importDicom(dicomDataDir, db)
  patientUIDs = db.patients()
  for patientUID in patientUIDs:
    loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

segmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode')
masterVolumeNode = segmentationNode.GetNodeReference(segmentationNode.GetReferenceImageGeometryReferenceRole())

segmentationNode.CreateDefaultDisplayNodes()
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment('skin')

segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentEditorNode')
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment("Segmentation")
segmentEditorNode.SetSelectedSegmentID(addedSegmentID)
    
segmentEditorWidget.setActiveEffectByName('Threshold')
effect = segmentEditorWidget.activeEffect()
effect.setParameter('MinimumThreshold',"135")
effect.setParameter('MaximumThreshold',"294")
effect.self().onApply()

```

When execution arrival at this line i have this error, Something escape me…

````auto
SegmentEditorThresholdEffect.py", line 590, in onApply

``` modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix)
AttributeError: 'NoneType' object has no attribute 'GetImageToWorldMatrix'

layoutManager = slicer.app.layoutManager()
threeDWidget = layoutManager.threeDWidget(0)
threeDView = threeDWidget.threeDView()
threeDView.resetFocalPoint()  

outputFolder = "C:/Users/xbouq/Downloads/Anonymized/dcm"
slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsClosedSurfaceRepresentationToFiles(outputFolder, segmentationNode, None, "OBJ", True, 1.0, False)

````

---

<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 26, 2022, 5:48pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/18 "2022-04-26T17:48:01Z")

</div>

> [@xavier\_bouquin](#):
>
> ```auto
> masterVolumeNode = segmentationNode.GetNodeReference(segmentationNode.GetReferenceImageGeometryReferenceRole())
> 
> ```

This would get you the node that was used to set the segmentation geometry (which is usually the master volume). But you have just created a new segmentation node. You have not set its geometry, so this GetNode… method will return None.

Instead, you can set the master volume (a volume that you loaded from DICOM) into the segmentation node by calling `segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)`.

---

<div class="post-metadata">

**Author:** ![xavier\_bouquin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/xavier_bouquin/32/14620_2.png) [@xavier\_bouquin](https://discourse.slicer.org/u/xavier_bouquin)\
**Post date:** [April 27, 2022, 9:29am UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/19 "2022-04-27T09:29:03Z")

</div>

> [@xavier\_bouquin](#):
>
> `masterV`

Hi Andras  
How to replace this init of masterVolumeNode  
sampleDataLogic = SampleData.SampleDataLogic()  
masterVolumeNode = sampleDataLogic.downloadMRHead()

with this loading system  
dicomDataDir = “C:/Users/xbouq/Downloads/Anonymized/dcm”  
loadedNodeIDs = # this list will contain the list of all loaded node IDs

from DICOMLib import DICOMUtils  
with DICOMUtils.TemporaryDICOMDatabase() as db:  
DICOMUtils.importDicom(dicomDataDir, db)  
patientUIDs = db.patients()  
for patientUID in patientUIDs:  
loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

masterVolumeNode =

Do you know if there are freelancers to develop with 3dSlicer.  
Our idea is to do a proof of concept, where we will copy Dicom files to a directory and with an online command we could select filters to generate 3d files to visualize them in the end in hololens.  
But we don’t have any expertise with 3Dslicer which is sacred software and with Python either.

I manage to generate OBJ files with the software but I can’t automate the process and I may not find the time to learn to program with 3Dslicer. There are too many concepts that I don’t know 🙂

---

<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 27, 2022, 3:02pm UTC](https://discourse.slicer.org/t/segmentation-using-thresholding-using-python/7833/20 "2022-04-27T15:02:33Z")

</div>

It would be something like this:

```auto
i = 0 # first loaded image series (it multiple image series are loaded then you may want to iterate through all of them)
masterVolumeNode = slicer.mrmlScene.GetNodeByID(loadedNodeIDs[i])

```

> [@xavier\_bouquin](#):
>
> Our idea is to do a proof of concept, where we will copy Dicom files to a directory and with an online command we could select filters to generate 3d files to visualize them in the end in hololens.  
> But we don’t have any expertise with 3Dslicer which is sacred software and with Python either.

Simple thresholding often does not provide sufficiently good quality results. I would recommend to use `Grow from seeds` or `Local threshold` effects in Segment Editor, or use MONAILabel extension to train a neural network for automatic segmentation. As a proof of concept, you can segment a couple of images manually using Segment Editor module and later you can automate it.

> [@xavier\_bouquin](#):
>
> Do you know if there are freelancers to develop with 3dSlicer.

I would recommend to contact [Slicer Commercial Partners](https://www.slicer.org/commercial-use.html#commercial-partners).
