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

OpenCV图像采集脚本报错:Camera index out of range与cv::imshow断言失败求助

问题

运行OpenCV图像采集脚本时出现两个连续错误:

  1. 先抛出Camera index out of range(摄像头索引超出范围)提示
  2. 执行到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'

解决方案

问题根源

  1. 摄像头索引无效:cv2.VideoCapture(2)指定的索引2不存在,导致无法打开摄像头,cap.read()返回的ret为False,frame是空值
  2. 未校验帧读取状态:不管是否成功读取到帧,直接调用cv2.imshow,空帧触发断言错误
  3. 循环逻辑错误:第一个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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:17:43