# Counting the number of segments

**URL:** <https://discourse.slicer.org/t/counting-the-number-of-segments/32251>\
**Category:** Support\
**Tags:** segmentation\
**Created:** [October 16, 2023, 2:17pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251 "2023-10-16T14:17:29Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [October 16, 2023, 2:17pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/1 "2023-10-16T14:17:29Z")

</div>

I have a volume from which I have segmented several scattered isolated structures. These are the nuclei of a group of cells.  
I need to count the number of these segments (nuclei).

Is there a function to do this?

Thank you for the kind answer

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [October 16, 2023, 3:04pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/2 "2023-10-16T15:04:27Z")

</div>

You could use Identify Islands plus Segment Statistics for that. It won’t be efficient if you have over 100 islands or so. You could write a quick python script to calculate the answer.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 9, 2024, 9:30am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/3 "2024-04-09T09:30:30Z")

</div>

Thank you very much for your answer pieper.

As you anticipated, I was able to use this method on small files for tests but no longer on large files with many objects.  
Can you suggest me where to read material that will enable me to start writing python scripts?  
Can I run these scripts directly in 3D Slicer?

Thank you

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 9, 2024, 12:19pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/4 "2024-04-09T12:19:44Z")

</div>

You can start by reading through the [script repository](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html) to see what’s possible and then do some of the programming tutorials linked from [slicer.org](http://slicer.org).

---

<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 10, 2024, 4:10am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/5 "2024-04-10T04:10:01Z")

</div>

The filter that counts cells is called [vtkITKIslandMath](https://apidocs.slicer.org/master/classvtkITKIslandMath.html#details). For example:

```python
segmentationNode = getNode('Segmentation')
segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(0)

# Get segment binary labelmap representation as vtkOrientedImageData
image = slicer.vtkOrientedImageData()
segmentationNode.GetBinaryLabelmapRepresentation(segmentID, image)

# Get number of islands
import vtkITK
islands = vtkITK.vtkITKIslandMath()
islands.SetInputData(image)
islands.SetMinimumSize(10)
islands.Update()
print(f"Found {islands.GetNumberOfIslands()} islands")

```

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 12, 2024, 8:02am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/6 "2024-04-12T08:02:12Z")

</div>

> [@lassoan](#):
>
> ```auto
> segmentationNode = getNode('Segmentation')
> segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(0)
> 
> # Get segment binary labelmap representation as vtkOrientedImageData
> image = slicer.vtkOrientedImageData()
> segmentationNode.GetBinaryLabelmapRepresentation(segmentID, image)
> 
> # Get number of islands
> import vtkITK
> islands = vtkITK.vtkITKIslandMath()
> islands.SetInputData(image)
> islands.SetMinimumSize(10)
> islands.Update()
> print(f"Found {islands.GetNumberOfIslands()} islands")
> 
> ```

Dear pieper and lassoan,  
thank you for your answers.

I tried to copy and post the script from lassoan in the Python Console of 3D Slicer replacing the text “segmentID” with the name of my segment (“Nuclei”).  
And i got this error:  
Traceback (most recent call last):  
File “”, line 6, in   
NameError: name ‘Nuclei’ is not defined

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/9/a9878972b15cb5de149cf7f32f87448c5870528b.png)

I also tried to convert the segment in a module. But I get the same message.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 12, 2024, 9:19am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/7 "2024-04-12T09:19:25Z")

</div>

When I run the script without changing anything in it I get this error.  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/e/5/e58f4c0c52babac29d440ff2570680aff1d06084.png)

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 12, 2024, 3:49pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/8 "2024-04-12T15:49:28Z")

</div>

Zooming in heavily on my images, I realized that I have very small islands accidentally selected by the threshold function. This increases the number of islands and could be the problem.

I cut the segments with the Scissor function to test the script a on smaller volume. I rounded the segments with the Smoothing function and eliminated the smaller islands with Remove small islands. After several progressively more aggressive attempts, I obtained a number of islands small enough to be counted with the script. However, on the original files I will definitely have more than 255 objects.  
Is there a possibility of counting more objects with a different script? Can the “maximum output pixel type” be increased?  
Or, is there a possibility of analyzing sequentially adjacent portions of the volume automatically and then summing up the results of the individual portions analyzed?

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [April 12, 2024, 4:44pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/9 "2024-04-12T16:44:44Z")

</div>

What is your modality? If you are working with microscopy, did you try more cell specific NN for this task? I am not sure where they stand with 3D data, but cellpose seems to have been developed specifically for this purpose.

> **[GitHub - MouseLand/cellpose: a generalist algorithm for cellular segmentation...](https://github.com/MouseLand/cellpose)**
>
> a generalist algorithm for cellular segmentation with human-in-the-loop capabilities - MouseLand/cellpose

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 12, 2024, 4:52pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/10 "2024-04-12T16:52:48Z")

</div>

`vtkITKIslandMath` is probably just using the same scalar type as your input data. So if you cast the data, wither in vtk or using the Cast Scalar Volume module you can use an integer type with more bits to support more islands.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 18, 2024, 3:57pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/11 "2024-04-18T15:57:33Z")

</div>

thank you muratmaga. The segmentation of the cells into two dimensions has already been done by another method other than cellpose but which nevertheless worked adequately. Now I need to get the data out of the 3D files.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 18, 2024, 4:00pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/12 "2024-04-18T16:00:59Z")

</div>

Thank you piper.  
I converted my volume in .vtk and performed again the segmentation as it was done before.

I used the code from [lassoan](https://discourse.slicer.org/u/lassoan) and now I am stuck with this error:

> Traceback (most recent call last):  
> File “”, line 1, in   
> File “C:\Users\XX\AppData\Local\slicer.org\Slicer 5.6.2\bin\Python\slicer\util.py”, line 1566, 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 ‘Segmentation’

Am I missing any steps in the segmentation?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 18, 2024, 5:00pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/13 "2024-04-18T17:00:55Z")

</div>

The message is telling you that you need to use the name of the segmentation. The first line of the script may need to be changed to say “Segmentation\_1” or whatever the object in your scene is called.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 19, 2024, 8:38am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/14 "2024-04-19T08:38:41Z")

</div>

In fact, that was the mistake. I corrected the code but now I get the same error as before.

> “Slicer has caught an application error, please save your work and restart.\n\nIf you have a repeatable sequence of steps that causes this message, please report the issue following instructions available at [https://slicer.org](https://slicer.org)\n\n\nThe message detail is:\n\nException thrown in event: D:\D\S\S-0-build\ITK\Modules\Segmentation\ConnectedComponents\include\itkConnectedComponentImageFilter.hxx:144:\nITK ERROR: ConnectedComponentImageFilter(0000020DD9CDF300): Number of objects (836) greater than maximum of output pixel type (255).”

With both .vtk and .nrrd volumes.

I have tried to use the “Cast Scalar Volume” module but the list of input volumes is empty even though I have loaded more than one volume with different formats.

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/7/d74b80f8f684d1d7e7d068714f7187e658b350b1.png)

Do I need to do any steps beforehand?

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 19, 2024, 2:18pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/15 "2024-04-19T14:18:39Z")

</div>

The volume was not shown by Cast Scalar Volume because it had not been converted to scalar volume. I converted the volume with the Vector to Scalar Volume module and then used the Cast Scalar Volume module and tried to convert the volume to Int and to Float.  
I got the same error as before with both output types.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 19, 2024, 2:37pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/16 "2024-04-19T14:37:05Z")

</div>

Looking closer, I see this line `segmentationNode.GetBinaryLabelmapRepresentation(segmentID, image) ` is giving you the smallest datatype that can represent the number of input segments.

So you need to add this to the code after getting `image` from the `segmentationNode`:

```auto
cast = vtk.vtkImageCast()
cast.SetOutputScalarTypeToInt()
cast.SetInputData(image)
cast.Update()
# to confirm
print(cast.GetOutputDataObject(0).GetScalarTypeAsString())

```

And then put `image` through `vtkITKIslandMath`.

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 19, 2024, 4:47pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/17 "2024-04-19T16:47:20Z")

</div>

This is the code I got now but I still get the same error.

```auto
segmentationNode = getNode('Segmentation')
segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName("Nuclei")

# Get segment binary labelmap representation as vtkOrientedImageData
image = slicer.vtkOrientedImageData()
segmentationNode.GetBinaryLabelmapRepresentation(segmentID, image)

# cast vtk.vtkImageCast
cast = vtk.vtkImageCast()
cast.SetOutputScalarTypeToInt()
cast.SetInputData(image)
cast.Update()
# to confirm
print(cast.GetOutputDataObject(0).GetScalarTypeAsString())

# Get number of islands
import vtkITK
islands = vtkITK.vtkITKIslandMath()
islands.SetInputData(image)
islands.SetMinimumSize(10)
islands.Update()
print(f"Found {islands.GetNumberOfIslands()} islands")

```

However, the part of the code you suggest to add works and prints “int” at the end of the code and before the error.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [April 19, 2024, 4:49pm UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/18 "2024-04-19T16:49:00Z")

</div>

You need to also change `islands.SetInputData(image)` to `islands.SetInputData(cast.GetOutputDataObject(0))`

---

<div class="post-metadata">

**Author:** ![FraP](https://avatars.discourse-cdn.com/v4/letter/f/e68b1a/32.png) [@FraP](https://discourse.slicer.org/u/FraP)\
**Post date:** [April 22, 2024, 10:15am UTC](https://discourse.slicer.org/t/counting-the-number-of-segments/32251/19 "2024-04-22T10:15:49Z")

</div>

> [@pieper](#):
>
> vtkITKIslandMath

Thank you!!!  
Now it’s working perfectly 😄
