Capture video from two cameras in OpenCV at the same time

How do you shoot video from two or more cameras at the same time (or almost) using OpenCV using the Python API?

I have three video streaming webcams located at / dev / video 0, / dev / video1 and / dev / video2.

Using the tutorial as an example, capturing images from a single camera is simple:

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

And it works great.

However, if I try to initialize the second camera, an attempt to read() from it returns 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?! 

Just to make sure that I didn't accidentally give OpenCV a bad camera index, I tested each camera index individually, and they all work on their own. eg.

 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?! 

What am I doing wrong?

Edit: My hardware is a Macbook Pro running Ubuntu. Studying the problem specifically for Macbooks, I found others who encountered this problem, both on OSX and on different types of cameras. If I access iSight, both calls in my code do not work.

+9
python opencv camera
source share
6 answers

Yes, you are definitely limited by USB bandwidth. Trying to read from both devices with a complete error, you probably got the error:

 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 

And then when you reduce the resolution to 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?! 

now it works! I am sure you have two cameras connected to the same USB-card. You can run the lsusb command to make sure, and it should point to something like:

 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 

(Pay attention to both cameras on the same bus.) If possible, you can add another USB card to your computer to increase throughput. I have done this before to run multiple full resolution cams on the same machine. Although it was a tower workstation with accessible slots for motherboards, and, unfortunately, you may not have this option on a MacBook laptop.

+3
source share

Using OPENCV and two standard USB cameras, I was able to do this using multithreading. Essentially, define one function that opens the opencv window and the VideoCapture element. Then create two streams with camera ID and window name as input.

 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() 

Great resource for learning flow in python: https://www.tutorialspoint.com/python/python_multithreading.htm

+4
source share

I use "imutils" and read the webcam in the image.

import imutils

frame capture vedio

--- 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)

i create read_frame () function send parameter about Image.fromarray and display

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

and final function show video on "imageFrame"

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

Example. 4-webcam

Youtube: Youtube

+2
source share

It was a pain for me for a long time, so I created a library on top of OpenCV to work with multiple cameras and viewing areas. I encountered a lot of problems, such as videos that are not compressed by default, or windows that are displayed only in the main stream. At the moment, I can display in real time two 720p webcams in Windows.

Try:

 pip install CVPubSubs 

Then in Python:

 import cvpubsubs.webcam_pub as w from cvpubsubs.window_sub import SubscriberWindows t1 = w.VideoHandlerThread(0) t2 = w.VideoHandlerThread(1) t1.start() t2.start() SubscriberWindows(window_names=['cammy', 'cammy2'], video_sources=[0,1] ).loop() t1.join() t1.join() 

Although it is relatively new, so tell me about any bugs or unoptimized code.

0
source share

try using this code ... it worked as expected ... this is for two cameras, if you want more cameras, just create "VideoCapture ()" objects ... for example, the third camera will have: cv2.VideoCapture (3) and corresponding code in while loop

 import cv2 frame0 = cv2.VideoCapture(1) frame1 = cv2.VideoCapture(2) while 1: ret0, img0 = frame0.read() ret1, img00 = frame1.read() img1 = cv2.resize(img0,(360,240)) img2 = cv2.resize(img00,(360,240)) if (frame0): cv2.imshow('img1',img1) if (frame1): cv2.imshow('img2',img2) k = cv2.waitKey(30) & 0xff if k == 27: break frame0.release() frame1.release() cv2.destroyAllWindows() 

ALL THE BEST !

0
source share
 frame0 = cv2.VideoCapture(1) frame1 = cv2.VideoCapture(2) 

should be:

 frame0 = cv2.VideoCapture(0) # index 0 frame1 = cv2.VideoCapture(1) # index 1 

So it works

0
source share

All Articles