I'm using OpenCV-Python 3.1 Following the example code from here:
http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html and using a http camera stream instead of the default camera, the read function in videocapture never returns "False" (or anything for that matter) when the camera is physically disconnected, thus hanging/freezing the program entirely. Does anyone know how to fix this?
import numpy as np
import cv2
cap = cv2.VideoCapture('http://url')
ret = True
while(ret):
# Capture frame-by-frame
ret, frame = cap.read()
print(ret)
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I'm experiencing the same issue with the webcam of my MacBook, when the lid is closed (i.e. cam not available). After a quick look at the doc, the VideoCapture
constructor doesn't seem to have any timeout
parameter. So the solution has to involve forcibly interrupting this call from Python.
After yet more readings about Python's asyncio
then threading
in general, I couldn't come up with any clue on how to interrupt a method which is busy outside the interpreter. So I resorted to creating a daemon per VideoCapture
call, and let them die on their own.
import threading, queue
class VideoCaptureDaemon(threading.Thread):
def __init__(self, video, result_queue):
super().__init__()
self.daemon = True
self.video = video
self.result_queue = result_queue
def run(self):
self.result_queue.put(cv2.VideoCapture(self.video))
def get_video_capture(video, timeout=5):
res_queue = queue.Queue()
VideoCaptureDaemon(video, res_queue).start()
try:
return res_queue.get(block=True, timeout=timeout)
except queue.Empty:
print('cv2.VideoCapture: could not grab input ({}). Timeout occurred after {:.2f}s'.format(video, timeout))
If anyone has better, I'm all ears.