Stack several images along channel dimension to create multichannel images (e.g. 4D volume)

I sometimes need to stack several 2D/3D images/volumes along the channel dimension, create a multichannel image and save it as a 4D Nifti/Nrrd. For simplicity’s sake, you can assume that I already have co-registered the images, and that they are all resampled into the first image’s pixel/voxel grid as reference. Fwiw, I know how to convert the images to numpy arrays and stack them along a channel dimension, but I don’t know how to create a new multichannel volume from that and make sure that it has an identical geometry as in the reference image header.
Thanks for any tips in advance!

You can use sequences for this. If all the volumes in the sequence have the same geometry then they will be saved as a single 4D nrrd file. You can pick one of the channels and display it in the scene by adding a sequence browser node for each. See examples for getting/setting data in sequences in the script repository.

Alternatively, you can store all the channels in a single vector volume. For example, you can create a 6-channel volume with random content like this:

import numpy as np
volumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLVectorVolumeNode')
voxels = np.random.rand(3,4,5,6)
slicer.util.updateVolumeFromArray(volumeNode, voxels)

The disadvantage is that you cannot easily browse the channels but for example you can extract any of them using the “Vector to scalar volume” module (or in Python, using slicer.util.arrayFromVolume()).

1 Like

Hi Andreas,

thanks for the tip. If I use your numpy-based code example…:

…, except that voxels is a stacked 4D array volume [0,1,2,...,N], how would I assign the same reference geometry as e.g. volume0 to the newly-created volumeNode, such that when I save that node as Nifti/Nrrd, it would overlap perfectly with volume0?

You also need set the image geometry, by copying it from the original image: