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'
问题根源
这个错误的核心原因有两个,其中第一个是最可能触发你当前问题的:
- OpenCV版本的返回值不匹配:在OpenCV 3.x及以上版本(你用的是4.0.0),
cv2.findContours的返回值是(contours, hierarchy),但你写的是_, contours = ...,这导致你把层级信息(hierarchy)赋值给了contours变量,而真正的轮廓数据被丢弃了。遍历这样的"假轮廓"自然会出现空点的错误。 - 未处理无效帧:当视频读取到末尾时,
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
相关产品推荐
相关产品推荐

