5

I'm using Python OpenCV to read from 2 USB webcams on a Raspberry Pi4. If I'm using either of the camera individually they work fine. As soon as I initialize both cameras in the script as following:

import cv2
cap0 = cv2.VideoCapture(0);
cap0.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap0.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

cap1 = cv2.VideoCapture(2);
cap1.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap1.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

while True:
        ret0, frame1 = cap0.read()
        ret1, frame2 = cap1.read()

        print('Retval cap0: ' ,ret0)
        print('Retval cap1: ', ret1)

        if ret0:
                cv2.imshow('frame1', frame1)
        if ret1:
                cv2.imshow('frame2', frame2)

        if cv2.waitKey(1) & 0xFF == ord('q'):
                break

cap0.release()
cap1.release()
cv2.destroyAllWindows()

I get this ouput:

select timeout
VIDIOC_DQBUF: Resource temporarily unavailable
Retval cap0:  True
Retval cap1:  False
VIDIOC_QBUF: Invalid argument
Retval cap0:  True
Retval cap1:  False
VIDIOC_QBUF: Invalid argument
...

If I use 640x480 resolution it seems to work but I would need the HD resolution. It didn't help to add a deleay between the read steps. Using the Rpi3 Model B+ (Raspian Strech) I can run the script properly, the VIDIOC Error appeard only on Rpi4 (Raspian Buster).

  • This also occurs with one USB camera attached. I think it is a change between the July 10th release of Buster and the September 26th release (untested for the moment). I had the above script running on the 7/10 release, but have the same VIDIOC_DQBUF: Resource temporarily unavailable error on 9/26 release. This also is an issue on pygame for video capture, but not for very slow image capture (?). – Bill Armstrong Nov 26 '19 at 0:13
  • I can confirm also on RPi4 Raspian/Buster with 2 USB cameras. same issue. – Nasser Al-Wohaibi Dec 1 '19 at 18:59
3

I was able to narrow this down to a Kernel issue. I do think there is something that has been updated that is causing the problem since the 7/10 release...

If you look at a list (lsmod) of your Kernal modules you see one called uncvideo - this is the problem item. Start by removing it:

pi@raspberrypi:~ $ sudo rmmod uvcvideo

Then you can read the module with some extended longer no response triggers.

pi@raspberrypi:~ $ sudo modprobe uvcvideo nodrop=1 timeout=5000 quirks=0x80

The nodrop=1 makes sure that even corrupt frames get delivered. This will help by putting a bad frame upfront to get the process going. See source here.

The timeout is obvious - it just extends the no response trigger. See here.

The quirks parameter is a bit of a mystery to me - but there is some documentation here and here. The second one is where I came up with the 0x80 value - but you'll see that there appears to be a lot of options (640 adds a baud rate adjustment).

As a final note, with these modifications, I got the OpenCV 4.0.0 installed and running on Python 3.7.3. The whole thing is running on a Raspi 4 x 4gb. The performance is still way too slow - so more work needed here.

| improve this answer | |
  • Unfortunately I was still not able to run the above script properly after using the suggested modifications. (Buster 9/26 release, OpenCV 3.4.5 and Python 3.7.3) – user111029 Nov 26 '19 at 18:29
  • Yes - I had to roll back to Buster 7/10 release to get it to work. Although I’m using a different OpenCV version (4.0.0) which maybe has an impact. – Bill Armstrong Nov 26 '19 at 18:32
  • So far I tried it with Buster 7/10 release and OpenCV 4.1.0 which was unsuccessfull. However I didn't manage to install OpenCV 4.0.0 yet. – user111029 Nov 27 '19 at 9:42
  • Even in the suggested configuration, Buster 7/10 release, OpenCV 4.0.0 and Python 3.7.3 I was not sucessfull in running the code with 2 cams. Further investigation showed, that if I'm using this configuration in combination with a Rpi 3B+ the Error messages didn't appear and all retval were all shown as True. To test that I inserted the same micro SD card in the Pi4 and Pi3. It seems as my Rpi4 might be the problem. – user111029 Nov 29 '19 at 18:49
  • 1
    I have a couple of Raspi 3s laying around. I’ll also give that a try - the FPS on the 4 (even though I can get it to work) makes it ineffective. Hope it’s fixable. – Bill Armstrong Nov 29 '19 at 22:22
1

I believe that there are some limitations in the main USB camera driver uvc, or your CPU/GPU's processing power for that matter, where running multiple uncompressed camera streams will just ... hang. see

So, since OpenCV uses uvc to read the USB camera stream in Linux and that cv2.VideoCapture might default to some uncompressed stream like YUYV, we need to change the stream format into something like MJPG , depending if it is supported by the camera, likewise:

import cv2

#first camera src
cap0 = cv2.VideoCapture(0); 
# set the format into MJPG in the FourCC format 
cap0.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))

#same for camera 2
cap1 = cv2.VideoCapture(2);
cap1.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))

To check what streams are supported by your camera run:

$ v4l2-ctl -d /dev/video0 --list-formats 

or for more details

$ luvcview -d /dev/video0 -L
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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