OpenCV图像采集脚本报错:Camera index out of range与cv::imshow断言失败求助
问题
运行OpenCV图像采集脚本时出现两个连续错误:
- 先抛出
Camera index out of range(摄像头索引超出范围)提示 - 执行到
cv2.imshow时触发断言错误:cv2.error: OpenCV(4.7.0) ... (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
脚本代码
import os import cv2 DATA_DIR = './data' if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) number_of_classes = 3 dataset_size = 100 cap = cv2.VideoCapture(2) for j in range(number_of_classes): if not os.path.exists(os.path.join(DATA_DIR, str(j))): os.makedirs(os.path.join(DATA_DIR, str(j))) print('Collecting data for class {}'.format(j)) done = False while True: ret, frame = cap.read() if ret: cv2.putText(frame, 'Ready? Press "Q" ! :)', (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.3, (0, 255, 0), 3, cv2.LINE_AA) cv2.imshow('frame', frame) if cv2.waitKey(25) == ord('q'): break else: break counter = 0 while counter < dataset_size: ret, frame = cap.read() cv2.imshow('frame', frame) cv2.waitKey(25) cv2.imwrite(os.path.join(DATA_DIR, str(j), '{}.jpg'.format(counter)), frame) counter += 1 cap.release() cv2.destroyAllWindows()
报错信息
[ERROR:0@0.156] global obsensor_uvc_stream_channel.cpp:156 cv::obsensor::getStreamChannelGroup Camera index out of range out of range Collecting data for class 0 Traceback (most recent call last): File "d:\Final Year Project\Proj_By_Me\collect_imgs.py", line 26, in <module> cv2.imshow('frame', frame) (-215:Assertion f cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-python\opencv\modules\highgui\src\window.cpp:971: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
解决方案
问题根源
- 摄像头索引无效:
cv2.VideoCapture(2)指定的索引2不存在,导致无法打开摄像头,cap.read()返回的ret为False,frame是空值 - 未校验帧读取状态:不管是否成功读取到帧,直接调用
cv2.imshow,空帧触发断言错误 - 循环逻辑错误:第一个
while循环会直接break,用户根本看不到准备提示语,无法触发采集确认
修复步骤
1. 修正摄像头索引
摄像头索引通常从0开始,优先尝试0,失败再试1:
cap = cv2.VideoCapture(0) if not cap.isOpened(): cap = cv2.VideoCapture(1) if not cap.isOpened(): raise RuntimeError("无法检测到可用摄像头,请检查设备连接")
2. 强制校验帧读取状态
每次调用cap.read()后,必须判断ret是否为True,仅在读取到有效帧时才执行显示、保存操作
3. 修复准备循环逻辑
原循环会直接退出,改为等待用户按下q才开始采集:
while True: ret, frame = cap.read() if ret: cv2.putText(frame, 'Ready? Press "Q" to start! :)', (80, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3, cv2.LINE_AA) cv2.imshow('frame', frame) if cv2.waitKey(25) == ord('q'): break
4. 保存图片前加校验
避免保存空帧导致无效文件:
while counter < dataset_size: ret, frame = cap.read() if ret: cv2.imshow('frame', frame) cv2.imwrite(os.path.join(class_dir, f'{counter}.jpg'), frame) counter += 1 cv2.waitKey(25)
修正后的完整代码
import os import cv2 DATA_DIR = './data' if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) number_of_classes = 3 dataset_size = 100 # 尝试打开摄像头,优先索引0,再试1 cap = cv2.VideoCapture(0) if not cap.isOpened(): cap = cv2.VideoCapture(1) if not cap.isOpened(): raise RuntimeError("无法检测到可用摄像头,请检查设备连接") for j in range(number_of_classes): class_dir = os.path.join(DATA_DIR, str(j)) if not os.path.exists(class_dir): os.makedirs(class_dir) print(f'Collecting data for class {j}') # 等待用户准备 while True: ret, frame = cap.read() if ret: cv2.putText(frame, 'Ready? Press "Q" to start! :)', (80, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3, cv2.LINE_AA) cv2.imshow('frame', frame) # 按下q开始采集 if cv2.waitKey(25) == ord('q'): break counter = 0 while counter < dataset_size: ret, frame = cap.read() if ret: cv2.imshow('frame', frame) cv2.imwrite(os.path.join(class_dir, f'{counter}.jpg'), frame) counter += 1 cv2.waitKey(25) cap.release() cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Dacron
相关产品推荐
相关产品推荐

