Как соединить ломаные линии в двоичном изображении с помощью Python/Opencv
Как я могу соединить эти линии в целевых точках? Изображение является результатом скелетирования.
Я пытаюсь сегментировать каждую строку как область, используя преобразование водораздела.
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, я предлагаю снова извлечь скелет
Вы получаете расширенное изображение:
обратите внимание, как закрываются зазоры, сохраняя при этом четкие горизонтальные линии
Если вы далее применяете скелет морфологическая операция на эродированном изображении вы можете получить такой результат:
после подключения кривых вам не нужно использовать сегментацию водораздела, а использовать подключенные компоненты для маркировки каждой кривой.
поскольку изображение уже Монохроматическое, вы можете использовать морфологические преобразования для закрытия ломаных линий.
в случае, если вам нужен пример, вы можете найти его в документации здесь: 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.