How to overlay more than two volumes

Operating system: Windows 10
Slicer version: 4.10.1

I am wondering if there is a way to overlay more than just two volumes. I know we can overlay two by setting them to foreground and background, but is there a way to add more layers? Reason being, I am using Slicer to look at 2D cell images, where each image highlights different proteins in the cell.

Expected behavior:

The above is 3 images overlaid together, which is what I would like to be able to do. (This image was created in a different program)

Actual behavior:

The above image is from Slicer with only 2 images overlaid.

This is not currently supported (the two-layer limitation is pretty hard coded right now). But it is something we would like to support for multi-channel use cases like you describe.

@pieper do you envision changing the slice view pipeline or just adding a module that can create an RGB volume from a vector volume?

@sthirumal You can create a colored image by combining any number of volumes into a single volume using custom rules by writing a couple of lines of Python code. See this example for combining two volumes into a third volume: Creating Volume from Numpy. You can modify it to create a colored volume by creating a new vector volume instead of cloning the input scalar volume.

I don’t have a specific implementation in mind - I hope to learn more about the specific needs before forming a plan.

@blowekamp walked me through some use cases at Project Week and my current general thought is that we could have a version/variant of the Vector To Scalar module that allows you to assign primary colors to different channels of an input volume and then display it as a RGB image. Or maybe a scalar volume with the channels mapped to different numerical ranges with a custom color lookup. Another possibility would be custom node and display node types.

I’m not sure which approach would be best for segmentation, quantification, etc.

Of course a lot of this microscopy data is also large, so we need to also think about handling that aspect of things.

For the labeled microscopy case, you will generally have an image with many channels, or multiple images with channels. It is good to be able to assign each channel or molecular “marker” a string label and a color, then select which channels to visualize.

This is a rough block of SimpleITK code to do some of the work in a command line utility:

        # matplotlib named colors: https://matplotlib.org/3.1.0/gallery/color/named_colors.html
        color_list = ["red", "green", "blue", "cyan", "magenta", "yellow"]
        if len(image_list) == 3:
            color_list = ["cyan", "magenta", "yellow"]

        rescale = False
        out = None
        for img, marker, color_name in zip(image_list, marker_list, cycle(color_list)):

            color = mcolors.get_named_colors_mapping()[color_name]
            rgb_color = mcolors.to_rgb(color)

            print("Colorizing {0} with {1} [{2}]...".format(marker, color_name, rgb_color))
            img = sitk.Cast(img, sitk.sitkFloat32)
            if rescale:
                img = sitk.RescaleIntensity(img, outputMaximum=255)

            img = sitk.Compose([c * img for c in rgb_color])

            if out is None:
                out = img
            else:
                out += img

        del image_list
        out = sitk.Clamp(out, sitk.sitkVectorUInt8, 0, 255)
1 Like