Skip to content

Advanced Topic: Skeletons

William Silversmith edited this page May 29, 2021 · 33 revisions

Short Example

skel = vol.skeleton.get(SEGID) 
skels = vol.skeleton.get([ SEGID, SEGID, ... ]) # threaded download 
vol.skeleton.upload(skel) 
vol.skeleton.upload([ skel1, skel2, ... ]) # threaded upload
vol.skeleton.upload_raw(segid, vertices, edges, radii=None, vertex_types=None)

# Accessing Attributes
skel.id # segment ID
skel.vertices # numpy array shape is (Nv, 3)
skel.edges # numpy array shape is (Nv, 2)
skel.radii # numpy array shape is (Nv, 1)
skel.vertex_types # numpy array shape is (Nv, 1)

# Stand-Alone Visualization
skel.viewer() # requires matplotlib which is not installed by default

Default Skeleton Format

Skeletons are visible in Neuroglancer. We use a binary format to represent the skeleton tree. Neuroglancer understands vertices and edges, and doesn't crash if more data are provided. We take advantage of this to provide the extended attributes Radii and SWC Vertex Type. The Precomputed format also supports custom extended vertex attributes.

Filename: $CLOUDPATH/skeletons/$SEGID

Vertex Count (Nv) Edges Count (Ne) Vertices Edges Radii+ Vertex+ Type
Format scalar scalar x, y, z, ... v11, v12, ... r1, r2, ... t1, t2, ...
Data Type uint32 uint32 float32 uint32 float32 uint8
Bytes 4 4 Nv x 12 Ne x 8 Nv x 4 Nv
Default Value 0 0 N/A N/A -1.0f 0
Units - - nm - nm -
Required Yes Yes Yes Yes Optional Optional, Req. Radii

Skeleton Examples

from cloudvolume import Skeleton

skel = Skeleton(VERTICES, EDGES, RADII, VERTEX_TYPES, SEGID)

skel.id # segment ID
skel.vertices # numpy array shape is (Nv, 3)
skel.edges # numpy array shape is (Nv, 2)
skel.radii # numpy array shape is (Nv, 1)
skel.vertex_types # numpy array shape is (Nv, 1)

skel.empty() # boolean

bytes = skel.to_precomputed() # encode to Precomputed format (bytes)
skel = Skeleton.from_precomputed(bytes) # decode from the Precomputed format

skel = skel.crop(slices or bbox) # eliminate vertices and edges outside bbox
skel = skel.consolidate() # eliminate duplicate vertices and edges and disconnected vertices
skel3 = skel.merge(skel2) # merge two skeletons into one
skel = skel.clone() # create copy
skel = Skeleton.from_swc(swcstr) # decode an SWC file
skel_str = skel.to_swc() # convert to SWC file in string representation

skel.cable_length() # sum of all edge lengths
skel = skel.downsample(2) # reduce size of skeleton by factor of 2, preserves branch and end points
skels = skel.components() # return a list of all the connected components in this skeleton

skel1 == skel2 # check if contents of internal arrays match
Skeleton.equivalent(skel1, skel2) # ...even if there are differences like differently numbered edges

The SWC file format was defined by Cannona et al. [1]. This website saved in the Internet Archive has a good explanation. The SWC files we generate may contain multiple connected components (i.e. multiple roots). You can avoid this by generating a separate SWC for each component:

for i, skel in enumerate(skeleton.components()):
  with open(str(skel.id) + '-' + str(i) + '.swc', 'wt') as f:
    f.write(skel.to_swc())

Viewer

There is an optional stand-alone viewer based on matplotlib (not installed by default), which plots a skeleton in 3D in an interactive graph. The vertices form a heat map colored indexed by the value of the radii. Unfortunately, matplotlib is more difficult to get working outside of a linux environment, but it is certainly possible.

pip install matplotlib
skel.viewer() # default

skel.viewer(
   draw_vertices=True,
   draw_edges=True,
   units='nm',
   color_by='radius', # aka 'r' or 'components' aka 'c'
)

A spiny dendrite with vertices colored by radius.

Creating Skeletons

There are many ways to create skeletons, but there are a few libraries in particular that are being developed by our lab members and collaborators that are designed for large scale operation:

  • Kimimaro (Python) - for large densely labeled image volumes using a TEASAR variant and designed for this format
  • MeshParty (Python) - "Mesh TEASAR"
  • RealNeuralNetworks.jl (Julia) - sparse skeletonization of large volumes of dense labels using a TEASAR variant
  • skeletonize.m (MATLAB) - sparse skeletonization of dense labels
  • skeletonization (Python) - sparse skeletonization of large volumes using a TEASAR variant

There are also other libraries (usually) by other members of the connectomics community. However, please direct your queries to their authors.

  • ImageProcessing (C++) - TEASAR on binary image volumes
  • Skeletor (Python) - Skeletonization by laplacian mesh contraction by Philipp Schlegel.
  • Skeletor (Python) - Wrapper around a voxel thinning algorithm (and potentially others) by Constantin Pape.
  • NeuTu - Full featured connectomics reconstruction engine that includes the ability to skeletonize binary TIFFs from the command line using TEASAR.

References

  1. R. Cannona, D. Turner, G. Pyapali, H. Wheal. "An on-line archive of reconstructed hippocampal neurons". Journal of Neuroscience Methods. Volume 84, Issues 1–2, 1 October 1998, Pages 49-54 doi: 10.1016/S0165-0270(98)00091-0 (link) - defines the SWC format