立即从OpenCV中的两台摄像机读取数据

如何使用Python API同时(或几乎)使用OpenCV从两台或更多台摄像机捕获视频?

我有三个网络摄像头,都可以进行视频流传输,位于/ dev / video0,/ dev / video1和/ dev / video2。

以该教程为例,从单个相机捕​​捉图像很简单:

import cv2
cap0 = cv2.VideoCapture(0)
ret0, frame0 = cap0.read()
cv2.imshow('frame', frame0)
cv2.waitKey()

这工作正常。

但是,如果我尝试初始化第二个摄像头,试图从它read()返回None:

import cv2
cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
ret0, frame0 = cap0.read()
assert ret0 # succeeds
ret1, frame1 = cap1.read()
assert ret1 # fails?!

为了确保我不会无意中给OpenCV一个糟糕的相机索引,我单独测试了每个相机索引,并且它们都是独立工作的。 例如

import cv2
#cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
#ret0, frame0 = cap0.read()
#assert ret0
ret1, frame1 = cap1.read()
assert ret1 # now it works?!

我究竟做错了什么?

编辑:我的硬件是运行Ubuntu的Macbook Pro。 在MacBook上专门研究这个问题,我发现其他人也遇到了这个问题,无论是在OSX上还是在不同类型的相机上。 如果我访问iSight,代码中的两个调用都会失败。


是的,你肯定受USB带宽的限制。 尝试从全部设备读取这两个设备时,可能会出错:

libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device
Traceback (most recent call last):
  File "p.py", line 7, in <module>
    assert ret1 # fails?!
AssertionError

然后当你将res缩小到160x120时:

import cv2
cap0 = cv2.VideoCapture(0)
cap0.set(3,160)
cap0.set(4,120)
cap1 = cv2.VideoCapture(1)
cap1.set(3,160)
cap1.set(4,120)
ret0, frame0 = cap0.read()
assert ret0 # succeeds
ret1, frame1 = cap1.read()
assert ret1 # fails?!

现在它似乎工作! 我敢打赌,你有两个凸轮连接在同一张USB卡上。 您可以运行lsusb命令来确认,并且它应该显示如下内容:

Bus 001 Device 006: ID 046d:081b Logitech, Inc. Webcam C310
Bus 001 Device 004: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 001 Device 007: ID 046d:0990 Logitech, Inc. QuickCam Pro 9000
Bus 001 Device 005: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 001 Device 003: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 001 Device 002: ID 1058:0401 Western Digital Technologies, Inc. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

(请注意同一总线上的两台摄像机。)如果可能,您可以将另一张USB卡添加到您的机器以获得更多带宽。 为了在一台机器上以全分辨率运行多个摄像头,我之前完成了此操作。 虽然这是一个带有可用主板插槽的塔式工作站,但不幸的是,您可能没有在MacBook笔记本电脑上使用该选件。


我使用“imutils”并在图像上阅读网络摄像头显示。

导入imutils

捕捉视频帧

--- WebCam1

cap = cv2.VideoCapture(0)cap.set(cv2.CAP_PROP_FRAME_WIDTH,300)cap.set(cv2.CAP_PROP_FRAME_HEIGHT,300)

--- WebCam2

cap1 = cv2.VideoCapture(1)cap1.set(cv2.CAP_PROP_FRAME_WIDTH,300)cap1.set(cv2.CAP_PROP_FRAME_HEIGHT,300)

--- WebCam3

cap2 = cv2.VideoCapture(2)cap2.set(cv2.CAP_PROP_FRAME_WIDTH,300)cap2.set(cv2.CAP_PROP_FRAME_HEIGHT,300)

--- WebCame4

cap3 = cv2.VideoCapture(3)cap3.set(cv2.CAP_PROP_FRAME_WIDTH,300)cap3.set(cv2.CAP_PROP_FRAME_HEIGHT,300)

我创建函数read_frame()发送关于Image.fromarray的参数并显示

def read_frame():webCameShow(cap.read(),display1)webCameShow(cap1.read(),display2)webCameShow(cap2.read(),display6)webCameShow(cap3.read(),display7)
window.after(10,read_frame)

和最终功能展示视频上的“imageFrame”

def webCameShow(N,Display):_,frameXX = N cv2imageXX = cv2.cvtColor(frameXX,cv2.COLOR_BGR2RGBA)imgXX = Image.fromarray(cv2imageXX)#imgtkXX = ImageTk.PhotoImage(image = imgXX)Display.imgtk = imgtkXX Display .configure(图像= imgtkXX)

例。 4-摄像头

油管油管


使用OPENCV和两个标准的USB摄像头,我可以使用多线程来实现这一点。 本质上,定义一个打开opencv窗口和VideoCapture元素的函数。 然后,创建两个线程,将摄像机ID和窗口名称作为输入。

import cv2
import threading

class camThread(threading.Thread):
    def __init__(self, previewName, camID):
        threading.Thread.__init__(self)
        self.previewName = previewName
        self.camID = camID
    def run(self):
        print "Starting " + self.previewName
        camPreview(self.previewName, self.camID)

def camPreview(previewName, camID):
    cv2.namedWindow(previewName)
    cam = cv2.VideoCapture(camID)
    if cam.isOpened():  # try to get the first frame
        rval, frame = cam.read()
    else:
        rval = False

    while rval:
        cv2.imshow(previewName, frame)
        rval, frame = cam.read()
        key = cv2.waitKey(20)
        if key == 27:  # exit on ESC
            break
    cv2.destroyWindow(previewName)

# Create two threads as follows
thread1 = camThread("Camera 1", 1)
thread2 = camThread("Camera 2", 2)
thread1.start()
thread2.start()

学习如何在python中进行线程的很好的资源:https://www.tutorialspoint.com/python/python_multithreading.htm

链接地址: http://www.djcxy.com/p/83783.html

上一篇: Reading from two cameras in OpenCV at once

下一篇: Opencv doesn't detect firewire webcam on linux