Ask Your Question

In Python, how can I reduce a list of contours to those of a specified size?

asked 2015-06-27 18:50:50 -0500

mattroos gravatar image

updated 2015-06-27 18:52:02 -0500

I've extracted contours from an image and now want to discard those that don't match a specified size requirement. But I'm new to Python and can't figure out how to do this efficiently. I can get a list of booleans that identify which contours should be retained, but how can I generate the new list of contours in a simple, single line? E.g., what's the right way to code the final line below? Thanks!

contours, hierarchy = cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

brect = np.array([list(cv2.boundingRect(cnt)) for cnt in contours])

widths = brect[:,2]

heights = brect[:,3]

bUse = (widths<widthmax) &amp;="" (heights<heightmax)="" &amp;="" (widths="">widthMin) & (heights>heightMin)

contours = contours[bUse] # DOESN'T WORK! WHY?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2015-06-27 23:05:11 -0500

updated 2015-06-28 01:32:15 -0500

I am not sure if this would work for you but you can make use of contourArea method to get contour area and filter out some small contours on a basis of that. Here is the link.. Example code as below:

threshold_area = 10000     #threshold area 
contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)   
for cnt in contours:        
    area = cv2.contourArea(cnt)         
    if area > threshold_area:                   
         #Put your code in here

Another elegant solution would be get a minimum area rect and get width and height from rect's 4 coordinates (by calculating distance on your own). But I'm not sure if you're using it to detect regular shaped contours and not.

And as far as I understand, you code should be rearranged as follow for it to work:

contours, hierarchy = cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours
    rect = cv2.minAreaRect(cnt)       #I have used min Area rect for better result
    width = rect[1][0]
    height = rect[1][1]
    if (width<widthmax) and (height <heightmax) and (width >= widthMin) and (height > heightMin):
        #put your code here if desired contour is detected

Hope it helps.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2015-06-27 18:50:50 -0500

Seen: 14,454 times

Last updated: Jun 28 '15