You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV drawContours报错:眼动检测Python代码运行异常

解决cv2.drawContours报错:Assertion failed (npoints > 0)

问题背景

你跟着教程编写眼动检测代码时遇到了cv2.drawContours的断言错误,报错提示npoints > 0,这说明代码在尝试绘制一个没有任何点的空轮廓。我们来一步步排查并解决问题。

你的代码

import cv2
import numpy
cap = cv2.VideoCapture("C:\Users\sinsbv\Desktop\Project\Kaggle\Tutorial_Mini_Project\open_cv\eye_recording.flv")
while True:
    ret,frame = cap.read()
    roi = frame[269:795,537:1416]
    gray_roi = cv2.cvtColor(roi,cv2.COLOR_BGR2GRAY)
    gray_roi = cv2.GaussianBlur(gray_roi , (7 , 7) ,0)
    _,threshold = cv2.threshold(gray_roi,5,255,cv2.THRESH_BINARY_INV)
    _, contours = cv2.findContours ( threshold , cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE )
    for cnt in contours:
        # ctr = numpy.array(cnt).reshape((-1,1,2)).astype(numpy.int32)
        cv2.drawContours(roi,cnt , -1,(0,0,255) ,3)
    cv2.imshow("threshold" , threshold)
    cv2.imshow("gray roi" , gray_roi)
    cv2.imshow("Roi" , roi)
    key = cv2.waitKey(30)
    if key == 27:
        break
cv2.destroyAllWindows()

报错回溯

Traceback (most recent call last):
  File "C:/Users/sinsbv/Desktop/Project/Kaggle/Tutorial_Mini_Project/open_cv/open_cv.py", line 14, in 
    cv2.drawContours(roi,cnt , -1,(0,0,255) ,3)
cv2.error: OpenCV(4.0.0) C:\projects\opencv-python\opencv\modules\imgproc\src\drawing.cpp:2509: error: (-215:Assertion failed) npoints > 0 in function 'cv::drawContours'

问题根源

这个错误的核心原因有两个,其中第一个是最可能触发你当前问题的:

  1. OpenCV版本的返回值不匹配:在OpenCV 3.x及以上版本(你用的是4.0.0),cv2.findContours的返回值是(contours, hierarchy),但你写的是_, contours = ...,这导致你把层级信息(hierarchy)赋值给了contours变量,而真正的轮廓数据被丢弃了。遍历这样的"假轮廓"自然会出现空点的错误。
  2. 未处理无效帧:当视频读取到末尾时,cap.read()返回的ret为False,此时frame是无效的,后续处理得到的roi和轮廓都会出问题。

修复方案

我们针对上述问题逐一修正:

1. 修正findContours的返回值

把这一行:

_, contours = cv2.findContours ( threshold , cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE )

改成:

contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

这样你才能拿到真正的轮廓数据。

2. 增加帧有效性判断

每次读取帧后,先检查是否成功读取,如果失败就退出循环:

ret, frame = cap.read()
if not ret:
    break

3. 过滤空轮廓(额外保险)

即使前面的步骤都做了,偶尔还是可能出现空轮廓,所以在绘制前加个判断:

for cnt in contours:
    if len(cnt) > 0:
        cv2.drawContours(roi, cnt, -1, (0,0,255), 3)

4. 修复路径转义问题

Windows路径中的反斜杠会被解析成转义字符,在路径前加r可以避免这个问题:

cap = cv2.VideoCapture(r"C:\Users\sinsbv\Desktop\Project\Kaggle\Tutorial_Mini_Project\open_cv\eye_recording.flv")

完整修复后的代码

import cv2
import numpy as np  # 用np作为numpy别名更符合Python社区规范

# 加r避免路径转义问题
cap = cv2.VideoCapture(r"C:\Users\sinsbv\Desktop\Project\Kaggle\Tutorial_Mini_Project\open_cv\eye_recording.flv")

while True:
    ret, frame = cap.read()
    # 检查是否成功读取帧,失败则退出
    if not ret:
        break
    
    roi = frame[269:795,537:1416]
    # 额外检查roi是否有效(避免帧尺寸不足的情况)
    if roi.size == 0:
        continue
    
    gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
    gray_roi = cv2.GaussianBlur(gray_roi, (7,7), 0)
    _, threshold = cv2.threshold(gray_roi, 5, 255, cv2.THRESH_BINARY_INV)
    
    # 正确获取轮廓和层级信息
    contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    
    for cnt in contours:
        # 只绘制有有效点数的轮廓
        if len(cnt) > 0:
            cv2.drawContours(roi, cnt, -1, (0,0,255), 3)
    
    cv2.imshow("threshold", threshold)
    cv2.imshow("gray roi", gray_roi)
    cv2.imshow("Roi", roi)
    
    key = cv2.waitKey(30)
    if key == 27:
        break

# 释放视频捕获资源,避免内存泄漏
cap.release()
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者subin alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:51:59