Python 如何正确检查摄像机是否可用?

Python 如何正确检查摄像机是否可用?,python,opencv,Python,Opencv,我正在使用OpenCV打开和阅读几个网络摄像头。这一切都很好,但我似乎找不到一种方法来知道是否有相机 我尝试了此代码(cam 2不存在): 但这只是打印了很多错误: VIDEOIO ERROR: V4L: index 2 is not correct! failed to open /usr/lib64/dri/hybrid_drv_video.so Failed to wrapper hybrid_drv_video.so failed to open /usr/lib64/dri/hybri

我正在使用OpenCV打开和阅读几个网络摄像头。这一切都很好,但我似乎找不到一种方法来知道是否有相机

我尝试了此代码(cam 2不存在):

但这只是打印了很多错误:

VIDEOIO ERROR: V4L: index 2 is not correct!
failed to open /usr/lib64/dri/hybrid_drv_video.so
Failed to wrapper hybrid_drv_video.so
failed to open /usr/lib64/dri/hybrid_drv_video.so
Failed to wrapper hybrid_drv_video.so
GStreamer Plugin: Embedded video playback halted; module v4l2src0 reported: Internal data stream error.
OpenCV Error: Unspecified error (GStreamer: unable to start pipeline
) in cvCaptureFromCAM_GStreamer, file /builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_gstreamer.cpp, line 832
VIDEOIO(cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, reinterpret_cast<char *>(index))): raised OpenCV exception:

/builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_gstreamer.cpp:832: error: (-2) GStreamer: unable to start pipeline
 in function cvCaptureFromCAM_GStreamer

OpenCV Error: Unspecified error (unicap: failed to get info for device
) in CvCapture_Unicap::initDevice, file /builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_unicap.cpp, line 139
VIDEOIO(cvCreateCameraCapture_Unicap(index)): raised OpenCV exception:

/builddir/build/BUILD/opencv-3.2.0/modules/videoio/src/cap_unicap.cpp:139: error: (-2) unicap: failed to get info for device
 in function CvCapture_Unicap::initDevice

CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate production trees: Can't create any node of the requested type!
<VideoCapture 0x7fa5b5de0450>
视频IO错误:V4L:索引2不正确! 无法打开/usr/lib64/dri/hybrid_drv_video.so 未能包装hybrid_drv_video.so 无法打开/usr/lib64/dri/hybrid_drv_video.so 未能包装hybrid_drv_video.so GStreamer插件:嵌入式视频播放暂停;模块v4l2src0报告:内部数据流错误。 OpenCV错误:未指定的错误(GStreamer:无法启动管道 )在cvCaptureFromCAM_GStreamer中,文件/builddir/build/build/opencv-3.2.0/modules/videoio/src/cap_GStreamer.cpp,第832行 VIDEOIO(cvCreateCapture\u GStreamer(CV\u CAP\u GStreamer\u V4L2,重新解释(索引)):引发OpenCV异常: /builddir/build/build/opencv-3.2.0/modules/videoio/src/cap_gstreamer.cpp:832:错误:(-2)gstreamer:无法启动管道 功能内cvCaptureFromCAM\u GStreamer OpenCV错误:未指定的错误(unicap:无法获取设备的信息 )在CvCapture_Unicap::initDevice中,文件/builddir/build/build/opencv-3.2.0/modules/videoio/src/cap_Unicap.cpp,第139行 VIDEOIO(cvCreateCameraCapture_Unicap(索引)):引发OpenCV异常: /builddir/build/build/opencv-3.2.0/modules/videoio/src/cap_unicap.cpp:139:错误:(-2)unicap:无法获取设备的信息 函数中的CvCapture_Unicap::initDevice CvCapture\u OpenNI::CvCapture\u OpenNI:枚举生产树失败:无法创建所请求类型的任何节点! 没有抛出异常。稍后使用
c.read()
时,我确实会得到
False
,但我希望在程序的初始化阶段这样做


那么,我如何找出我有多少个有效的摄像头,或者检查某个数字是否“映射”到一个有效的摄像头

使用cv2.VideoCapture(无效设备号)不会引发异常。它构造了一个包含无效设备的
——如果使用它,就会出现异常

测试构造的对象的
None
not isOpened()
以清除无效对象


对我来说,这是可行的(1台笔记本电脑摄像设备):

输出1:

Warning: unable to open video source:  1
示例来自: 第159ff行


Linux中提供的另一个解决方案是在
VideoCapture()
调用中使用
/dev/videoX
设备。当凸轮插入时,这些装置就在那里。与
glob()
一起,获得所有摄像头非常简单:

import cv2, glob

for camera in glob.glob("/dev/video?"):
    c = cv2.VideoCapture(camera)
当然,需要使用
isOpened()
c
进行检查,但您确定只扫描可用的摄像头。

您可以尝试以下代码:

from __future__ import print_function
import numpy as np
import cv2

# detect all connected webcams
valid_cams = []
for i in range(8):
    cap = cv2.VideoCapture(i)
    if cap is None or not cap.isOpened():
        print('Warning: unable to open video source: ', i)
    else:
        valid_cams.append(i)

caps = []
for webcam in valid_cams:
    caps.append(cv2.VideoCapture(webcam))

while True:
    # Capture frame-by-frame
    for webcam in valid_cams:
        ret, frame = caps[webcam].read()
        # Display the resulting frame
        cv2.imshow('webcam'+str(webcam), frame)
    k = cv2.waitKey(1)
    if k == ord('q') or k == 27:
        break

# When everything done, release the capture
for cap in caps:
    cap.release()

cv2.destroyAllWindows()
这里有一个“不工作”的解决方案,可以帮助您避免在这个陷阱中翻倒:

将cv2作为cv导入
导入PySpin
打印(简历版本)
#Patrick Artner提供的解决方案,可用于除
#灰点(FLIR)的那些。
def测试设备(来源):
cap=cv.VideoCapture(源)
如果cap为None或not cap.isOpened():
打印('警告:无法打开视频源:',源)
# ... PySpin/Spinnaker(包装器/SDK库)。。。
system=PySpin.system.GetInstance()
cam\u list=system.GetCameras()
凸轮=“”
凸轮数=0
对于ID,枚举中的cam(cam列表):
#检索TL设备节点映射
如果ID==cam_num:
打印('有摄像头')
凸轮=凸轮
cam.Init()
# ... CV2再一次。。。
对于范围(10)内的i:
测试设备(i)#无打印输出

“未引发异常”:是的,因为您捕获了所有未处理的异常。始终只捕获您愿意处理的异常。@AndrasDeak从未显示
打印“Cam 2无效”
。啊,这让它更有趣(但我支持我前面的陈述)。那么…它会打印什么样的错误?请阅读并确认:P@AndrasDeak添加
import cv2
是制造此MCV所需的全部。我还添加了错误。Úsing
cv2。VideoCapture(无效设备号)
不会引发异常。它构造了一个包含无效设备的
——如果使用它,就会出现异常。测试构造的对象的
None
not IsOpen()
以清除无效对象。请参阅代码示例的答案。“不存在的设备”是这个问题的核心:如何判断给定源ID的设备是否不可用。@AndrasDeak必须首先安装opencv来测试它-对我来说,它可以工作-不会崩溃opencv_contrib的示例不检查
cv2.VideoCapture()是否可用
返回
None
-它检查
classes.get(params.get('class',None),VideoSynthBase)是否为None
。看看整个情况:建议的解决方案不适用于点灰(FLIR)相机。我的
cam.Init()
想法也没有发布在这里。我在实践中发现
cv::VideoCapture()
在某些情况下会抛出异常(OpenCV 3.1.0,因为升级很困难)。当心。点灰FLIR相机有什么特别之处?我也是其中之一-这种解决方案对这种相机有效吗(使用PySpin包装器?)这种相机对cv2有用吗?我还不知道,我们正在努力解决这个问题。我已经从PyCapture2迁移到PySpin,但丢失了CameraPoveron/OFF等功能。我在另一个Q/a会话中描述了一个
isValid()
测试,它或多或少起到了作用(读:拼凑),但是读/写注册器函数在这里是一个失败的例子。就我现在所见,它们使用GENiCAM结构化命名/框架,因此可以处理节点和活动摄影机实例(如所提供的代码所示)。事实上,我有点震惊CV2在镜头中无法将手指放在门后。也许你应该提出你自己的问题-这似乎不是答案
cap = cv.VideoCapture(source)
    if 'size' in params:
        w, h = map(int, params['size'].split('x'))
        cap.set(cv.CAP_PROP_FRAME_WIDTH, w)
        cap.set(cv.CAP_PROP_FRAME_HEIGHT, h)
if cap is None or not cap.isOpened():
    print 'Warning: unable to open video source: ', source
import cv2, glob

for camera in glob.glob("/dev/video?"):
    c = cv2.VideoCapture(camera)
from __future__ import print_function
import numpy as np
import cv2

# detect all connected webcams
valid_cams = []
for i in range(8):
    cap = cv2.VideoCapture(i)
    if cap is None or not cap.isOpened():
        print('Warning: unable to open video source: ', i)
    else:
        valid_cams.append(i)

caps = []
for webcam in valid_cams:
    caps.append(cv2.VideoCapture(webcam))

while True:
    # Capture frame-by-frame
    for webcam in valid_cams:
        ret, frame = caps[webcam].read()
        # Display the resulting frame
        cv2.imshow('webcam'+str(webcam), frame)
    k = cv2.waitKey(1)
    if k == ord('q') or k == 27:
        break

# When everything done, release the capture
for cap in caps:
    cap.release()

cv2.destroyAllWindows()