Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect closed contours

Tags:

python

opencv

This is example image:

screenshot

and I use opencv to detect contours:

>>> fc = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
>>> contours = fc[0]

For detecting closed contour I thought to check start and end points in each contour returned by opencv, while I noticed that regardless the shape of object opencv seem to outline each object, so I get this result:

>>> for contour in contours:
>>>    print(contour[0,:,:], contour[-1,:,:])
[[246  38]] [[247  38]]
[[92 33]] [[93 33]]

or each found contour has closed path.

I searched for additional constants to available methods in findContour() function, but it seems all return closed paths.

So is there some general way of detecting if found contour is closed?


I googled before asking and didn't got results, but I see good candidate in similar questions at the right side: How can i know if a contour is open or closed in opencv? where it is suggested I use cv2.isContourConvex(contour), but:

>>> for contour in contours:
>>>    print(cv2.isContourConvex(contour))
False
False

yet another update: contourArea looks like it may provide answer (at least for simple contours) but I didn't tested on anything else then above example image:

>>> for contour in contours:
>>>     print(cv2.contourArea(contour))
0.0
12437.5
like image 477
theta Avatar asked Jul 05 '13 00:07

theta


People also ask

How are contours detected?

As we discussed previously, the algorithm looks for borders, and similar intensity pixels to detect the contours. A binary image provides this information much better than a single (RGB) color channel image.

How do I know if contour is closed on Opencv?

Just use findContours() in your image, then decide whether the contour is closed or not by examining the hierarchy passed to the findContours() function.

Can a contour be open?

Contours can be either open or closed. A contour must be closed to obtain measurements of the area within the contour. An open contour can be used to measure the length of a curved line.


1 Answers

I came across this problem myself and I found a work around...

Going through this..

for i in contours:
   print(cv2.contourArea(i), cv2.arcLength(i,True))

I've noticed that closed contours (e.g. circles) have a higher contourArea than arcLength, whilst open contours (e.g. lines) have a lower contourArea than arcLength, so you can filter them as such...

closed_contours = []
open_contours = []
for i in contours:
    if cv2.contourArea(i) > cv2.arcLength(i, True):
        closed_contours.append(i)
    else:
        open_contours.append(i)

I know this was asked over 3 years ago but for anybody else needing an idea this worked for me!

like image 85
Max Avatar answered Oct 08 '22 17:10

Max