# Colour Gradient Based on Pixel Density of Overlaid Segmentations?

**URL:** https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294
**Category:** Support
**Tags:** segmentation, extensions-manager
**Created:** [October 21, 2021, 11:52pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294 "2021-10-21T23:52:33Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 21, 2021, 11:52pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/1 "2021-10-21T23:52:33Z")

</div>

Hello,

I am new to 3D slicer, but I have a series of MRIs which I have overlaid and segmented. I would like to now take those segmentations and apply a filter to visualize their overlap. I have seen this done with two segmentations, but as I have ~40 I would like to use a colour scale to express the relative amount of overlap.

Any suggestions would be appreciated!

Thanks, Greg

---

<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: [October 22, 2021, 3:53am UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/2 "2021-10-22T03:53:46Z")

</div>

A simple way of dealing with this is to write a short Python script, which does the following:

- create an “accumulation volume” (segments from all images will be added to it) fill with all zeros, get it as a numpy array (using `slicer.util.arrayFromVolume()`)
- load each segmentation, export the segment to a numpy array (using `slicer.util.arrayFromSegmentBinaryLabelmap`), you threshold this numpy array (set it to 1 where it has non-zero values), and add the values to the accumulation volume’s numpy array
- update the accumulation volume node from its numpy array (using `slicer.util.arrayFromVolumeModified()`)

---

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 24, 2021, 9:52pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/3 "2021-10-24T21:52:17Z")

</div>

Hi Andras,

Thank you for your response. Sorry I am still a little confused, I believe I have followed your instructions (although I am very much still learning so the mistake is probably mine), but now I just see a complete overlay of all these segmentations. Is there a way to apply a colour gradient based on the relative overlap?

Thanks, Greg

---

<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: [October 25, 2021, 11:42am UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/4 "2021-10-25T11:42:31Z")

</div>

Could you copy the otthon script that you created? We could tell you what to add or change to see the result as a scalar volume instead of a binary.

---

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 25, 2021, 3:37pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/5 "2021-10-25T15:37:38Z")

</div>

Hi Andras,

I am not terribly familiar with python (so after a few failed attempts) I used the method you mention under: [Segment / BinaryLabelMap to numpy array](https://discourse.slicer.org/t/segment-binarylabelmap-to-numpy-array/778).

Would this work for the problem?

---

<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: [October 25, 2021, 3:48pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/6 "2021-10-25T15:48:20Z")

</div>

You need to add the numpy arrays so that if a voxel is set to 1 in multiple segmentations then that voxel value will be larger than 1 (the value should be the number of segmentations where that voxel is non-zero).

---

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 26, 2021, 2:26am UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/7 "2021-10-26T02:26:25Z")

</div>

Hi Andras,

I think I must be making some mistake, when I try to make an accumulation volume using the code above I get thrown:

File “”, line 1, in   
File “/Applications/Slicer.app/Contents/bin/Python/slicer/util.py”, line 1476, in arrayFromVolume  
vimage = volumeNode.GetImageData()  
AttributeError: ‘str’ object has no attribute ‘GetImageData’

Greg

---

<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: [October 26, 2021, 4:05am UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/8 "2021-10-26T04:05:35Z")

</div>

`arrayFromVolumeNode` takes a volume node object as input (not the volume’s name). You can get the volume node object from the volume’s name by calling:

```
volumeNode = slicer.util.getNode('MyVolumeName')
```

---

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 26, 2021, 6:08pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/9 "2021-10-26T18:08:46Z")

</div>

Hi Andras,

When entering this code I run into the following problem:  
Traceback (most recent call last):  
File “”, line 1, in   
File “/Applications/Slicer.app/Contents/bin/Python/slicer/util.py”, line 1324, in getNode  
raise MRMLNodeNotFoundException(“could not find nodes in the scene by name or id ‘%s’” % (pattern if (isinstance(pattern, str)) else “”))  
slicer.util.MRMLNodeNotFoundException: could not find nodes in the scene by name or id ‘the\_scene\_I\_inputted.mrml’.

Sorry for all of these small errors

---

<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: [October 26, 2021, 11:29pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/10 "2021-10-26T23:29:41Z")

</div>

Replace `MyVolumeName` with the actual name of your volume node. It seems that the string that the method got was `the_scene_I_inputted.mrml` which does not seem like a volume node name.

---

<div class="post-metadata">

### Author: ![Greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Greg](https://discourse.slicer.org/u/Greg)
#### Post date: [October 26, 2021, 11:32pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/11 "2021-10-26T23:32:08Z")

</div>

> [@Greg](#):
>
> When entering this code I run into the following problem:  
> Traceback (most recent call last):  
> File “”, line 1, in  
> File “/Applications/Slicer.app/Contents/bin/Python/slicer/util.py”, line 1324, in getNode  
> raise MRMLNodeNotFoundException(“could not find nodes in the scene by name or id ‘%s’” % (pattern if (isinstance(pattern, str)) else “”))  
> slicer.util.MRMLNodeNotFoundException: could not find nodes in the scene by name or id ‘the\_scene\_I\_inputted.mrml’.
> 
> Sorry for all of these small errors

Hi Andras, sorry I should have clarified.

I replaced ‘My Volume Name’ with the volume of the scene I was working with. The ‘the\_scene\_I\_inputted.mrml’ is meant to be the placeholder for the scene that I inputted under ‘My Volume’. Sorry for the confusion.

---

<div class="post-metadata">

### Author: ![ungi](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/ungi/32/78573_2.png) [@ungi](https://discourse.slicer.org/u/ungi)
#### Post date: [November 14, 2021, 4:53pm UTC](https://discourse.slicer.org/t/colour-gradient-based-on-pixel-density-of-overlaid-segmentations/20294/12 "2021-11-14T16:53:41Z")

</div>

This code should work. It produces a volume named ExportVolume, which you can use in Volume Rendering to assign colors and opacities to show the density of original segments in each location.

```auto
# Export one volume that shows the sum of segments in a segmentation of the same shape

# Update these names using your scene

segmentationNodeName = '2'
masterVolumeName = '10 ciss3d_tra_iso'
outputVolumeName = 'ExportVolume'

# Prepare nodes that will be needed

segmentationNode = slicer.mrmlScene.GetFirstNodeByName(segmentationNodeName)
segLogic = slicer.modules.segmentations.logic()
segmentation = segmentationNode.GetSegmentation()
labelmapVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLabelMapVolumeNode")

# Make sure the output volume exists, and it has the same shape as the master volume for segmentation

outputVolume = slicer.mrmlScene.GetFirstNodeByName(outputVolumeName)
masterVolume = slicer.mrmlScene.GetFirstNodeByName(masterVolumeName)
if outputVolume is None:
  volumesLogic = slicer.modules.volumes.logic()
  outputVolume = volumesLogic.CloneVolume(slicer.mrmlScene, masterVolume, outputVolumeName)
  outputVolume.CreateDefaultDisplayNodes()

# Prepare output volume array and set voxel values to zero

exportArray = slicer.util.arrayFromVolume(outputVolume)
exportArray[:] = 0

# Add each segment to the output array one-by-one

for i in range(segmentation.GetNumberOfSegments()):
  segmentIds = vtk.vtkStringArray()
  segmentId = segmentation.GetNthSegmentID(i)
  segmentIds.InsertNextValue(segmentId)  
  segLogic.ExportSegmentsToLabelmapNode(segmentationNode, segmentIds, labelmapVolume, masterVolume)
  labelArray = slicer.util.arrayFromVolume(labelmapVolume)
  exportArray = exportArray + labelArray

# Update the output volume

slicer.util.updateVolumeFromArray(outputVolume, exportArray)

```
