Error: (-215:Assertion failed) npoints > 0 while working with contours using OpenCV

Error: (-215:Assertion failed) npoints > 0 while working with contours using OpenCV

当我运行这段代码时:

import cv2

image = cv2.imread('screenshoot10.jpg')
cv2.imshow('input image', image)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

edged = cv2.Canny(gray, 30, 200)
cv2.imshow('canny edges', edged)

_, contours = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.imshow('canny edges after contouring', edged)

print(contours)
print('Numbers of contours found=', len(contours))

cv2.drawContours(image, contours, -1, (0, 255, 0), 3)
cv2.imshow('contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

我收到这个错误:

OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\imgproc\src\drawing.cpp:2509: error: (-215:Assertion failed) npoints > 0 in function 'cv::drawContours'

我做错了什么?

根据documentation for findContours,方法returns(contours, hierarchy),所以我认为代码应该是:

contours, _ = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

而不是

_, contours = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

根据 OpenCV 版本,cv2.findContours() 具有不同的 return 签名。在 v3.4.X 中,return 编辑了三个项目。

image, contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

v2.Xv4.1.X 中,有两项 returned。

contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

无论版本如何,您都可以轻松获取轮廓:

cnts = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    ...

由于最后两个值始终相同,我们可以使用 [-2:] 进一步将其压缩成一行,以从 return 由 cv2.findContours() 编辑的元组中提取轮廓。 =20=]

cnts, _ = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]

因为在查找 Error: (-215:Assertion failed) npoints > 0 while working with contours using OpenCV 时这个问题出现在最前面,所以我想指出另一个可能的原因来说明为什么会出现这个错误:

我在执行 minAreaRect 之后使用 BoxPoints 函数来获得围绕轮廓旋转的矩形。在将它传递给 drawContours 之前,我没有对其输出进行 np.int0 (将返回的数组转换为整数值)。这修复了它:

rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect) 
box = np.int0(box) # convert to integer values
cv2.drawContours(im,[box],0,(0,0,255),2)

此处提供的所有解决方案要么针对特定版本是固定的,要么不存储从 cv2.findContours() 返回的所有值。您可以存储从函数的每个元组返回的所有值,而与 cv2.

的版本无关

无论您 system/environment 中安装的 OpenCV 版本如何,以下代码片段都可以工作,并且还将所有元组存储在单个变量中。

首先,安装 OpenCV 的版本(我们不希望整个版本只是主版本号 3 或 4 ) :

import cv2
version = cv2.__version__[0]

根据版本,将执行以下两个语句之一并填充相应的变量:

if version == '4':
    contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

elif version == '3':
    img, contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

在任一场景中从函数返回的轮廓将存储在 contours

Note: the above snippet is written assuming either version 3 or 4 of OpenCV is installed. For older versions, please refer to the documentation or update to the latest.

如果您使用的是 OpenCV 版本 4,并且想知道版本 3 的 cv2.findContours() 返回的第一个变量是什么;它与输入图像相同(在本例中 binary_image)。