How to Integrate Threshold Effect from Segment Editor into a Custom Module

Hi everyone,

I am currently working on a custom module in 3D Slicer and would like to incorporate the functionality of the “Threshold” effect from the Segment Editor module.

My main goal is to allow users to:

  1. Set threshold values (e.g., lower and upper bounds).
  2. Preview the thresholded region in real-time on a specific image.

I’ve been trying to achieve this for some time now, but I haven’t been able to figure it out. I don’t need the full functionality of the Segment Editor, just these two features.

Could anyone guide me on how to accomplish this? Are there any Python examples or specific API calls I should look into?

Thank you in advance for your help!

You may get some inspiration from this module.

Thank you for your response! It helped me a lot. Do you happen to have any modules that implement the Flood Filling effect and Keep Selected Island (from the Islands operation) that I could take inspiration from? It would be great to see how others have approached this topic.

For flood filling: 1, 2.

For ‘Keep selected island’: no known reference. The module I linked in my previous post uses KEEP_LARGEST_ISLAND; if you use KEEP_SELECTED_ISLAND, it should do the trick.

I’m unsure how to properly capture the click event and translate it into a flood-filling operation. Could someone guide me on how to:

  1. Detect a user click in the Slice View.
  2. Retrieve the voxel coordinates of the clicked point.
  3. Apply a flood-filling operation (e.g., using ITK or other available methods).

If there are any examples or similar implementations, I would greatly appreciate any references or advice.

But the ‘Flood filling’ effect already does that. Your goal is not very clear. If you don’t plan to use the ‘Segment editor’, you’ll have to rewrite much code, a lot of work to achieve robustness and efficiency.

My plan is to use ‘Segment editor’ but I don`t know how to write the code to let my module use ‘Flood filling’

To be more precise I want to chose values of ‘Intensity tolerance’ and ‘Neighborhood size’ from widget of my module and then click button in the widget to get ‘Flood filling’ efect from ‘Segment editor’ with those values. I have created something like this for widget:

Flood filling parameters

    floodFillingCollapsibleButton = ctk.ctkCollapsibleButton()
    floodFillingCollapsibleButton.text = "Flood Filling"
    self.layout.addWidget(floodFillingCollapsibleButton)

    floodFillingFormLayout = qt.QFormLayout(floodFillingCollapsibleButton)

    # Intensity tolerance for flood filling
    self.intensityToleranceSlider = ctk.ctkSliderWidget()
    self.intensityToleranceSlider.minimum = 0
    self.intensityToleranceSlider.maximum = 200  # Adjust based on your data
    self.intensityToleranceSlider.value = 80  # Default value
    self.intensityToleranceSlider.setToolTip("Set the intensity tolerance for flood filling.")
    floodFillingFormLayout.addRow("Intensity Tolerance:", self.intensityToleranceSlider)

    # Neighborhood size for flood filling
    self.neighborhoodSizeSlider = ctk.ctkSliderWidget()
    self.neighborhoodSizeSlider.minimum = 0
    self.neighborhoodSizeSlider.maximum = 10  # Adjust based on your data
    self.neighborhoodSizeSlider.value = 2  # Default value
    self.neighborhoodSizeSlider.setToolTip("Set the neighborhood size for flood filling.")
    floodFillingFormLayout.addRow("Neighborhood Size (mm):", self.neighborhoodSizeSlider)

    # Flood filling button
    self.floodFillButton = qt.QPushButton("Apply Flood Fill")
    self.floodFillButton.toolTip = "Apply flood filling."
    self.floodFillButton.enabled = True
    floodFillingFormLayout.addRow(self.floodFillButton)

    # Connect the Flood Fill button to logic
    self.floodFillButton.connect("clicked(bool)", self.onFloodFillButton)

And this for calling the efect:

#Flood filling
def applyFloodFill(self, inputVolume, intensityTolerance, neighborhoodSize):
if not self.segmentationNode:
print(“No segmentation node found! Please apply thresholding first.”)
return

    if not self.currentSegmentID:
        print("No segment selected! Please create a new segment first.")
        return

    # Get the Segment Editor widget
    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

    if not self.segmentEditorNode:
        self.segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
    segmentEditorWidget.setMRMLSegmentEditorNode(self.segmentEditorNode)
    segmentEditorWidget.setSegmentationNode(self.segmentationNode)
    segmentEditorWidget.setMasterVolumeNode(inputVolume)

    # Set the active effect to "Flood Filling"
    segmentEditorWidget.setActiveEffectByName("Flood filling")
    effect = segmentEditorWidget.activeEffect()

    if not effect:
        print("Failed to activate Flood Filling effect!")
        return

    # Set the parameters for the "Flood Filling" effect
    effect.setParameter("IntensityTolerance", str(intensityTolerance))
    effect.setParameter("NeighborhoodSizeMm", str(neighborhoodSize))

    # Apply the effect to the current segment
    segmentEditorWidget.setCurrentSegmentID(self.currentSegmentID)
    effect.self().onApply()

    print("Applied flood filling to the selected segment.")

But it is not working. That’s why I wanted to ask for some advice or what I should change to trigger the ‘Flood filling’ effect in the right way

See here to apply the effect.