Как извлечь информацию о скелете skimage в узлы и ребра NetworkX в python для дальнейшего расширенного анализа

В настоящее время я использую skimage в python для извлечения скелета открытого пространства из некоторой бинарной карты, как показано на следующих рисунках:

Исходное изображение карты BWОткрытая площадка со скелетом

Со следующими кодами Python:

from skimage.morphology import skeletonize
from skimage import draw
from skimage.io import imread, imshow
from skimage.color import rgb2gray

# load image from file
img_fname=os.path.join('images','mall1_2F_schema.png') 
image=imread(img_fname)

# Change RGB color to gray 
image=rgb2gray(image)

# Change gray image to binary
image=np.where(image>np.mean(image),1.0,0.0)

# perform skeletonization
skeleton = skeletonize(image)

Теперь я хотел бы извлечь конечные точки и точки пересечения из скелета в качестве узлов для графического объекта Networkx при вычислении расстояния между соседними узлами в качестве ребер для графического объекта Networkx. В настоящее время мне приходится вручную получать координаты точек и вводить их в процесс инициализации объекта NetworkX. Есть ли у нас более разумный способ сделать все автоматически?

Кстати, я нашел ответ yaron kahanovitch на вопрос о stackoverflow предлагает аналогичные подходы. Однако предложений по реализации больше не поступало, и я думаю, что NetworkX может быть одним из подходов.

Любые предложения от вас очень ценятся.


person gongming wei    schedule 07.12.2016    source источник
comment
Нашел еще одну интересную ссылку, чтобы найти конечную или точку пересечения что может быть полезно для поиска решения на python.   -  person gongming wei    schedule 07.12.2016


Ответы (1)


Ну вот.

Этот фрагмент кода предназначен для 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
person TurtleIzzy    schedule 27.02.2021