Call ImageStacks tool in a Python script

Hi everyone,

I am starting using 3D Slicer and I learnt how to load large image stack as 3D volume thanks to the ImageStacks tool provided by the SlicerMorph extension, following the Youtube tutorial.

I was wondering if it is possible there is an ImageStacks function that would load the image stack from a Python script, something similar to:

loadedVolumeNode = slicer.util.loadVolume('c:/Users/abc/Documents/SomeImage/file001.png', {'singleFile': False})

But using the ImageStack module.

Thanks for your help!

Gabriele

1 Like

I solved it. As lassoan already mentioned in this answer, you need MRML and module logic classes to interact with any other module (find more in these slides).

After looking at ImageStack code, I ended up with the following script:

# filename is the first image path of the stack, eg "/opt/data/image-0001.tif"
filename = "/opt/data/image-0001.tif"

# Set "ImageStacks" as currently active module.
slicer.util.selectModule("ImageStacks")
# Python scripted modules
moduleWidget = slicer.modules.imagestacks.widgetRepresentation().self()

# load image stack
# User selects a file like "/opt/data/image-0001.tif"
moduleWidget.archetypeText.text = filename

# The populateFromArchetype method will populate the file list with all files 
# that match the numbering pattern in that directory
moduleWidget.populateFromArchetype()
# to check correct file loading
# print(moduleWidget.logic.filePaths)

# Instantiate and add a VolumeNode to the scene.
masterVolumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", "microCT_scan")

# Load the files in paths to outputNode.
moduleWidget.logic.loadVolume(outputNode = masterVolumeNode)
3 Likes

Thanks for sharing. You can further simplify this by not instantiating a widget class but creating and using the logic class directly:

import ImageStacks
logic = ImageStacks.ImageStacksLogic()
logic.reverseSliceOrder = ...
logic.sliceSkip = ...
...
outputVolume = logic.loadVolume(None)
2 Likes

Dear lassoan
Thank you so much for sharing this information.
I had a question as I followed your instruction.
I had been getting ‘NoneType’ object has no attribute ‘shape’ error and I couldn’t figure out how to solve the problem.
I tried adding a scalar volume node before loading the volume but it still did not worked.
Could you please give me some advice?
Thank you always for your help.

Below is the code I used

file_dir = r"E:\CT_RAW\20211221\901377\901377_Rec\901377__rec00000028.bmp"
bmp_file = []
bmp_file.append(file_dir)

import ImageStacks
logic = ImageStacks.ImageStacksLogic()
logic.filePaths = bmp_file
logic.originalVolumeRecommendedSpacing = [0.006999972, 0.006999972, 0.006999972]
logic.outputQuality = ‘preview’
outputVolume = logic.loadVolume(None)

This is the message I have been getting.

Traceback (most recent call last):
File “”, line 1, in
File “C:/Users/njy95/AppData/Local/NA-MIC/Slicer 4.13.0-2022-02-25/NA-MIC/Extensions-30657/SlicerMorph/lib/Slicer-4.13/qt-scripted-modules/ImageStacks.py”, line 680, in loadVolume
if len(volumeArray.shape) == 3:
AttributeError: ‘NoneType’ object has no attribute ‘shape’

@hourglassnam when you get an error like that you need to trace through the code to identify where your use doesn’t match the expectations. In this case you can find the source code based on the information in the error message. You can also edit your local copy to add print statements and then restart Slicer to figure out why your data doesn’t load. If you are writing python scripts this is an important skill to develop.

1 Like