skan.csr: CSR Graph representation of skeletons#
- class skan.csr.Skeleton(skeleton_image, *, spacing=1, source_image=None, keep_images=True, value_is_height=False)[source]#
Object to group together all the properties of a skeleton.
In the text below, we use the following notation:
N: the number of points in the pixel skeleton,
ndim: the dimensionality of the skeleton
P: the number of paths in the skeleton (also the number of links in the junction graph).
J: the number of junction nodes
Sd: the sum of the degrees of all the junction nodes
[Nt], [Np], Nr, Nc: the dimensions of the source image
- Parameters:
skeleton_image (array) β The input skeleton (1-pixel/voxel thick skeleton, all other values 0).
spacing (float or array of float, shape
(ndim,)
) β The scale of the pixel spacing along each axis.source_image (array of float, same shape as skeleton_image) β The image that skeleton_image represents / summarizes / was generated from. This is used to produce visualizations as well as statistical properties of paths.
keep_images (bool) β Whether or not to keep the original input images. These can be useful for visualization, but they may take up a lot of memory.
value_is_height (bool) β Whether to consider the value of a float skeleton to be the βheightβ of the image. This can be useful e.g. when measuring lengths along ridges in AFM images.
- graph#
The skeleton pixel graph, where each node is a non-zero pixel in the input image, and each edge connects adjacent pixels. The graph is represented as an adjacency matrix in SciPy sparse matrix format. For more information see the
scipy.sparse
documentation as well asscipy.sparse.csgraph
. Note: pixel numbering starts at 1, so the shape of this matrix is(N + 1, N + 1)
instead of(N, N)
.- Type:
scipy.sparse.csr_matrix, shape (N + 1, N + 1)
- nbgraph#
A thin Numba wrapper around the
csr_matrix
format, this provides faster graph methods. For example, it is much faster to get a list of neighbors, or test for the presence of a specific edge.- Type:
NBGraph
- coordinates#
skeleton_pixel_id i -> coordinates[i] The image coordinates of each pixel in the skeleton. Some values in this matrix are non-sensical β you should only access them from node ids.
- Type:
array, shape (N, ndim)
- paths#
A csr_matrix where element [i, j] is on if node j is in path i. This includes path endpoints. The number of nonzero elements is N - J + Sd.
- Type:
scipy.sparse.csr_matrix, shape (P, N + 1)
- n_paths#
The number of paths, P. This is redundant information given n_paths, but it is used often enough that it is worth keeping around.
- Type:
int
- distances#
The distance of each path. Note: not initialized until path_lengths() is called on the skeleton; use path_lengths() instead
- Type:
array of float, shape (P,)
- skeleton_image#
The input skeleton image. Only present if keep_images is True. Set to False to preserve memory.
- Type:
array or None
- source_image#
The image from which the skeleton was derived. Only present if keep_images is True. This is useful for visualization.
- Type:
array or None
- path(index)[source]#
Return the pixel indices of path number index.
- Parameters:
index (int) β The desired path.
- Returns:
path β The indices of the pixels belonging to the path, including endpoints.
- Return type:
array of int
- path_coordinates(index: int)[source]#
Return the image coordinates of the pixels in the path.
- Parameters:
index (int) β The desired path.
- Returns:
path_coords β The (image) coordinates of points on the path, including endpoints.
- Return type:
array of float
- path_label_image()[source]#
Image like self.skeleton_image with path_ids as values.
- Returns:
label_image β Image of the same shape as self.skeleton_image where each pixel has the value of its branch id + 1.
- Return type:
array of ints
- path_lengths()[source]#
Return the length of each path on the skeleton.
- Returns:
lengths β The length of all the paths in the skeleton.
- Return type:
array of float
- path_means()[source]#
Compute the mean pixel value along each path.
- Returns:
means β The average pixel value along each path in the skeleton.
- Return type:
array of float
- path_stdev()[source]#
Compute the standard deviation of values along each path.
- Returns:
stdevs β The standard deviation of pixel values along each path.
- Return type:
array of float
- path_with_data(index: int)[source]#
Return pixel indices and corresponding pixel values on a path.
- Parameters:
index (int) β The desired path.
- Returns:
path (array of int) β The indices of pixels on the path, including endpoints.
data (array of float) β The values of pixels on the path.
- paths_list()[source]#
List all the paths in the skeleton, including endpoints.
- Returns:
paths β The list containing all the paths in the skeleton.
- Return type:
list of array of int
- prune_paths(indices: _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) Skeleton [source]#
Prune nodes from the skeleton.
- Parameters:
indices (List[int]) β List of indices to be removed.
Retruns
-------
Skeleton β A new Skeleton object pruned.
- skan.csr.make_degree_image(skeleton_image)[source]#
Create a array showing the degree of connectivity of each pixel.
- Parameters:
skeleton_image (array) β An input image in which every nonzero pixel is considered part of the skeleton, and links between pixels are determined by a full n-dimensional neighborhood.
- Returns:
degree_image β An image containing the degree of connectivity of each pixel in the skeleton to neighboring pixels.
- Return type:
array of int, same shape as skeleton_image
- skan.csr.nx_to_skeleton(g: Graph | MultiGraph) Skeleton [source]#
Convert a Networkx Graph to a Skeleton object.
The NetworkX Graph should have the following graph properties: - βshapeβ: the shape of the image from which the graph was created. - βdtypeβ: the dtype of the image from which the graph was created.
and the following edge properties: - βpathβ: an (N, Ndim) array of coordinates in the image of the pixels
traced by this edge.
βvaluesβ: an (N,) array of values for the pixels traced by this edge.
The skeleton_to_nx function can produce such a graph from a Skeleton object.
- Parameters:
g (nx.Graph) β Networkx graph to convert to Skeleton.
- Returns:
Skeleton object corresponding to the input graph.
- Return type:
Notes
Currently, this method uses the naive, brute-force approach of regenerating the entire image from the graph, and then generating the Skeleton from the image. It is probably low-hanging fruit to instead generate the Skeleton compressed-sparse-row (CSR) data directly.
- skan.csr.pixel_graph(image, *, mask=None, edge_function=None, connectivity=1, spacing=None)[source]#
Create an adjacency graph of pixels in an image.
Pixels where the mask is True are nodes in the returned graph, and they are connected by edges to their neighbors according to the connectivity parameter. By default, the value of an edge when a mask is given, or when the image is itself the mask, is the euclidean distance betwene the pixels.
However, if an int- or float-valued image is given with no mask, the value of the edges is the absolute difference in intensity between adjacent pixels, weighted by the euclidean distance.
- Parameters:
image (array) β The input image. If the image is of type bool, it will be used as the mask as well.
mask (array of bool) β Which pixels to use. If None, the graph for the whole image is used.
edge_function (callable) β A function taking an array of pixel values, and an array of neighbor pixel values, and an array of distances, and returning a value for the edge. If no function is given, the value of an edge is just the distance.
connectivity (int) β The square connectivity of the pixel neighborhood: the number of orthogonal steps allowed to consider a pixel a neigbor. See scipy.ndimage.generate_binary_structure for details.
spacing (tuple of float) β The spacing between pixels along each axis.
- Returns:
graph (scipy.sparse.csr_matrix) β A sparse adjacency matrix in which entry (i, j) is 1 if nodes i and j are neighbors, 0 otherwise.
nodes (array of int) β The nodes of the graph. These correspond to the raveled indices of the nonzero pixels in the mask.
- skan.csr.sholl_analysis(skeleton, center=None, shells=None)[source]#
Sholl Analysis for Skeleton object.
- Parameters:
skeleton (skan.csr.Skeleton) β A Skeleton object.
center (array-like of float or None, optional) β Scaled coordinates of a point on the skeleton to use as the center from which the concentric shells are computed. If None, the geodesic center of skeleton is chosen.
shells (int or array of floats or None, optional) β If an int, it is used as number of evenly spaced concentric shells. If an array of floats, it is used directly as the different shell radii in real world units. If None, the number of evenly spaced concentric shells is automatically calculated.
- Returns:
center (array of float) β The scaled coordinates in real world units of the center of the shells. (This might be provided as input, but it might also have been computed within this function, and that computation is expensive, so we return it just in case.)
shell_radii (array of float) β Radii in real world units for concentric shells used for analysis.
intersection_counts (array of int) β Number of intersections for corresponding shell radii.
- skan.csr.skeleton_to_csgraph(skel, *, spacing=1, value_is_height=False)[source]#
Convert a skeleton image of thin lines to a graph of neighbor pixels.
- Parameters:
skel (array) β An input image in which every nonzero pixel is considered part of the skeleton, and links between pixels are determined by a full n-dimensional neighborhood.
spacing (float, or array-like of float, shape (skel.ndim,)) β A value indicating the distance between adjacent pixels. This can either be a single value if the data has the same resolution along all axes, or it can be an array of the same shape as skel to indicate spacing along each axis.
value_is_height (bool, optional) β If True, the pixel value at each point of the skeleton will be considered to be a height measurement, and this height will be incorporated into skeleton branch lengths. Used for analysis of atomic force microscopy (AFM) images.
- Returns:
graph (sparse.csr_matrix) β A graph of shape (Nnz, Nnz), where Nnz is the number of nonzero pixels in skel. The value graph[i, j] is the distance between adjacent pixels i and j. In a 2D image, that would be 1 for immediately adjacent pixels and sqrt(2) for diagonally adjacent ones.
pixel_coordinates (array of float) β An array of shape (Nnz, skel.ndim), mapping indices in graph to pixel coordinates in skel.
- skan.csr.skeleton_to_nx(skeleton: Skeleton, summary: DataFrame | None = None) MultiGraph [source]#
Convert a Skeleton object to a networkx Graph.
- Parameters:
skeleton (Skeleton) β The skeleton to convert.
summary (pd.DataFrame | None) β The summary statistics of the skeleton. Each row in the summary table is an edge in the networkx graph. It is not necessary to pass this in because it can be computed from the input skeleton, but if it is already computed, it will speed up this function.
- Returns:
g β A graph where each node is a junction or endpoint in the skeleton, and each edge is a path.
- Return type:
nx.MultiGraph
- skan.csr.submatrix(M, idxs)[source]#
Return the outer-index product submatrix, M[idxs, :][:, idxs].
- Parameters:
M (scipy.sparse.spmatrix) β Input (square) matrix
idxs (array of int) β The indices to subset. No index in idxs should exceed the number of rows of M.
- Returns:
Msub β The subsetted matrix.
- Return type:
scipy.sparse.spmatrix
Examples
>>> Md = np.arange(16).reshape((4, 4)) >>> M = sparse.csr_matrix(Md) >>> print(submatrix(M, [0, 2]).toarray()) [[ 0 2] [ 8 10]]
- skan.csr.summarize(skel: Skeleton, *, value_is_height: bool = False, find_main_branch: bool = False, separator: str | None = None) DataFrame [source]#
Compute statistics for every skeleton and branch in
skel
.- Parameters:
skel (skan.csr.Skeleton) β A Skeleton object.
value_is_height (bool) β Whether to consider the value of a float skeleton to be the βheightβ of the image. This can be useful e.g. when measuring lengths along ridges in AFM images.
find_main_branch (bool, optional) β Whether to compute main branches. A main branch is defined as the longest shortest path within a skeleton. This step is very expensive as it involves computing the shortest paths between all pairs of branch endpoints, so it is off by default.
separator (str, optional) β Some column names are composite, e.g.
'coord_src_0'
. The separator argument allows users to configure which character is used to separate the components. The default up to version 0.12 is β-β, but will change to β_β in version 0.13.
- Returns:
summary β A summary of the branches including branch length, mean branch value, branch euclidean distance, etc.
- Return type:
pandas.DataFrame