Display two 2D images simultaneously

Hello,
I would like to display two 2D images at the same time in the Slicer window. For example, show image1 in the red slice and image2 in the yellow slice.
What would be the syntax of the code that would allow me to do this from a scripted module?
Thanks,
Rohan

There are some great examples here in the Slicer script repository for this use case https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Show_a_volume_in_slice_views

1 Like

Thank you James.
I’m trying this out with an example numpy array because I will have to start out with numpy array. Unfortunately, I’m still confused about how to go from this part:

img = np.zeros((50,50))
img[10:40,20:30] = 1
imgvect = img.ravel()
vtk_data_array = numpy_support.numpy_to_vtk(num_array=imgvect, array_type=vtk.VTK_FLOAT)
img_vtk = vtk.vtkImageData()
img_vtk.SetDimensions(img.shape[0],img.shape[1],1)
inputVolume.SetAndObserveImageData(img_vtk)

to this part:

slicer.app.layoutManager().sliceWidget('Red').sliceLogic().GetSliceCompositeNode().SetForegroundVolumeID(n.getID())

I’m not sure what I put in place of n.getID() or what data type conversions are needed.
Thanks,
Rohan

Using your numpy array you can update a volume node with that array using updateVolumeFromArray which can be found at https://github.com/Slicer/Slicer/blob/bd90449b32d23551133d954824f629e79aab0989/Base/Python/slicer/util.py#L1288-L1294

new_volume_node = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode")
slicer.util.updateVolumeFromArray(new_volume_node, my_numpy_array)
slicer.app.layoutManager().sliceWidget('Red').sliceLogic().GetSliceCompositeNode().SetForegroundVolumeID(new_volume_node.GetID())  # setvolume node as the foreground volume of the Red slice widget.
2 Likes

Thanks again, the 3 lines of code above solved my problem.

Hi,
I have another follow-up about this.
This method of displaying different images in red and yellow slices doesn’t seem to work if I’ve already done something like this earlier:

slicer.util.setSliceViewerLayers(background=self.inputSelector.currentNodeID)

In this case, self.inputSelector.currentNodeID remains in view even after I’ve done this:

slicer.app.layoutManager().sliceWidget('Red').sliceLogic().GetSliceCompositeNode().SetForegroundVolumeID(n.getID())

How do I get around this issue?

slicer.util.setSliceViewerLayers only changes views that are currently displayed. It is a convenience method only, so if you need a different behavior then you can go one level lower (accessing view widgets, as you do it in your second example). Also note that there is a difference between setting foreground and background volumes.