How to connect broken lines in a binary image using Python/Opencv

Thiago Resende picture Thiago Resende · May 9, 2017 · Viewed 14.7k times · Source

How can I make these lines connect at the target points? The image is a result of a skeletonization process.

Resulting Image From Skeletonization

Points That I Need To Connect

I'm trying to segment each line as a region using Watershed Transform.

Answer

Shai picture Shai · May 9, 2017

MikeE's answer is quite good: using dilation and erosion morphological operations can help a lot in this context.
I want to suggest a little improvement, taking advantage of the specific structure of the image at hand. Instead of using dilation/erosion with a general kernel, I suggest using a horizontal kernel that will connect the endpoints of the horizontal lines, but will not connect adjacent lines to one another.

Here's a sketch of code (assuming the input image is stored in 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) 

What you get is the dilated image:
enter image description here

Note how the gaps are closed, while maintaining the distinct horizontal lines

And the eroded image:
enter image description here

To remove artifacts created by dilate/erode, I suggest to extract the skeleton again.
If you further apply skeleton morphological operation to the eroded image you can get this result:
enter image description here

Once you have the curves connected you do not need to use watershed segmentation, but rather use connected components to label each curve.