Opencv findContours() and drawContours() show hollow contours

Viewed 70

enter image description here enter image description here

the left is "plane.png", the right is "plane_contours.png". I want to get filled contours without the inner hollow gaps between two lines in the right image.

In other words, I only need the contours of one line.

My code:

img = cv2.imread('plane.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray[(gray >= 120)] = 255
gray[(gray < 120)] = 0
cv2.imwrite('plane_gray.png', gray)
con, _ = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
img = np.zeros(img.shape).astype(np.uint8)
for i in range(len(con)):
    cv2.drawContours(img, [con[i]], 0, [255, 255, 255], 1)
    # plt.imshow(img)
    # plt.show()
cv2.imwrite('plane_contours.png', img)

I tried to set thickness to -1

cv2.drawContours(img, [con[i]], 0, [255, 255, 255], -1)

And result is

enter image description here

I also set range(len(con)) to range(len(con) - 1) to avoid final filling which will make whole image the same color.

But one window and one wing of plane has been filled which is not what I want.

How can I get the correct image?

Any help is appreciated.

UPDATE:

I tried RETR_CCOMP. But if I only take outer contours or inner contours, those contours are disconnected.

For example:

enter image description here original image

enter image description here RETR_LIST

enter image description here RETR_CCOMP

1 Answers

Its about the retrieval mode you are using. You chose the RETR_LIST which means:

retrieves all of the contours without establishing any hierarchical relationships.

So even in your input image a line looks like only one, it is not one; it includes one contour outer one is inner. There are 2 retrieval modes can solve your problem. RETR_EXTERNAL and RETR_CCOMP. According to the documentation:

RETR_EXTERNAL: retrieves only the extreme outer contours. It sets hierarchy[i][2]=hierarchy[i][3]=-1 for all the contours.

This method will eliminate the inner lines.

RETR_CCOMP: retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.

This will give you the contours in a hierarchical order. The point is that it only gives 1 parent 1 child. So you can use this info to get rid of inner or outer contours.

Related