1

If I run this code on a PC with two webcams attached it runs fast (or fast enough) without any issues:

import cv2

cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)

while True:
    ret0, img0 = cap0.read()
    print('read 0')
    ret0, img1 = cap1.read()
    print('read 1')

When I run the same code on Rpi3B+, I get this output. It cannot read the second camera and even if the first camera is being read, it's so slow it's unusable:

read 0
[ WARN:[email protected]] global /tmp/pip-wheel-efxaz4j7/opencv-python_bedc0fac27944da0921e079da44d32bf/opencv/modules/videoio/src/cap_v4l.cpp (1000) tryIoctl VIDEOIO(V4L2:/dev/video1): select() timeout.
read 1

Somehow OpenCV on RPi cannot properly do cv2.VideoCapture on two cameras. I've tried using threads and QThreads, but that doesn't help. If you change the loop to capture and release the camera in every loop step, it works: but it's too slow (< 1 FPS):

import cv2

while True:
    cap0 = cv2.VideoCapture(0)
    ret0, img0 = cap0.read()
    cap0.release()
    print('read 0')
    cap1 = cv2.VideoCapture(1)
    ret1, img1 = cap1.read()
    print('read 1')
    cap1.release()

Are there any tricks to overcome the limitations of OpenCV on RPi?

Update: I degraded resolution from 640x480 (default) to 320x240 per this question and it seems to work. However, that resolution may not be usable. I'm basically just asking for one frame at a time. It's confusing to me why reducing resolution makes such a huge difference.

cap0.set(3,320)
cap0.set(4,240)
cap1.set(3,320)
cap1.set(4,240)
3
  • try the following ... it may point to the problem area ... keep only the cap0 code from the first script and run it ... then create a second script for cap1 and run it at the same time in a separate terminal window
    – jsotola
    Apr 21, 2022 at 23:59
  • @jsotola. Interesting thought. I tried your idea. cap0 and cap1 in separate scripts. First launch cap0 script. Then switch to another terminal and launch cap1 script. Unfortunately cap1 gets stuck with the dreaded select() timeout.
    – bfris
    Apr 22, 2022 at 1:01
  • Check the CPU load while you run your scripts. The Pi is often simply too slow when you give it a PC's workload. May 4, 2022 at 7:18

1 Answer 1

0

Try using using grab() and retrieve() instead of read() in multi-camera setups, see the OpenCV documentation

I have used this technique to handle 2 cameras in a single thread on a Pi 3, see this blog post

2
  • I tried grab() and retrieve(). They only seem to work if I set resolution to 320×240. The cameras are supposed to be 2M pixel, 1600×1200 so it's really frustrating to only be able to use them at a fraction of what they can do. If I only one one camera at a time in a loop, I can grab a few fps @ 1600×1200.
    – bfris
    May 10, 2022 at 1:23
  • I was able to get much better resolution than that with 2 cameras. I wonder if the problem is in the way you are handling the data; are you putting it in message queues, and checking for space in the queue before adding more data? The captured data can easily out-pace the image processing, so you need a mechanism for discarding frames if there is a backlog awaiting processing.
    – jayben
    May 10, 2022 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.