Reputation: 975
is there an easy and direct way to extract the internal contours (holes) from an image using opencv 3.1 python ?
I know that I can use "area" as a condition. However, if I change the image resolution, the "areas" are not the same.
For instance, with this image: How can I extract the internal holes?
_, contours, hier_ = cv2.findContours(img,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in millCnts]
max_area = np.max(areas)
Mask = np.ones(img.shape[:2], dtype="uint8") * 255
# I can do something like this (currently not working, just to show an example)
for c in contours:
if(( cv2.contourArea(c) > 8) and (cv2.contourArea(c)< 100000)):
cv2.drawContours(Mask ,[c],-1,0,1)
Upvotes: 2
Views: 11806
Reputation: 11420
As I explained in my comment, you have to check the hierarchy return variable. After find contours you will get the contours (List of List of Points) and hierarchy (List of List).
The documentation is very clear in this:
hierarchy – Optional output vector, containing information about the image topology. It has as many elements as the number of contours. For each i-th contour contours[i] , the elements
hierarchy[i][0]
,hiearchy[i][1]
,hiearchy[i][2]
, andhiearchy[i][3]
are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.
So, this means that for each countour[i]
you should get a hierarchy[i]
that contains a List with 4 variables:
hierarchy[i][0]
: the index of the next contour of the same levelhierarchy[i][1]
: the index of the previous contour of the same levelhierarchy[i][2]
: the index of the first child hierarchy[i][3]
: the index of the parentSo, saying that, in your case, there should be one without a parent, and you can check which one by checking the hierarchy[i][3]
if it is negative.
It should be something like (untested code):
holes = [contours[i] for i in range(len(contours)) if hierarchy[i][3] >= 0]
* UPDATE:*
To summarize what we discussed in the chat,
Upvotes: 7