# Help with Blood Vessel Segmentation Module for My Engineering Thesis

**URL:** <https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388>\
**Category:** Development\
**Created:** [November 26, 2024, 6:12pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388 "2024-11-26T18:12:56Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![igi133](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/igi133/32/78666_2.png) [@igi133](https://discourse.slicer.org/u/igi133)\
**Post date:** [November 26, 2024, 6:12pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/1 "2024-11-26T18:12:56Z")

</div>

Hello everyone,

I am currently working on my engineering thesis and I am developing a module for 3D Slicer that aims to detect and segment blood vessels from CT scan images. This module will be part of my research project, and my goal is to automate the process of extracting vascular structures from medical imaging data.

At the moment, I am in the early stages of the project, and I have written some code that allows me to segment the blood vessels from CT images. I would greatly appreciate any feedback or suggestions regarding my approach.

Below is the code I have written so far. If anyone has experience with blood vessel segmentation or working with medical image data in 3D Slicer, your help in reviewing and improving this code would be invaluable.

```python
# Retrieve the volume node
volumeNode = slicer.util.getNode("CTChest") # Replace with your volume node's actual name

if not volumeNode:
    raise ValueError("Volume node 'CTChest' not found. Check the name and ensure it's loaded into the scene.")

# Create a new segmentation node
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # Ensure display nodes are initialized

# Initialize the Segment Editor
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorWidget.setSegmentationNode(segmentationNode)

# Explicitly set the Master Volume Node
segmentEditorWidget.setMasterVolumeNode(volumeNode)

# Debugging: Ensure the Master Volume Node is set correctly
if not segmentEditorWidget.masterVolumeNode():
    raise RuntimeError("Master volume node is not set correctly in the Segment Editor Widget.")

# Activate the Threshold effect
segmentEditorWidget.setActiveEffectByName("Threshold")
effect = segmentEditorWidget.activeEffect()

if effect:
    print("Threshold effect activated successfully!")
    # Set threshold values
    effect.setParameter("MinimumThreshold", "100") # Replace with your desired lower threshold
    effect.setParameter("MaximumThreshold", "300") # Replace with your desired upper threshold
    effect.self().onApply() # Apply the threshold effect
    print("Threshold segmentation applied successfully.")
else:
    raise RuntimeError("Failed to activate the Threshold effect. Check Slicer configuration and plugins.")

# Optional: Smooth the segmentation to refine it
segmentEditorWidget.setActiveEffectByName("Smoothing")
effect = segmentEditorWidget.activeEffect()

if effect:
    effect.setParameter("SmoothingMethod", "Gaussian")
    effect.setParameter("KernelSizeMm", "1.5")
    effect.self().onApply()
    print("Smoothing applied successfully.")
else:
    print("Smoothing effect could not be activated.")

# Finalize (clean up resources)
segmentEditorWidget = None

```

Thank you in advance for any help you can provide!

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 26, 2024, 8:24pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/2 "2024-11-26T20:24:02Z")

</div>

The qMRMLSegmentEditorWidget needs a vtkMRMLSegmentEditorNode.

An effet needs a segment that you must create _and_ select. Identify the added lines below.

```auto
# Initialize the Segment Editor
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
mrmlSegmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(mrmlSegmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)

# Explicitly set the Master Volume Node
segmentEditorWidget.setMasterVolumeNode(volumeNode)

# Debugging: Ensure the Master Volume Node is set correctly
if not segmentEditorWidget.masterVolumeNode():
    raise RuntimeError("Master volume node is not set correctly in the Segment Editor Widget.")

segmentID = segmentationNode.GetSegmentation().AddEmptySegment()
segmentEditorWidget.setCurrentSegmentID(segmentID)

```

Please note that bones have a wide intensity range, that includes the range in the contrast media.

---

<div class="post-metadata">

**Author:** ![igi133](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/igi133/32/78666_2.png) [@igi133](https://discourse.slicer.org/u/igi133)\
**Post date:** [November 27, 2024, 1:08pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/3 "2024-11-27T13:08:09Z")

</div>

Thank you for your feedback!

I really appreciate your suggestions and the time you took to help me with my code. Your insights are very helpful, and I’ll definitely implement your recommendations to improve my approach.

I also have a follow-up question: do you think it’s possible to segment only the blood vessels using the threshold function in 3D Slicer? If not, do you have any ideas or suggestions on alternative methods to achieve this? I’m open to exploring different techniques if thresholding alone isn’t sufficient.

Thank you again for your assistance!

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 27, 2024, 1:31pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/4 "2024-11-27T13:31:02Z")

</div>

> [@igi133](#):
>
> any ideas or suggestions on alternative methods

You may investigate the “Flood filling” effect of the “Segment editor” with high values of “Intensity tolerance”. Other effects allow an efficient segmentation also, but this one is probably the fastest. No segmentation technique is magic, you’ll have to play a lot and a lot to grasp their offerings and limits.

A few modules of the SlicerVMTK installable extension use the “Flood filling” effect, this time on targeted regions that you define.

In all cases, you need good quality CT scans with sufficiently contrasted lumen.

---

<div class="post-metadata">

**Author:** ![igi133](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/igi133/32/78666_2.png) [@igi133](https://discourse.slicer.org/u/igi133)\
**Post date:** [November 27, 2024, 2:52pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/5 "2024-11-27T14:52:48Z")

</div>

To put it simply, the module I want to create looks as follows in my mind. First, a script would perform segmentation of regions containing blood vessels from a specific CT image. Due to the similarity in grayscale values to bone, the module would need to prompt the user to select the regions of interest.

Next, I need my module to calculate values such as the volume and other related parameters of the blood vessels, and then display the obtained results. Do you have any advice that could help me achieve this?

Currently, the segmentation part works, but it also segments parts of the bone. The image I’m using to test my program is from Slicer and is named _CTACArdio_. I would be very grateful for any suggestions you might have.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 27, 2024, 4:37pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/6 "2024-11-27T16:37:35Z")

</div>

> [@igi133](#):
>
> I need my module to calculate values

To do that, you must work on segmented blood vessels and segmented blood vessels only. That’s why you want your users to select regions of interest.

With a volume like CTA-cardio and most real-life volumes, thresholding will give you a lumen that will be attached to bones and soft tissues often. Even the ‘Islands’ segment editor effect won’t be of much help, it many remove some detached parts of the segment, called Islands, but you won’t get just nice blood vessels.

You may still use the ‘Scissors’ effect to cut anything that is not an artery but it’s obviously impractical in this use case.

Consider using the ‘Flood filling’ effect with an “Intensity tolerance” of 90 and a “Neighbourhood size” of 2.0. Just click in the abdominal aorta for example and you will see the difference. Your module can ask the user to do that.

Another option is to crop CTA-cardio to a ROI and threshold in that targeted volume.

---

<div class="post-metadata">

**Author:** ![igi133](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/igi133/32/78666_2.png) [@igi133](https://discourse.slicer.org/u/igi133)\
**Post date:** [November 28, 2024, 4:26pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/7 "2024-11-28T16:26:42Z")

</div>

Can u tell me what is wrong with activing flood filling effect in this script?

# Step 2: Refine with Flood Filling

> > > segmentEditorWidget.setActiveEffectByName(“FloodFilling”)  
> > > effect = segmentEditorWidget.activeEffect()
> > > 
> > > if effect:  
> > > … print(“Flood Filling effect activated successfully!”)  
> > > … # Set flood filling parameters  
> > > … effect.setParameter(“IntensityTolerance”, “90”) # Adjust intensity tolerance  
> > > … effect.setParameter(“NeighborhoodSize”, “2.0”) # Adjust neighborhood size  
> > > … print(“Click on a vessel in the volume to apply the flood filling effect.”)  
> > > … input(“Press Enter after applying flood filling…”) # Wait for user interaction  
> > > … else:  
> > > … raise RuntimeError(“Failed to activate the Flood Filling effect. Check Slicer configuration and plugins.”)

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 28, 2024, 5:05pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/8 "2024-11-28T17:05:32Z")

</div>

> [@igi133](#):
>
> … print(“Click on a

The user must type something or an error will be raised.

> [@igi133](#):
>
> effect.setParameter(“IntensityTolerance”, “90”)

I’m not sure if the values can be passed as string; try with int and float respectively.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 28, 2024, 5:08pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/9 "2024-11-28T17:08:20Z")

</div>

> [@igi133](#):
>
> effect.setParameter(

You could also call

> effect.updateGUIFromMRML()

after setting the parameters.

---

<div class="post-metadata">

**Author:** ![igi133](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/igi133/32/78666_2.png) [@igi133](https://discourse.slicer.org/u/igi133)\
**Post date:** [November 29, 2024, 2:35pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/10 "2024-11-29T14:35:46Z")

</div>

I have changed the code like this but I still have errors, any ideas? # Step 2: Refine with Flood Filling in a new segment

> > > floodFillSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(“FloodFillVessels”)  
> > > segmentEditorWidget.setCurrentSegmentID(floodFillSegmentID)
> > > 
> > > segmentEditorWidget.setActiveEffectByName(“FloodFilling”)  
> > > effect = segmentEditorWidget.activeEffect()
> > > 
> > > if effect:  
> > > … print(“Flood Filling effect activated successfully!”)  
> > > …  
> > > … # Set flood filling parameters with int and float values  
> > > … intensity\_tolerance = 90 # Intensity tolerance as integer  
> > > … neighborhood\_size = 2.0 # Neighborhood size as float  
> > > …  
> > > … effect.setParameter(“IntensityTolerance”, intensity\_tolerance) # Use int for IntensityTolerance  
> > > … effect.setParameter(“NeighborhoodSize”, neighborhood\_size) # Use float for NeighborhoodSize  
> > > …  
> > > … effect.updateGUIFromMRML() # Synchronize GUI with parameters  
> > > … print(“Click on a vessel in the volume to apply the flood filling effect.”)  
> > > …  
> > > … # Pause for user interaction  
> > > … input(“Press Enter after completing the flood filling interaction…”)  
> > > … else:  
> > > … raise RuntimeError(“Failed to activate the Flood Filling effect. Check Slicer configuration and plugins.”)

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [November 29, 2024, 3:13pm UTC](https://discourse.slicer.org/t/help-with-blood-vessel-segmentation-module-for-my-engineering-thesis/40388/11 "2024-11-29T15:13:57Z")

</div>

> [@igi133](#):
>
> any ideas?

Replace “FloodFilling” by “Flood filling”.

Also, ask the user to type something before pressing enter, else an EOL error will be raised. Just after this ‘input’ line, use setActiveEffect(None).

BTW, you seem to be targeting power users since your code should run in the Python console so that they get a chance to press enter. I don’t know what is the design of your research but it should not imply the console. You could add a button in your UI to restore the active effect to None rather. That part is however totally your design and target audience.
