Volume subsetting and slicing

Prerequisites

Before starting this lesson, you should be familiar with:

Learning Objectives

After completing this lesson, learners should be able to:
  • Slice 3D image stacks

  • Subset a multidimensional image to create a new image that is smaller or has fewer dimensions

Motivation

In some cases, you may only want to focus on a particular part of a multidimensional image, such as a specific time point or region in space. To achieve this, you can subset the image, which means reducing it to fewer dimensions or selecting only certain parts of the existing dimensions. One special way to do this is through slicing: selecting a 2D slice from a 3D volume.

Concept map

graph TD ND("N-dimensional image") --> SS("Subset") SS("Subset") --> SI("Partial N-dimensional image") ND("N-dimensional image") --> S("Slice") S --> M("2D image")



Figure


(Left) Subsetting a 3D volume results in a smaller 3D or 2D image. (Right) Slicing a 3D volume is a form of subsetting that results in a 2D slice.



Activities

Slice different planes of a 3D image


Show activity for:  

ImageJ GUI

  • [File > Open…] xyz_16bit_t1-head.tif
  • [Image > Stacks > Orthogonal views] or press CTRL+SHIFT+H to explore the data in XY, XZ and YZ view.
  • Scroll to z-slice 60 and [Image > Duplicate] to duplicate the image.
    • Duplicate stack
  • Use the line tool to draw a straight vertical line (hold down SHIFT) at X=135 and go to [Image > Stacks > Reslice [/]…] or press / to open the Reslice menu.
    • Rotate 90 degrees (optional)
    • avoid interpolation
  • Use the line tool to draw a straight horizontal line (hold down SHIFT) at Y=160 and go to [Image > Stacks > Reslice [/]…] or press / to open the Reslice menu.
    • Rotate 90 degrees (optional)
    • avoid interpolation
  • Use the line tool to draw a diagonal line from the bottom left to the right top corner and go to [Image > Stacks > Reslice [/]…] or press / to open the Reslice menu.
    • Rotate 90 degrees (optional)
    • avoid interpolation
  • Alternatively, you can also slice the data at arbitrary angles using [Plugins > BigDataViewer > Open Current Image]
    • Shift-X/Y/Z: slice along x,y,z.
    • Left button drag: slice along arbitray plane
    • I: toggle interpolation

ImageJ Macro

// This macro opens the head image stack and reslices it to view it from different angles (side, front, top and diagonal view)
// and then selects slices corresponding to Z=60, X=135, and Y=160.
// Close other open images
run("Close All");

// open head image stack
open("http://imagej.net/images/t1-head.zip");
rename("Head viewed from the side");
run("Duplicate...", "duplicate range=60");
rename("Head Z=60");

// Reslice the head image stack to view the head from the front and from the top, and select the slices for X=135 and Y=160 in the orginal view.
selectWindow("Head viewed from the side");
run("Reslice [/]...", "output=1.500 start=Left rotate"); // view head from the front
rename("Head viewed from the front");
run("Duplicate...", "duplicate range=135-135");
rename("Head X=135");

selectWindow("Head viewed from the side");
run("Reslice [/]...", "output=1.500 start=Top rotate"); // view head from the top
rename("Head viewed from the top");
run("Duplicate...", "duplicate range=160-160");
rename("Head Y=160");

// Rotate the head stack that is viewed from the side and reslice to obtain diagonal view
selectWindow("Head viewed from the side");
run("Duplicate...", "duplicate");
run("Rotate... ", "angle=45 grid=1 interpolation=Bilinear enlarge stack"); // rotate the stack
run("Reslice [/]...", "output=1.500 start=Top rotate");
rename("Head in diagonal view");

run("Tile");

ImageJ Jython

''' This jython script opens the head image stack and reslices it to view it from different angles 
(side, top, front, and diagonal view), and then selects slices corresponding to Z=60, X=135, and Y=160. '''

# import classes
from ij import IJ, ImagePlus

# Close other open images
IJ.run("Close All")

# open head image stack
head = IJ.openImage("http://imagej.net/images/t1-head.zip")
head.show() # shows head from the side
head.setTitle("Head viewed from the side")

# get an image of the slice at Z=60
head_z60 = ImagePlus('head Z=60', head.getImageStack().getProcessor(60))
head_z60.show()

# Reslice the head image stack to view the head from the front
IJ.run(head, "Reslice [/]...", "output=1.500 start=Left rotate") # view head from the front
head_front = IJ.getImage()
head_front.setTitle("Head viewed from the front")

# get an image of the slice at original X=135
head_x135 = ImagePlus('head X=135', head_front.getImageStack().getProcessor(135))
head_x135.show()

# Reslice the head image stack to view the head from the top and from the side
IJ.run(head, "Reslice [/]...", "output=1.500 start=Top rotate") # view head from the top
head_top = IJ.getImage()
head_top.setTitle("Head viewed from the top")

# get an image of the slice at original Y=160
head_y160 = ImagePlus('head Y=160', head_top.getImageStack().getProcessor(160))
head_y160.show()

# Rotate the head stack by 45 degrees and reslice to obtain a diagonal slice
head_diagonal = head.duplicate()
IJ.run(head_diagonal, "Rotate... ", "angle=45 grid=1 interpolation=None enlarge stack") # rotate the stack
IJ.run(head_diagonal, "Reslice [/]...", "output=1.500 start=Top rotate")
head_diagonal = IJ.getImage()
head_diagonal.setTitle("Head in diagonal view")
head_diagonal.show()
head_diagonal = ImagePlus('head diagonal slice', head_diagonal.getImageStack().getProcessor(170))
head_diagonal.show()
IJ.run("Tile")



Subset a 3D image


Show activity for:  

ImageJ GUI

  • Open the 3D multi-channel image xyzc_8bit_spheres.tif.
    • Use the sliders to explore different dimensions in the data.
    • Explore the voxel dimensions, using [ Image > Properties… ] or [Ctrl-Shift-P].
      • Observe that the voxel dimensions are anisotropic.
    • Crop out the green sphere (i.e. “subset” the data).
      • Select the rectangular selection tool and draw an ROI around the green sphere.
      • Duplicate the selection, using [ Image > Duplicate ] or [Ctrl-Shift-D].
        • Duplicate hyperstack
        • Channels: 2
        • Slices: 3-11
      • Draw a vertical line along the sphere and create a YZ slice with and without interpolation:
        • [ Image > Stacks > Reslice] or press / to open the reslice menu.
          • Output spacing: 2.000 um
          • Select Top
          • Rotate 90 degrees
          • avoid interpolation
          • Click OK.
        • [ Image > Stacks > Reslice] or press / to open the reslice menu.
          • Select Top
          • Rotate 90 degrees
          • avoid interpolation
          • Click OK.

Further explanation

Since the voxels dimensions are anisotropic in this data set, reslicing it would yield rectangular pixels. However, on your screen pixels always appear as squares. Therefore there are two options:

  • new pixels are added by interpolation to keep the proportions such that they follow the calibration of the image (you can witness the effect in the black square in the green sphere).
  • no pixels are added by interpolation, but we keep in mind that the voxel size is larger in one dimension than in the other (this is stored in the calibration metadata). In the green sphere slice, you will see that the black square is a rectangle in the YZ view.

ImageJ Macro

// Close other open images
run("Close All");

// open image
openImage("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyzc_8bit_spheres.tif")

// crop out the green sphere
makeRectangle(23,7,18,18);
run("Duplicate...", "duplicate channels=2 slices=3-11");
rename("Green sphere");

// Reslice green sphere from the top, WITH interpolation
selectWindow("Green sphere")
run("Reslice [/]...", "output=2.000 start=Top rotate");
rename("Green sphere viewed from the top, WITH interpolation")
run("Duplicate...", "duplicate range=5-5");
rename("Green sphere YZ slice WITH interpolation")

// Reslice green sphere from the top, WITHOUT interpolation
selectWindow("Green sphere")
run("Reslice [/]...", "output=2.000 start=Top avoid");
rename("Green sphere viewed from the top, WITHOUT interpolation")
run("Duplicate...", "duplicate range=10-10");
rename("Green sphere YZ slice WITHOUT interpolation")

run("Tile")

ImageJ Jython

""" Open a multidimensional image and crop out the green bead. Then reslice it from the top """

# import packages
from ij import IJ
from ij.plugin import Duplicator

# Close other open images
IJ.run("Close All")

# open image
spheres = IJ.openImage("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyzc_8bit_spheres.tif")
spheres.show()

# crop out the green sphere
spheres.setRoi(23,7,18,18)
green_sphere = Duplicator().run(spheres, 2, 2, 3, 11, 1, 1) # int firstC, int lastC, int firstZ, int lastZ, int firstT, int lastT)
green_sphere.setTitle("Green sphere")
green_sphere.show()

# Reslice green sphere from the top, WITH interpolation
IJ.run(green_sphere, "Reslice [/]...", "output=2.000 start=Top rotate");
green_sphere_top = IJ.getImage()
green_sphere_top.setTitle("Green sphere viewed from the top, WITH interpolation")
green_sphere_YZ_interpolated = Duplicator().run(green_sphere_top, 5, 5) # first Z, last Z
green_sphere_YZ_interpolated.setTitle("green_sphere_YZ_interpolated")
green_sphere_YZ_interpolated.show()

# Reslice green sphere from the top, WITHOUT interpolation
green_sphere_top2 = IJ.run(green_sphere, "Reslice [/]...", "output=2.000 start=Top rotate avoid")
green_sphere_top2 = IJ.getImage()
green_sphere_top2.setTitle("Green sphere viewed from the top, WITHOUT interpolation")
green_sphere_YZ_NOTinterpolated = Duplicator().run(green_sphere_top2, 10, 10) # first Z, last Z
green_sphere_YZ_NOTinterpolated.setTitle("green_sphere_YZ_NOTinterpolated")
green_sphere_YZ_NOTinterpolated.show()

IJ.run("Tile")






Assessment

Fill in the blanks

  1. A set of 2D ____ placed on top of each other form a 3D ____.
  2. An ____ voxel size can cause the image to appear ____ when viewing it at an angle.

Solution

  1. 2D slices placed on top of each other from a 3D stack.
  2. An anisotropic voxel size can cause the image to appear deformed when viewing at a certain angle.

True or False

  1. Isotropic image data has voxels of equal XYZ dimensions.
  2. Slicing is the process of sectioning the data, that has more than two dimensions, along defined axes and dimensions.
  3. Reslicing is a term used to indicate repeated slicing.
  4. Images can have 5 dimensions.

Solution

  1. True
  2. True
  3. False - Typically, the term reslicing refers to resampling volumetric data from a different direction, such that the resulting image stack is a rotated version of the original stack.
  4. True - If we denote width by x, height by y, depth by z, time by t and channel by c, we could have images with dimensions such as: [xy -> 2D], [xyz -> 3D, xyt -> 3D: 2D time-lapse, xyc -> 3D: 2D multi-channel], or [xyzt -> 4D: 3D time-lapse, xyzc -> 4D: 3D multi-channel], or [xyztc -> 5D: 3D time-lapse multi-channel]

Explanations

The word ‘slice’ is often used in different ways. The different ‘layers’ in the z-dimension are referred to as z-slices. Slicing (or subsetting) image data means that part of the image data is selected and ‘sliced out’ to form a new image. This can include selecting one or more dimensions, or just part of a dimension, for example selecting slice 6-12 of the Z-dimension. You can also rotate the data in one of the spatial dimensions and resample the data set to see that data from a different angle, which is sometimes referred to as ‘reslicing’.




Follow-up material

Recommended follow-up modules:

Learn more: