Glossary¶
Every feature maskel can extract, grouped by the level it's computed at and named exactly as it appears in the corresponding CSV column (summary.csv, <image>_branches.csv, <image>_nodes.csv — see Configurable parameters for when each file is written). Generated by running maskel with every extraction option enabled on a 3D vessel volume and reading the resulting tables and code together.
Spacing-aware below means the value changes once extraction.spacing is set to a non-isotropic value instead of the default null; everything else stays in raw pixel/voxel units (or a dimensionless ratio/count) no matter what spacing is.
Object-level features (summary.csv)¶
One row per object per image. Requires extraction.summary (on by default); most fields need other options too, as noted.
Every mask-derived field below (vessel_area, vessel_area_fraction, and the radius/diameter statistics) is measured against the mask after preprocessing — if extraction.fill_holes or extraction.closing_iterations is set, that's the morphologically-modified mask, not the raw input crop.
object_id— the mask's own label value for this object (1for a plain binary mask).num_nodes— number of distinct graph nodes (junctions/endpoints) referenced by any branch in this object.num_edges— number of branches (skeleton segments) in this object. Always computed alongside the summary, regardless of whetherextraction.branchesis also on.num_endpoints— number of nodes with degree 1 (skeleton tips).num_bifurcations— number of nodes with degree ≥ 3 (branch points).total_length— sum of every branch'sbranch-distance. Spacing-aware.mean_length/std_length/max_length/min_length— mean/std/max/min ofbranch-distanceacross all branches. Spacing-aware.mean_tortuosity/std_tortuosity— mean/std of per-branchtortuosity(see Branch-level below), excluding branches where it's undefined (zero euclidean distance). Tortuosity is a length ratio, so unaffected byspacingeven though the underlying lengths are.num_components— number of disjoint connected pieces in this object's branch graph. Usually1, since each object is already its own connected foreground region before thinning — but pruning or thinning can fragment it further.mean_degree/max_degree— mean/max node degree over this object's graph nodes.fractal_dimension— box-counting fractal dimension of this object's own skeleton crop: count how many boxes of a given size contain any skeleton pixel, repeat over a range of box sizes, and fit a log-log line whose slope magnitude is the fractal dimension. Ranges ~1–2 for 2D skeletons (up to ~3 for 3D); values near the upper end mean the skeleton densely fills space, values near the lower end mean sparse, line-like coverage. Requiresextraction.fractal_dimension; forced to0.0whenspacingis set and anisotropic, since box-counting assumes isotropic voxels.fractal_dimension_r2— R² goodness-of-fit of the log-log line used to computefractal_dimension(fit-quality indicator, not a feature of the vessel itself).hgu— "hyphal growth unit":total_length / num_endpoints. The average uninterrupted skeleton length per tip; higher means longer stretches between endpoints. Spacing-aware (inherits fromtotal_length).mean_radius/std_radius/min_radius/max_radius— statistics of the Euclidean-distance-transform radius, sampled at every skeleton pixel of this object (not per-branch — see the branch-level fields of the same name for that). Requiresextraction.mask_radius. Spacing-aware (the EDT is computed withspacingas the pixel sampling distance).mean_diameter/std_diameter/min_diameter/max_diameter—2 ×the radius statistics above. Same requirements and spacing-awareness.vessel_area— foreground pixel/voxel count of this object's own (padded bounding-box) crop of the binary mask, before thinning (see note above on which mask). Despite the name, this is an area in 2D and a volume in 3D. Spacing-aware: scaled by the pixel/voxel's physical area/volume (spacing[0] * spacing[1] * ...) when set.vessel_area_fraction— the same foreground count as a fraction (0–1) of the crop's total pixel/voxel count. A ratio, so unaffected byspacing.mean_segment_volume— mean of the branch-levelvolumecolumn (see below) across this object's branches. Requiresextraction.mask_radius;0.0when there are no branches with a valid radius. Spacing-aware.mean_surface_area— mean of the branch-levelsurface_areacolumn across this object's branches. Same requirements and spacing-awareness.
Branch-level features (<image>_branches.csv)¶
One row per branch (skeleton edge between two graph nodes). Requires extraction.branches (and output.write_branch_csv to actually write the CSV). Most columns other than object_id, tortuosity, straightness, and the radius/diameter/volume/surface_area group come directly from skan's summarize().
object_id— added by maskel; the object this branch belongs to.skeleton-id— which connected skeleton fragment (within this object) the branch belongs to, in casenum_components> 1. Not the same asobject_id.node-id-src/node-id-dst— the two endpoint nodes' ids in this object's own graph (matchesnode_idin<image>_nodes.csvfor the same object).branch-distance— the branch's path length along the skeleton (sum of step-to-step distances, not a straight line). Spacing-aware.branch-type—0= endpoint-to-endpoint (an isolated segment, both ends degree 1),1= endpoint-to-junction (a tip),2= junction-to-junction,3= isolated cycle (a closed loop with no branch point, so both ends are the same node).mean-pixel-value/stdev-pixel-value— mean/std of the skeleton array's own pixel values along the branch's path. Since maskel's skeleton is a binary 0/1 array (not a grayscale intensity image), this is essentially always1.0/0.0— kept for compatibility with skan's schema rather than being informative here.image-coord-src-0,image-coord-src-1, (image-coord-src-2) /image-coord-dst-*— the source/destination node's raw pixel-index coordinates, one column per axis, in this object's local (cropped) coordinate system. Never spacing-scaled.coord-src-*/coord-dst-*— the same coordinates scaled byspacing(identical to theimage-coord-*values whenspacingisnull). Spacing-aware.euclidean-distance— straight-line distance between the source and destination nodes, computed from the spacing-scaledcoord-src/coord-dstvalues. Spacing-aware.tortuosity—branch-distance / euclidean-distance;NaNwheneuclidean-distanceis0(a cycle). A length ratio, so unaffected byspacingeven though both inputs are spacing-aware.straightness— the inverse,euclidean-distance / branch-distance;NaNwhenbranch-distanceis0. Also spacing-independent.mean_radius/std_radius/min_radius/max_radius— EDT radius statistics sampled along just this branch's path (as opposed to the object-level fields of the same name, which cover the whole object). Requiresextraction.mask_radius. Spacing-aware.mean_diameter/std_diameter/min_diameter/max_diameter—2 ×the radius statistics above. Same requirements and spacing-awareness.volume— this branch modeled as a chain of frustums between consecutive skeleton pixels along its path: each step's physical length (diagonal- and spacing-aware) weighted by the average radius of its two endpoints, summed asπ × Σ(r_mid² × step_length). Requiresextraction.mask_radius. Spacing-aware.surface_area— the same frustum chain's lateral surface area,2π × Σ(r_mid × step_length). Same requirements and spacing-awareness.
Node-level features (<image>_nodes.csv)¶
One row per graph node (junction, endpoint, or pass-through point). Requires extraction.nodes (and output.write_node_csv to write the CSV) — unlike napari-maskel's node layer, which only displays branch/end nodes, this CSV includes every node, including pass-through ones.
object_id— added by maskel; the object this node belongs to.node_id— this node's id in the object's own graph (matchesnode-id-src/node-id-dstin<image>_branches.csvfor the same object).coord_0,coord_1, (coord_2) — the node's raw pixel-index coordinates, one column per axis, already offset into the full image's coordinate system (unlike the branch CSV's local-crop coordinates). Never spacing-scaled.degree— number of branches meeting at this node.is_endpoint—truewhendegree == 1(a skeleton tip).is_junction—truewhendegree >= 3(a branch point).is_pass_through—truewhendegree == 2(a point along a straight, unbranched run — not a true topological feature, just where skan happened to place a node).radius— the EDT radius sampled at this node's exact pixel. Requiresextraction.mask_radius. Spacing-aware.