干得好。
这段代码适用于 2D 骨架图像,您可以轻松地将其扩展到 3D。
import networkx as nx
import numpy as np
def skeleton_image_to_graph(skeIm, connectivity=2):
assert(len(skeIm.shape) == 2)
skeImPos = np.stack(np.where(skeIm))
skeImPosIm = np.zeros_like(skeIm, dtype=np.int)
skeImPosIm[skeImPos[0], skeImPos[1]] = np.arange(0, skeImPos.shape[1])
g = nx.Graph()
if connectivity == 1:
neigh = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]])
elif connectivity == 2:
neigh = np.array([[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]])
else:
raise ValueError(f'unsupported connectivity {connectivity}')
for idx in range(skeImPos[0].shape[0]):
for neighIdx in range(neigh.shape[0]):
curNeighPos = skeImPos[:, idx] + neigh[neighIdx]
if np.any(curNeighPos<0) or np.any(curNeighPos>=skeIm.shape):
continue
if skeIm[curNeighPos[0], curNeighPos[1]] > 0:
g.add_edge(skeImPosIm[skeImPos[0, idx], skeImPos[1, idx]], skeImPosIm[curNeighPos[0], curNeighPos[1]], weight=np.linalg.norm(neigh[neighIdx]))
g.graph['physicalPos'] = skeImPos.T
return g