1

TLDR: USB Camera stops returning images with continued usage.

I am running a continuous application using Raspberry Pi4, Ubuntu, OpenCV where I am capturing an image once every 5 seconds and sending that to an API. I'm having an issue where I am getting None frames after some time and the camera becomes unresponsive.

I've tried using V4L2 and fswebcam directly in the command line as tests, but I keep getting the same issue of the camera either being completely unresponsive or taking several minutes to capture an image.

Simplified Code

import cv2
import time

cam=cv2.VideoCapture(0)
time.sleep(2)
cam.set(3,1280)
cam.set(4,720)
cam.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))

while True:
     time.sleep(5)
     ret , frame = cam.read()

This runs fine at first, but the images start coming in slower and slower over time. Eventually, it returns None frame and becomes unresponsive. Subsequent attempts to release and select the camera result in camera select timeout errors.

VIDEOIO(V4L2:/dev/video0): select() timeout

Any idea what would cause the camera to start taking longer and longer to capture the images and why the camera becomes unresponsive?

stateMachine
  • 5,227
  • 4
  • 13
  • 29
Cody
  • 11
  • 2
  • did you try not convert the video stream on the fly with "VideoWriter_fourcc" ? Just comment that line or increase that 5 seconds sleep. Maybe raspberry can't deal with this amount of computation. – Henrique Mar 24 '22 at 20:25
  • I'm specifying the MJPG format because I'm trying to access the precompressed stream from the camera. I don't believe the pi should be doing anything computationally intensive. The CPU utilization is like 3%. – Cody Mar 24 '22 at 21:01
  • set the fourcc first, then other properties. and make sure no other bandwidth-hungry peripherals are on the same usb controller. -- generally it's wasteful to repeatedly open and close the same device. keep it open, keep reading frames, keep a reference to the latest frame, use when needed. – Christoph Rackwitz Mar 25 '22 at 09:12

2 Answers2

0

Have you tried this implementation to avoid having the videocapture resource tied up while you are waiting for 5 seconds?

import cv2
import time

while True:
    time.sleep(5)
    cam=cv2.VideoCapture(0)
    time.sleep(2)
    cam.set(3,1280)
    cam.set(4,720)
    cam.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))
    ret , frame = cam.read()
    cam.release()
Shawn Ramirez
  • 796
  • 1
  • 5
  • 10
  • I've tried doing something similar on the command line with V4L2 and fswebcam where I set the camera and capture - then sleep. It had the same failure condition of erroring out after it ran for a bit. I can try this though. – Cody Mar 24 '22 at 21:03
  • Sounds good. you may not even need to wait a full 5 seconds any longer since the pi take considerably longer to initialize a VideoCapture. The important point is cam.release() – Shawn Ramirez Mar 24 '22 at 21:10
  • Tried this and it didn't work unfortunately – Cody Mar 25 '22 at 14:31
  • Do you still have this problem when you use a smaller image size? – Shawn Ramirez Mar 25 '22 at 18:34
  • Yep, seems to happen at any resolution – Cody Mar 26 '22 at 22:00
0

I had the same problem and fixed it by moving my USB camera over to one of the USB 2.0 ports (the black ones). I only saw the problem when I plugged the camera into the USB 3.0 ports (the blue ones)

Ian Charnas
  • 366
  • 1
  • 3
  • 8