Perhaps this is not a bug. However, it was a trip wire.
>>> foo = numpy.zeros((50,50))
>>> skeleton_to_csgraph(foo)
ValueError: ...
>>> foo[0,0] = 1
>>> skeleton_to_csgraph(foo)
ValueError: ...
>>> foo[-1,:] = 1
>>> adj, coords, degs = skeleton_to_csgraph(foo)
>>> coords
[[0. 0.], [0. 0.], ...
This issue summarizes as:
- Two errors above are for all zeros, and an array with only isolated points.
- The final call has two [ 0. 0. ] coords. At least 1 [0. 0.] is always present
- The coords are all floating point and must be cast to integers for indexing
To fix it, I wrapped it like:
def get_cs_graph(skeleton: numpy.ndarray):
"""
Get compressed sparse adjacency matrix of a skeleton
:param skeleton: a skeletonized image
:return: adj:csv_matrix, nonzero_pixel_coords: ndarray, degree_mask:ndarray
"""
# Skan: https://jni.github.io/skan/getting_started.html
# Skan, the source of 'skeleton_to_csgraph' always returns the origin in the pixel list, even if the
# matrix is mostly zeros, so calculate this component with numpy
coords = numpy.vstack(numpy.where(skeleton > 0)).T
# Skan yields errors under some numerical conditions related to all zero arrays, and arrays with isolated pixels
try:
adj, _, degrees = skeleton_to_csgraph(skeleton)
except ValueError as e:
warnings.warn(str(e))
adj = csr_matrix()
degrees = numpy.zeros_like(skeleton)
return adj, coords, degrees
Perhaps this is not a bug. However, it was a trip wire.
This issue summarizes as:
To fix it, I wrapped it like: