Multichannel images

Prerequisites

Before starting this lesson, you should be familiar with:

Learning Objectives

After completing this lesson, learners should be able to:
  • Understand/visualize different image channels.

Motivation

Multichannel imaging typically involves using a fluorescence microscope equipped with multiple filter sets or detectors, each specific to a particular fluorophore’s emission wavelength (Note that this differs from images acquired with color cameras e.g. histological stains)

Concept map

graph TD F("Multichannel image") F --> C1("Channel 1") F --> C2("Channel 2") F --> CA(". . . .") F --> CN("Channel n")



Figure


Multichannel image. Left - Scheme of array organization for a multichannel image. Center - Example of three 2D (XY) images shown with grey look up table. Right - All 3 channels overlaid to display a composite image using Cyan, Magenta, and Yellow look up tables, respectively. Note that the array shape of (X,Y,C) is just an example. The position of the channel dimension may differ depending on the data and the reader.



Color combinations for multi channel images

General recommendationas

The choice of lookup tables to display a merged multi-channel image should fulfill:

  • Distinct color separation so to maximize the visual separation between channels.
  • Avoidance of problematic color combinations that can’t be distinguished with color vision deficiency (e.g. red/green)
  • If unsure test color combinations using a “color-blind mode”. For example in ImageJ Image > Color > Simulate Color Blindness
  • If possible show the single channels next to the merged channel for better clarity

Suggested color combinations

  • Two channels:For example Green/Magenta, Blue/Yellow, Red/Cyan, Blue/Red
  • Three channels: For example Magenta/Green/Blue, Megenta/Yellow/Cyan, Red/Cyan/Yellow
  • More than three channels: Displaying the merged image with enough contrast is challenging. It depends on the structures that have been stained and how much they overlap. Different color combinations should be tried out. One possibiility is Magenta/Green/Yellow/Cyan, or a grayscale LUT for one or more of the reference (less important) channels.



Activities

Display a multichannel image


Show activity for:  

ImageJ GUI

  • Open a sample multichannel image
  • Use the slider bar under the image to select the channel to be processed/analyzed
  • The number of bar positions are equal to the number of channels
    • Note: The color of the subtitle changes when you switch to a different channel
  • Open the Channels tool using Image > Color > Channels Tool or by pressing shift-z to select/deselect channels to display
  • Use the B & C tool using Image > Adjust > Brightness/Contrast or press shift-c to adjust the brightness and contrast of the current channel. Note: The slider bar decides your active channel for changing brightness and contrast settings
  • Try changing the channel color by selecting a LUT from the Image > Lookup Tables menu. Try different modes of blending e.g. Composite invert

skimage napari

# %%
# Display a multichannel image

# %%
# import modules
import napari
import numpy as np
from skimage import filters
from skimage.filters import rank
from skimage.morphology import disk # Structuring element
from OpenIJTIFF import open_ij_tiff

# %%
# Instantiate the napari viewer
viewer = napari.Viewer()

# %%
# Read and view the image
image, ax_names, ax_scales, ax_units = open_ij_tiff('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyc_16bit__cell_dna_mts_actin.tif')

# %%
# Note that channel dimension is a slider 
# If you try to adjust range it behaves like a 3D stack
viewer.add_image(image)

# %%
# The channel dimension is the 0th
print(ax_names)

# %%
viewer.layers.clear()
ch_axis = 0
ch_names = ['DNA', 'MTS', 'ACTIN']
viewer.add_image(image, channel_axis = ch_axis, name = ch_names)
# Now the channels render correctly 

# %%
# play with contrast and brightness sliders and find ranges that matches for your eyes
# play with colormap/LUT and find settings that you like
viewer.layers.clear()
viewer.add_image(image, channel_axis = ch_axis, name = ch_names, contrast_limits=
    [[105, 450], [100, 500], [100,5000]], # contrast limits for each channel
    colormap = ['blue', 'green', 'magenta'], # colormaps for each channel
    blending = ['translucent_no_depth', 'additive', 'additive'] # blending mode
)
# %%
# Try an inverted colormap and use minimum blending 
viewer.layers.clear()
viewer.add_image(image, channel_axis = 0, name = ch_names, contrast_limits=
    [[105, 450], [100, 500], [100,5000]], # contrast limits for each channel
    colormap = ['I Forest', 'I Purple','I Blue'], # colormaps for each channel
    blending = ['translucent_no_depth', 'minimum', 'minimum'] # blending mode
)

# %% 
# Close the viewer (CI test requires this)
viewer.close()

Galaxy Napari

  • This activity requires registration!
  • Navigate to Galaxy
  • In the Tools panel on the left, click Upload Data.
  • Click the Paste/Fetch data button.
  • Paste the image URL https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyc_16bit__cell_dna_mts_actin.tif and click the Start button.
  • After the upload finishes, click the Close button. The image will then be available in your Galaxy history.
  • Start the Napari Interactive Tool
  • In the Tools panel on the left, search for Run Napari interactive tool.
  • Select xyc_16bit__cell_dna_mts_actin.tif from the Images dropdown list.
  • Click the Run Tool button.
  • Once the Open link once it appears at the top of the page, click it. This will open Napari in a separate browser tab.
  • In the Napari tab, select File -> Open File(s), and choose the image xyc_16bit__cell_dna_mts_actin.tif from the “input” folder. The image will be displayed in Napari’s main window.
  • In the layer pane located at the bottom left, right-click the image and select Split RGB.
  • Experiment with adjusting the contrast of each channel.



Save a multichannel image


Show activity for:  

ImageJ GUI

  • Open a sample multichannel image
  • Use the channel tools Image > Color > Channel Tools and set use following settings
    • Note: Composite: [x] - Channel 1, [x] Channel 2, [x] Channel 3
  • Check the image data type using Image > Type. It is 16-bit. Convert it into RGB by selecting Image > Type > RGB Color. This will create a second image with the title xyc_16bit__cell_dna_mts_actin.tif (RGB).
  • Use File > Save As > Tiff to save as a 8-bit RGB TIFF. This image can be loaded for example into a presentation.
  • Next we create an image montage of all single channels (gray) and the composite RGB image.
  • Go to the original image xyc_16bit__cell_dna_mts_actin.tif or reopen it if needed.
  • Use the Image > Color > Channel Tools and change from Composite to Grayscale
  • Make a montage with Image > Stack > Make Montage ... and following parameters: Columns = 3, Rows = 1, scale factor = 1. Note that the montage is transformed to a RGB.
  • Combine the two RGB images, single channel montage and merged color image respectively, to a final image, Image > Stacks > Tools > Combine.
  • Add a scale bar ` Analyze › Tools › Scale Bar…`
  • Use File > Save As > Tiff to save as a TIFF.

ImageJ Macro

// Load a multi channel image and save composite images
run("Close All");
open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyc_16bit__cell_dna_mts_actin.tif");
rename("input");
Stack.setChannel(1);
setMinAndMax(143, 500);

Stack.setChannel(2);
setMinAndMax(100, 509);

Stack.setChannel(3);
setMinAndMax(100, 5055);

//  Image › Type › RGB Color
run("RGB Color");
rename("rgb");
// Eventually save the image
//saveAs("Tiff", "/your_path/rgb.tif");

// Show grayscale 
selectImage("input")
Property.set("CompositeProjection", "null");
Stack.setDisplayMode("grayscale");

// Image › Stacks › Make Montage...
run("Make Montage...", "columns=3 rows=1 scale=1");
rename("Montage");

//  Image › Stacks › Tools  › Combine...
run("Combine...", "stack1=Montage stack2=rgb");
rename("montage_rgb");

// Add a scale bar
run("Scale Bar...", "width=10 height=10 horizontal bold hide");
// Eventually save the image
//saveAs("Tiff", "/your_path/montage_rgb.tif");

skimage napari

# %%
# Save a multichannel image

# %%
# Initial imports
import numpy as np
from skimage import filters
from skimage.filters import rank
from skimage.morphology import disk # Structuring element
from OpenIJTIFF import open_ij_tiff
import napari
# %%
# Instantiate the napari viewer
viewer = napari.Viewer()

# %%
# Load the image and check axis names
image, ax_names, ax_scales, ax_units = open_ij_tiff('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyc_16bit__cell_dna_mts_actin.tif')
print(f"axis names {ax_names}")

# %%
# Display the image
viewer.layers.clear()
ch_axis = 0
ch_names = ['DNA', 'MTS', 'ACTIN']
viewer.layers.clear()
viewer.add_image(image, channel_axis = ch_axis, name = ch_names, contrast_limits=
    [[105, 450], [100, 500], [100,5000]], # contrast limits for each channel
    colormap = ['blue', 'green', 'magenta'], # colormaps for each channel
    blending = ['translucent_no_depth', 'additive', 'additive'] # blending mode
)

viewer.grid.enabled = False # Make sure we are not in grid mode

# %%
# Export image composite image
export_path = './' # Change it as needed
composite = viewer.export_figure(export_path + 'composite.png', scale_factor = 1) # 1 ~ full dimension of image


# %%
# Shape checks
print(f'original image shape {image.shape} type {image.dtype}') 
print(f'composite image shape {composite.shape} type {composite.dtype}') 
# Note the change of dimension order and type
# The image we save is a RGB image 
# The XYC, where the channels are Red, Green, Blue and Transparency


# %%
# Advanced 
# Create a montage with the 3 channels and the composite
viewer.layers.clear()
viewer.layers.clear()
viewer.add_image(image, channel_axis = ch_axis, name = ch_names, contrast_limits=
    [[105, 450], [100, 500], [100,5000]], # contrast limits for each channel
    colormap = ['gray', 'gray', 'gray'], # colormaps for each channel
    blending = ['translucent_no_depth', 'translucent_no_depth', 'translucent_no_depth'] # blending mode
)
viewer.add_image(composite)
viewer.grid.enabled = True
viewer.grid.stride = -1 # ensure order of images Ch1, Ch2, Ch3
viewer.grid.shape = (1,4)
viewer.reset_view()


# %%
# Export the image
composite_montage = viewer.export_figure(export_path + 'composite_montage.png', scale_factor = 1) 
print(composite_montage.shape)
# Obtained shape is (350,350,4)
# Expected shape should be ~ (350*4, 350, 4)
# Note that as for version Napari 0.5.6 the output size as the same XY shape as the original image. 
# This is a bug and should hopefuly be fixed


# %%
# Alternative make a montage using matplotlib
import matplotlib.pyplot as plt
nC = image.shape[0] #  number of channels
# Create a 1xchannels + 1  grid of subplots
fig, axes = plt.subplots(1, image.shape[0] + 1 , figsize=(12, 3)) # Adjust figsize for better aspect ratio
axes = axes.ravel()  # Flatten the 1x4 array of axes

# Display the grayscale images
for iC in range(image.shape[0]):
    axes[iC].imshow(image[iC,:,:], cmap='gray' )
    #axes[iC].imshow(image[iC,:,:], cmap='gray', vmin = 100,vmax = 500) # You can also adjust the contrast
    axes[iC].set_title(ch_names[iC])
    axes[iC].axis('off')

# Display the RGB image
axes[nC].imshow(composite)
axes[nC].set_title('Merge')
axes[nC].axis('off')

# Adjust layout
plt.subplots_adjust(wspace=0.01, hspace=0.1)
# save data
plt.savefig(export_path + 'montage_plt.png', format = 'png', bbox_inches='tight', pad_inches=0)
# show the montage
plt.show()


# %% 
# Close the viewer (CI test requires this)
viewer.close()
plt.close('all')






Assessment

True of false?

  1. In a multichannel image, each channel is an image that represents different data/stains
  2. There is no restriction in the choice of color for a merged image

Solution

  1. True
  2. False. Some color combinations may not be perceived as different colors by persons with color vision deficiency

Discuss with your neighbor

  1. How can multichannel images be used to improve machine learning models for image/object classification?
  2. Is RGB image always a 3-dimensional image?
  3. What is a potential challenge when analyzing multichannel images?

Solution

  1. By providing additional context and information that can be leveraged by the model
  2. Yes. In fact some software use 4 dimensions where the 4th dimension is transparency. If all channels are identical the image may render as a gray scale image.
  3. Crosstalk or bleed-through between channels. This typically should be corrected




Follow-up material

Recommended follow-up modules:

Learn more: