Упорядоченный список точек вдоль полилиний / кривых на изображении - PullRequest
1 голос
/ 20 июня 2020

У меня есть изображения с комбинацией полилиний / поликривых. Моя цель - восстановить упорядоченный список точек вдоль этих полилиний / поликривых.

Используя opencv connectedComponents, я могу изолировать каждую из этих полилиний / кривых на изображении, а затем я попытался получить упорядоченную последовательность точек с помощью эти шаги:

    num_labels, labels_im = cv2.connectedComponents(input_image)     
    ske = skimage.morphology.skeletonize(labels_im==1)
    x,y =np.where(ske)
    cnt = np.vstack([x,y]).T.reshape(-1, 1, 2)        
    recovered_points = cv2.approxPolyDP(cnt, 100, False) 

Однако точки в recovered_points не следуют вдоль исходной полилинии, они являются точками на исходной полилинии, но в растровом порядке, от let направо, снизу вверх, и это не то, что я хочу. Ниже вы можете увидеть input_image (исходное изображение), изображение скелета и точки recovered_points (обратите внимание, что они вышли повернутыми). enter image description here

I have also tried to use findContours on the connected components of the input_image and then approxPolyDP on the contours, but these are contours around the original polylines, so the recovered_points go along the polyline on one side and the comeback on the other and close on the first point, which is neither what I want. See image of the extracted contour below.

введите описание изображения здесь

Есть ли способ в opencv, scikit-image или другой библиотеке восстановить упорядоченные точки вдоль исходных полилиний / кривых?

1 Ответ

1 голос
/ 22 июня 2020

Я написал библиотеку под названием skan для анализа скелетных изображений в Python, которая будет делать то, что вы хотите, хотя она может быть для вас слишком тяжелой. Но он решает ту же проблему, что и у вас, а именно, что вам нужно l oop по соседним пикселям, что медленно в Python. (Для скорости используется Numba .) Класс skan.Skeleton будет делать то, что вы хотите, в частности, skeleton.path(0) даст вам индексы пикселей 0-го пути, а skeleton.coordinates[skeleton.path(0)] даст вам их координаты.

Конкретно с вашим кодом:

import cv2
import skimage.morphology
from skan import Skeleton

# [... missing code...]
num_labels, labels_im = cv2.connectedComponents(input_image)     
skeleton_image = skimage.morphology.skeletonize(labels_im==1)
skeleton = Skeleton(skeleton_image)
path_coordinates = skeleton.coordinates[skeleton.path(0)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...