Running a Python script for smoothing segmentation from the terminal

Hello,

I have the following script that smooths a binary segmentation using the Joint Taubin method from slicer. Suppose this script is saved at smoothing.py, I am calling it with this command: path/to/slicer --no-splash --python-script smoothing.py -mask path/to/mask -volume path/to/volume -output path/to/output. This will open the slicer software and does the job properly.

However, ideally I want to run it without opening the slicer window. I tried adding the --no-main-window flag, but then it simply does not do the smoothing and no output is generated. I’m wondering if any of the functions I am using in this script requires the slicer main window to be open to work? Help will be very much appreciated!

import slicer
import argparse

def smooth_mask(mask_path, volume_path, output_path):
    slicer.util.showStatusMessage("Loading files")
    segmentationNode = slicer.util.loadSegmentation(mask_path)
    masterVolumeNode = slicer.util.loadVolume(volume_path)

    # Create segment editor to get access to effects
    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
    segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
    segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
    segmentEditorWidget.setSegmentationNode(segmentationNode)
    segmentEditorWidget.setSourceVolumeNode(masterVolumeNode)

    # Smoothing
    slicer.util.showStatusMessage("Smoothing LSA PA mask")
    segmentEditorWidget.setActiveEffectByName("Smoothing")
    effect = segmentEditorWidget.activeEffect()
    effect.setParameter("SmoothingMethod", "JOINT_TAUBIN")
    effect.setParameter("JointTaubinSmoothingFactor", 0.5)
    effect.self().onApply()

    # Clean up
    segmentEditorWidget = None
    slicer.mrmlScene.RemoveNode(segmentEditorNode)

    # Export segmentation to a labelmap
    labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
    slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(segmentationNode, labelmapVolumeNode, masterVolumeNode)
    slicer.util.saveNode(labelmapVolumeNode, output_path)
    slicer.util.showStatusMessage("Saved smoothed LSA PA mask")
    return None



if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-mask', help='Path to a binary segmentation mask')
    parser.add_argument('-volume', help='Path to the master volume that the segmentation corresponds to')
    parser.add_argument('-output', help='Path to save output mask')

    args = parser.parse_args()
    smooth_mask(args.mask, args.volume, args.output)

You could make this work by avoiding using the module widget so you don’t need the main window, but a simple workaround could be to add this to your script:

slicer.util.mainWindow().showMinimized()

Sorry for my late reply. I added the suggested line of code to the beginning of the smooth_mask function, but it did not actually prevent the window of slicer from popping up. Nothing seemed to change. I was running the script on a mac machine. Do you know by any chance how I may fix this?

You may need to call slicer.app.processEvents() if you are running from a script that never uses the GUI.

Yes, I am actually just running the script from terminal. May I ask where in the script should this line of code be called?

Try calling it after calling the showMinimized() method.

That successfully suppressed the main window of slicer. Thank you! The only problem remaining was that it couldn’t stop the pop-up window when loading the files like this one below. Do you know any quick fix for this as well? If not, it is completely fine as well.

No, I think that one is hard coded.

1 Like