KevinR
KevinR

Reputation: 13

How can I fill gaps in a binary image in OpenCV?

I have some thresholded images of hand-drawn figures (circuits) but there are some parts where I need to have gaps closed between two points, as I show in the following image:

Binary image

I tried closing (dilation followed by erosion), but it is not working. It doesn't fill the gaps and makes the resistors and other components unrecognizable. I couldn't find a proper value for the morph size and number of iterations that give me a good result without affecting the rest of the picture. It's important not to affect too much the components. I can't use hough lines because the gaps are not always in lines.

Result after closing:

Result after closing

int morph_size1 = 2;
Mat element1 = getStructuringElement(MORPH_RECT, Size(2 * morph_size1 + 1, 2 * morph_size1 + 1), Point(morph_size1, morph_size1));
Mat dst1; // result matrix
for (int i = 1; i<3; i++)
{
    morphologyEx(binary, dst1, CV_MOP_CLOSE, element1, Point(-1, -1), i);

}

imshow("closing ", dst1);

Any idea? Thanks in advance.

Upvotes: 0

Views: 1825

Answers (2)

user1196549
user1196549

Reputation:

My proposal:

  • find the endpoints of the breaks by means of morphological thinning (select the white pixels having only one white neighbor);

  • in small neighborhoods around every endpoint, find the closest endpoint, by circling* up to a limit radius;

  • draw a thick segment between them.

*In this step, it is very important to look for neighbors in different connected component, to avoid linking a piece to itself; so you need blob labelling as well.

enter image description here

enter image description here

In this thinning, there are more breaks than in your original picture because I erased the boxes.

Of course, you draw the filling segments in the original image.

This process cannot be perfect, as sometimes endpoints will be missing, and sometimes unwanted endpoints will be considered.

As a refinement, you can try and estimate the direction at endpoints, and only search is an angular sector.

Upvotes: 2

My suggestion is to use a custom convolution filter (cv::filter2D) like the one below (can be larger):

0 0 1/12 0 0 
0 0 2/12 0 0 
1/12 2/12 0 2/12 1/12
0 0 2/12 0 0
0 0 1/12 0 0 

The idea is to fill gaps when there are two line segments near each other. You can also use custom structuring elements to obtain the same effect.

Upvotes: 0

Related Questions