Skeletonize densely labeled image volumes using TEASAR-derived algorithms for neuroscience and connectomics research.
—
The core skeletonization functionality implements the TEASAR-derived algorithm for converting densely labeled image volumes into skeleton representations. This module provides the primary skeletonize function along with specialized point connection capabilities.
Skeletonizes all non-zero labels in a 2D or 3D image using the TEASAR algorithm with support for parallel processing, soma detection, and various quality improvements.
def skeletonize(
all_labels,
teasar_params=DEFAULT_TEASAR_PARAMS,
anisotropy=(1,1,1),
object_ids=None,
dust_threshold=1000,
progress=True,
fix_branching=True,
in_place=False,
fix_borders=True,
parallel=1,
parallel_chunk_size=100,
extra_targets_before=[],
extra_targets_after=[],
fill_holes=False,
fix_avocados=False,
voxel_graph=None
):
"""
Skeletonize all non-zero labels in a given 2D or 3D image.
Parameters:
- all_labels (numpy.ndarray): 2D or 3D array of integer labels
- teasar_params (dict): Algorithm parameters controlling path tracing
- scale (float): Rolling ball invalidation scale multiplier (default: 1.5)
- const (float): Minimum invalidation radius in physical units (default: 300)
- pdrf_scale (float): Penalty distance field scale factor (default: 100000)
- pdrf_exponent (int): Penalty field exponent, powers of 2 are faster (default: 8)
- soma_detection_threshold (float): DBF threshold for soma detection (default: 750)
- soma_acceptance_threshold (float): DBF threshold for soma acceptance (default: 3500)
- soma_invalidation_scale (float): Soma-specific invalidation scale (default: 2)
- soma_invalidation_const (float): Soma-specific invalidation constant (default: 300)
- max_paths (int, optional): Maximum paths to trace per object
- anisotropy (tuple): Physical dimensions of voxels (x,y,z) (default: (1,1,1))
- object_ids (list, optional): Process only specified label IDs
- dust_threshold (int): Skip connected components smaller than this (default: 1000)
- progress (bool): Show progress bar (default: True)
- fix_branching (bool): Improve quality of branched shapes (default: True)
- in_place (bool): Modify input array in place (default: False)
- fix_borders (bool): Center skeleton where shape contacts border (default: True)
- parallel (int): Number of processes (1=single, <=0=all CPUs) (default: 1)
- parallel_chunk_size (int): Skeletons per progress update (default: 100)
- extra_targets_before (list): Extra target points before main algorithm
- extra_targets_after (list): Extra target points after main algorithm
- fill_holes (bool): Fill holes in connected components (default: False)
- fix_avocados (bool): Use heuristics to combine nuclei with cell bodies (default: False)
- voxel_graph (numpy.ndarray, optional): Custom connectivity graph
Returns:
dict: Dictionary mapping label IDs to Skeleton objects
Raises:
DimensionError: If input dimensions are incompatible
"""import kimimaro
import numpy as np
# Load segmented volume
labels = np.load("neurons.npy")
# Basic skeletonization
skeletons = kimimaro.skeletonize(labels, anisotropy=(4, 4, 40))
# Advanced skeletonization with custom parameters
skeletons = kimimaro.skeletonize(
labels,
teasar_params={
"scale": 2.0, # More aggressive invalidation
"const": 500, # Larger minimum radius
"pdrf_scale": 50000, # Lower penalty field influence
"soma_detection_threshold": 1000, # Higher soma threshold
"max_paths": 200, # Limit paths per object
},
anisotropy=(16, 16, 40), # 16x16x40 nm voxels
dust_threshold=2000, # Skip small objects
parallel=4, # Use 4 processes
fix_avocados=True, # Combine soma artifacts
fill_holes=True, # Fill holes in shapes
object_ids=[1, 5, 10, 15], # Process specific labels only
extra_targets_after=[(100, 200, 50)], # Add extra endpoint
)
# Access individual skeletons
neuron_1 = skeletons[1]
print(f"Skeleton has {len(neuron_1.vertices)} vertices")
print(f"Skeleton has {len(neuron_1.edges)} edges")Creates a direct skeleton path between two specified points on a binary image, useful for tracing specific connections or when exact endpoints are known.
def connect_points(
labels,
start,
end,
anisotropy=(1,1,1),
fill_holes=False,
in_place=False,
pdrf_scale=100000,
pdrf_exponent=4
):
"""
Draw a centerline between preselected points on a binary image.
Parameters:
- labels (numpy.ndarray): Binary image (2D or 3D)
- start (tuple): Starting point coordinates (x, y, z) in voxel space
- end (tuple): Ending point coordinates (x, y, z) in voxel space
- anisotropy (tuple): Physical voxel dimensions (default: (1,1,1))
- fill_holes (bool): Fill holes in shapes before tracing (default: False)
- in_place (bool): Modify input array in place (default: False)
- pdrf_scale (float): Penalty field scale factor (default: 100000)
- pdrf_exponent (int): Penalty field exponent (default: 4)
Returns:
Skeleton: Single skeleton connecting the two points
Raises:
ValueError: If start and end points are in disconnected components
"""import kimimaro
import numpy as np
# Create binary image of single object
binary_neuron = (labels == 12345)
# Connect two specific points
skeleton = kimimaro.connect_points(
binary_neuron,
start=(50, 100, 25), # Starting coordinates
end=(200, 300, 75), # Ending coordinates
anisotropy=(32, 32, 40) # Voxel dimensions in nm
)
# The skeleton traces the shortest path through the object
print(f"Path length: {skeleton.cable_length()} nm")Converts synapse centroid locations to skeleton target points for enhanced skeletonization around synaptic sites.
def synapses_to_targets(labels, synapses, progress=False):
"""
Convert synapse centroids to skeleton targets.
Given synapse centroids and desired SWC labels, finds the nearest
voxel to each centroid for the corresponding label.
Parameters:
- labels (numpy.ndarray): Labeled volume
- synapses (dict): Mapping of {label_id: [((x,y,z), swc_label), ...]}
- progress (bool): Show progress bar (default: False)
Returns:
dict: Mapping of {(x,y,z): swc_label, ...} for use as extra_targets
"""import kimimaro
# Define synapse locations for different labels
synapses = {
1: [((120, 200, 30), 3), ((150, 220, 35), 3)], # Two synapses on neuron 1
5: [((80, 180, 25), 4)], # One synapse on neuron 5
}
# Convert to target format
targets = kimimaro.synapses_to_targets(labels, synapses, progress=True)
# Use targets in skeletonization
skeletons = kimimaro.skeletonize(
labels,
extra_targets_after=list(targets.keys()),
anisotropy=(16, 16, 40)
)The TEASAR algorithm works through several key phases:
scale * DBF + constpdrf_scale * DBF^pdrf_exponent + euclidean_distanceparallel > 1 for large datasets with many objectsInstall with Tessl CLI
npx tessl i tessl/pypi-kimimaro