Skeletonization

Prerequisites

Before starting this lesson, you should be familiar with:

Learning Objectives

After completing this lesson, learners should be able to:
  • Apply a skeletonization algorithm to a binary image to view its internal skeleton

  • Count the number of branches and branch lengths to obtain morphological information from the image

Motivation

For objects that contain protrusions, it can be helpful to look at the object’s internal skeleton. This reveals the inner branches that make up the object. Measuring the number of branches and their lengths can provide useful morphological information of irregularly shaped objects with protrusions, such as glial cells. Skeletonization algorithms work by applying sequential erosions to remove pixels from the boundary of the objects to the center, stopping when the remaining structure is only one pixel wide.

Concept map

graph TD BI("Binary image") --> S("Skeletonize") S --> SI("Skeleton image") SI --- B("Slab pixels") SI --- J("Junction pixels") SI --- E("End-point pixels")



Figure


Image before and after skeletonization. a) raw image, b) binary image, c) skeleton image, d) tagged skeleton showing slab pixels (dark purple), junction pixels (cyan), and end-point pixels (pink). Examples of different skeleton pixels are indicated by arrows in the corresponding colors.



Activities


Show activity for:  

ImageJ GUI

  • Skeletonize a binary imgae and obtain branch information.
    • Open xy_8bit_glialcells.tif
    • Perform skeletonization: [ Process › Binary › Skeletonize]
    • Obtain branch information by analyzing the skeleton: [Analyze › Skeleton › Analyze Skeleton (2D/3D)]
      • ‘Prune ends’
      • ‘Calculate largest shortest path’, ‘Show detailed info’, ‘Display labeled skeletons’.
      • In the results window, you can find information about the different skeletons and their branches, such as the number of branches and junctions, the longest shortest path, and the average branch length.

ImageJ Macro

// Open binary image and perform skeletonization

// Open image
open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit_glialcells.tif");

// Duplicate the image
run("Duplicate...", " ");

// Perform skeletonization
run("Skeletonize");

// Obtain branch properties
run("Analyze Skeleton (2D/3D)", "prune=none calculate show display");

run("Tile")

ImageJ Jython

# Open image and perform skeletonization

# import classes
from ij import IJ

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

# perform skeletonization
skeleton = imp.duplicate()
IJ.run(skeleton, "Skeletonize", "")
skeleton.show()

# analyze the skeleton
IJ.run(skeleton, "Analyze Skeleton (2D/3D)", "prune=none calculate show display");

IJ.run("Tile")

Exercises

Perform skeletonization and skeleton analysis on this image: xy_8bit_glialcells2.tif.

Try to answer the following questions:

  1. Which cell has the largest number of branches?

  2. Which cell has the longest “longest shortest path”?

  3. Which cell has the highest average branch length?

Show exercise/solution for:

ImageJ GUI

  • Open xy_8bit_glialcells2.tif
  • Perform skeletonization: [ Process › Binary › Skeletonize]
  • Obtain branch information by analyzing the skeleton: [Analyze › Skeleton › Analyze Skeleton (2D/3D)]
    • ‘Prune ends’
    • ‘Calculate largest shortest path’, ‘Show detailed info’, ‘Display labeled skeletons’.
  • In the results window you can find that cell 3 has the largest number of branches, cell 1 has the longest “longest shortest path” and cell 2 has the highest average branch length.

ImageJ Macro

// Open binary image and perform skeletonization

// Open image
open("https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit_glialcells2.tif");

// Duplicate the image
run("Duplicate...", " ");

// Perform skeletonization
run("Skeletonize");

// Obtain branch properties
run("Analyze Skeleton (2D/3D)", "prune=none calculate show display");

run("Tile")
// check the data in the results window to answer the questions.

ImageJ Jython

# Open image and perform skeletonization

# import classes
from ij import IJ

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

# perform skeletonization
skeleton = imp.duplicate()
IJ.run(skeleton, "Skeletonize", "")
skeleton.show()

# analyze the skeleton
IJ.run(skeleton, "Analyze Skeleton (2D/3D)", "prune=none calculate show display")

IJ.run("Tile")
# check the data in the results window to answer the questions.



Assessment

True or False

Solution

  • Slab pixels never overlap with boundary pixels in the original binary image. True
  • Branches in the skeleton can be more than 1 pixel thick. False. They can be longer than 1 pixel, but the branch thickness is always 1 pixel.
  • The longest shortest path is the longest branch in the skeleton. False

Explanations




Follow-up material

Recommended follow-up modules:

Learn more: