OpenCV 3.1 drawContours '(-215) npoints > 0

2020-06-03 05:24发布

问题:

I'm trying to create a mask from a contour, but am getting a C++ error.

Using OS X Yosemite, Python 2.7.10, OpenCV 3.1.0.

def create_mask(img, cnt):
    '''Create a mask of the same size as the image
       based on the interior of the contour.'''
    mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
    print("create_mask, cnt=%s" % cnt)
    cv2.drawContours(mask, [cnt], 0, (0, 255, 0), -1)
    return mask

print("Creating mask from contour %s, on raw shape %s" % (page_contour, raw.shape))
page_mask = create_mask(raw, page_contour)

Output (see bottom for error):

Creating mask from contour [[ 1626.   360.]
 [ 1776.  3108.]
 [  126.  3048.]
 [  330.   486.]], on raw shape (3840, 2160, 3)
create_mask, cnt=[[ 1626.   360.]
 [ 1776.  3108.]
 [  126.  3048.]
 [  330.   486.]]
OpenCV Error: Assertion failed (npoints > 0) in drawContours, file /tmp/opencv320160309-92782-1efch74/opencv-3.1.0/modules/imgproc/src/drawing.cpp, line 2380
Traceback (most recent call last):
  File "./books.py", line 209, in <module>
    page_mask = create_mask(raw, page_contour)
  File "./books.py", line 123, in create_mask
    cv2.drawContours(mask, [cnt], 0, (0, 255, 0), -1)
cv2.error: /tmp/opencv320160309-92782-1efch74/opencv-3.1.0/modules/imgproc/src/drawing.cpp:2380: error: (-215) npoints > 0 in function drawContours

The docs say it should get an array of arrays and this is seemingly what I'm giving it. So what's wrong?

Code is ported from OpenCV 2.x.

回答1:

I think you are adding extra [] around cnt it should be

cv2.drawContours(mask, cnt, 0, (0, 255, 0), -1)

as cnt is already array of array but [cnt] is array of array of arrays which won't work


Update to the above code

you should convert your contour to numpy array first

ctr = numpy.array(cnt).reshape((-1,1,2)).astype(numpy.int32)
cv2.drawContours(mask, [ctr], 0, (0, 255, 0), -1)

check documentation here

contours is a Python list of all the contours in the image. Each individual contour is a Numpy array of (x,y) coordinates of boundary points of the object.



回答2:

For me this worked. But I'm not sure why.

cv2.drawContours(mask, [cnt.astype(int)], 0, (0, 255, 0), -1)

When you get an array of rounded floats from findContours, drawContours doesn't complain. But when I construct a similar (4,2) array of floats myself, it complains.



回答3:

You might have commited mistake while finding the contours. Contour is the second value returned by findContours() function as the docs say

im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

So the following code will not work

cnt = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

This might solve your problem.



回答4:

If you just use this, it will work...

ctr = np.array(cnt).reshape((-1,1,2)).astype(np.int32)
cv2.drawContours(mask, [ctr], -1, 255, -1)


回答5:

its hierarchy, contours so:

contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)