Python OpenCV 读取USB摄像头报错问题解决

报错信息:

Traceback (most recent call last):
  File "G:\Python图像识别相关学习视频\人体姿势检测.py", line 32, in <module>
    cv2.imshow('image_title',img)
cv2.error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\highgui\src\window.cpp:967: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'

 软件环境:

Python 3.8.10

opencv 4.6.0.66

硬件配置:

Intel Core i3-6100 @ 3.7GHz

内存8G

集显

USB摄像头

问题代码:

import cv2
cap = cv2.VideoCapture(0) # 读摄像头

# 设置图像大小640*480
cap.set(3,640)
cap.set(4,480)

while cap.isOpened():
    ret, img = cap.read()
    cv2.imshow('image_title',img)

    if cv2.waitKey(50) & 0xFF == ord('q'):
        cap.release()
        break
cv2.destroyAllWindows()

问题排查:

从报错信息来看,它提示size.width>0 && size.height>0 in function 'cv::imshow',可以看出,是imshow这个函数出问题,这个是显示图像的函数,既然出错,一般问题在于输入参数有问题,再往前看,size.width>0 && size.height>0,可以推测,是输入的图像数据宽度或高度为0,即变量img为空。

因此,检查变量img的来源,img来自这句:

ret, img = cap.read()

ret表示是否读取成功,若成功则返回True,若失败则返回False。img即为读取到的图像数据。既然img为空,说明此时ret应该是False,即读取图像数据失败。

我们再接着往上追溯,看看cap来自哪里,cap是一个VideoCapture对象,来自这句话:

cap = cv2.VideoCapture(0)

这里cv2.VideoCapture(0),其中参数0表示USB摄像头ID是0。接下来你可以试试cap.isOpened()是否返回True,如果不是,说明你的USB摄像头ID不是0,你可以换其他数字1、2、3等试试,直到cap.isOpened()返回True。

我这边cap.isOpened()返回True,说明此时摄像头已被正常打开。

那么问题来了,既然USB摄像头正常打开了(我的USB摄像头工作指示灯也亮起了),那为什么读取不到图像数据呢?

我检查了Python环境、USB摄像头硬件、代码语句等,折腾了好久,也百度了一大堆,依旧无头绪,硬件没问题,环境也没问题,网络上大家代码也写的大同小异……

问题解决:

最终问题还是解决了,于是,就有了本篇博客,给各位玩图像识别的朋友避避坑!

问题就出在这句话:

cap = cv2.VideoCapture(0)

我们在创建cap这个对象时,只指定摄像头ID,没有指定第二个参数apiPreference,当第二个参数没指定时,它默认是cv2.CAP_ANY,因此导致无法正确读取USB摄像头数据。(早期版本的OpenCV也许可以,毕竟网络上的参考代码,大部分都是不指定第二个参数的。另外,笔记本自带的摄像头应该也可以不指定第二个参数。)

我添加第二个参数为cv2.CAP_DSHOW,解决问题,更改后的语句如下:

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

已经可以正常读取USB摄像头数据了。

至此问题解决!

再来一遍修改后的完整代码:

import cv2
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW) # 读摄像头

# 设置图像大小640*480
cap.set(3,640)
cap.set(4,480)

while cap.isOpened():
    ret, img = cap.read()
    cv2.imshow('image_title',img)

    if cv2.waitKey(50) & 0xFF == ord('q'):
        cap.release()
        break
cv2.destroyAllWindows()

希望可以帮助到各位遇到同样问题的小可爱们~

也欢迎到我小破站留言交流:space.bilibili.com/14596169

猜你喜欢

转载自blog.csdn.net/daochengzhuke/article/details/127913562