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:
Set threshold values (e.g., lower and upper bounds).
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 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 ‘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.
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.
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