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.