Как соединить ломаные линии в двоичном изображении с помощью Python/Opencv

Как я могу соединить эти линии в целевых точках? Изображение является результатом скелетирования.

Resulting Image From Skeletonization

Points That I Need To Connect

Я пытаюсь сегментировать каждую строку как область, используя преобразование водораздела.

2 ответов


Майкиответ довольно хорош: использование морфологических операций дилатации и эрозии может помочь в этом контексте.
Я хочу предложить небольшое улучшение, воспользовавшись конкретной структурой изображения под рукой. Вместо использования расширения / эрозии с общим ядром я предлагаю использовать горизонтальная ядра это соединит конечные точки горизонтальных линий, но не будет соединять смежные линии друг с другом.

здесь эскиз кода (при условии, что входное изображение хранится в bw numpy 2D array):

import cv2, numpy as np

kernel = np.ones((1,20), np.uint8)  # note this is a horizontal kernel
d_im = cv2.dilate(bw, kernel, iterations=1)
e_im = cv2.erode(d_im, kernel, iterations=1) 

чтобы удалить артефакты, созданные dialte / erode, я предлагаю снова извлечь скелет

Вы получаете расширенное изображение:
enter image description here

обратите внимание, как закрываются зазоры, сохраняя при этом четкие горизонтальные линии

и размытое изображение:
enter image description here

Если вы далее применяете скелет морфологическая операция на эродированном изображении вы можете получить такой результат:
enter image description here

после подключения кривых вам не нужно использовать сегментацию водораздела, а использовать подключенные компоненты для маркировки каждой кривой.


поскольку изображение уже Монохроматическое, вы можете использовать морфологические преобразования для закрытия ломаных линий.

в случае, если вам нужен пример, вы можете найти его в документации здесь: http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html#closing

Он работает, сначала расширяя белые области на изображении, а затем размывая обратно на ту же сумму. Эффективно закрывая любые отверстия в белых областях. Больше подробности и примеры можно найти здесь: http://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html

эта стратегия требует, чтобы разрыв в ломаной линии меньше, чем расстояние между соседними линиями.

Он не будет работать, если линии пересекаются, или если линии слишком близко друг к другу. Однако я думаю, что это будет очень хорошо работать в вашем примере.

вы также можете удалить артефакты ниже третья строка с помощью функции erode.