Camera stops working after about an hour of working

After about an hour of running, my camera starts to timeout grabbing a frame and returns a None object.

Mar 24 18:51:11 ubuntu env[2570]: [ WARN:0] global /tmp/pip-req-build-frgo6bcn/opencv/modules/videoio/src/cap_v4l.cpp (1001) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
Mar 24 18:51:12 ubuntu env[2570]: [ WARN:0] global /tmp/pip-req-build-frgo6bcn/opencv/modules/videoio/src/cap_v4l.cpp (890) open VIDEOIO(V4L2:/dev/video1): can't open camera by index

When this happens I have code that closes the connection, runs usbreset on my USB camera and then attaches to it again. After a while, the camera fails to read at all, even after a usb reset

# Read from camera or reattach if broken
    _, frame = cam.read()
    if frame is None:
        for loop_counter in range(21):
            sleep(1.5)  # give camera time to turn on and try once more.
            _, frame = cam.read()
            if frame is not None:
                break
            if loop_counter == 7:
                cam.release()
                self.camera = None
                cam = None
                self.camera = self._set_up_camera(**self.img_size)
                cam = self.camera
                self.logger.warning("Camera has been dropped and re-attached")
            if loop_counter == 20:
                self.logger.error("Camera is really not working, enter panic")
                self.logger.critical("Haven't created a frame in {:.2f} seconds!".format(10*1.5))
                raise RuntimeError('Camera stopped capturing images')

I Loop through a few video optoins in case the USB camera does not attach to port 0 for some reason. I saw this happen once when I had to reset the device.

# Setup camera
  reset_usb_camera()  # Full usb reset
  dev_port = 0
  while True:
      camera = cv2.VideoCapture(dev_port, apiPreference=cv2.CAP_V4L2)
      if not camera.isOpened():
          print("Port %s is not working." % dev_port)
      else:
          sleep(1)  # give 'er a chance to start up
          camera.set(3, w)
          camera.set(4, h)
          camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc("M", "J", "P", "G"))
          is_reading, img = camera.read()
          if is_reading:
              print("Port %s is working and reads images (%s x %s)" % (dev_port, h, w))
              break
          else:
              print("Port %s for camera (%s x %s) is present but does not read." % (dev_port, h, w))
              camera.release()

I am running this on a Raspberry PI with this camera from amazon.

I tried running a loop with just v4l2-ctl, which I’m using as a backend in OpenCV, to see if it would run for a while but it ended up getting bogged down and stopped running after about 353 images.

#!/bin/bash -x

printf "starting test\n"
for i in {0..1000}
do
	time v4l2-ctl \
	 	--device /dev/video0 \
	 	--set-fmt-video=width=1280,height=720,pixelformat=MJPG \
	 	--stream-mmap \
	 	--stream-to=frame${i}.jpg \
	 	--stream-count=1
	
	sleep 3s
done

For example, one time output was

real	3m53.618s
user	0m0.006s
sys	    0m0.036s

Showing that the system was getting blocked by something else. I thought it was I/O bound but when I ran iotop it said it wasn’t writing at all or just a few bytes. Also, I checked my CPU thermals to see if the whole system was overheating but it was at 51c so the CPU was fine. I didn’t know how to get the temps of the camera. When I reboot the whole system it normally comes back but not always, which is frustrating. Any ideas would be helpful and appreciated.

since you can replicate those issues with plain v4l tools, I’m inclined to conclude that OpenCV can’t do anything about this.

can you replicate this with a camera from an entirely different manufacturer?