«Угловые» точки, которые вы хотите найти, не определены как «пересечения», используемые для построения графика. Поэтому их нельзя найти одним и тем же методом.
В зависимости от того, что вы на самом деле определяете для этих точек, можно было бы упростить путь, используя алгоритм Дугласа-Пекера , используя approximate_polygon
в skimage
( см. демоверсию здесь ). Для этого необходимо выбрать допуск.
Из примера , приведенного в файле readme sknw
, я попытался воссоздать ваш:
import numpy as np
import matplotlib.pylab as plt
from skimage.morphology import skeletonize
from skimage import data
import sknw
import networkx as nx
from skimage.measure import approximate_polygon
# open and skeletonize
img = data.horse()
ske = skeletonize(~img).astype(np.uint16)
# build graph from skeleton
graph = sknw.build_sknw(ske)
# draw image
plt.imshow(img, cmap='gray')
# draw edges by pts
for (s,e) in graph.edges():
polyline = graph[s][e]['pts']
plt.plot(polyline[:,1], polyline[:,0], 'green', alpha=.6)
# Find the "corner points" and plot:
tolerance = 5
simple_polyline = approximate_polygon(polyline, tolerance)
plt.plot(simple_polyline[1:-1, 1], simple_polyline[1:-1, 0], '.m')
# draw node by o
node, nodes = graph.node, graph.nodes()
ps = np.array([node[i]['o'] for i in nodes])
plt.plot(ps[:,1], ps[:,0], 'r.')
# title and show
plt.title('Build Graph')
plt.show()
, который дает: (пурпурные точки являются «угловыми» точками)
Я думаю, что это будет работать намного лучше на изображении лабиринта.
edit, пример кода для итерации по пути:
one_path = nx.shortest_path(graph, source=0, target=8)
full_line = []
for source, target in zip(one_path, one_path[1:]):
polyline = graph[source][target]['pts']
# Find the "corner point":
tolerance = 5
simple_polyline = approximate_polygon(polyline, tolerance)
full_line.extend(simple_polyline[:-1])
full_line.append(simple_polyline[-1]) # add the last point
full_line = np.array(full_line) # convert to an array