I’m working on a project that involves streaming from a few USB cameras simultaneously using Python and OpenCV. I’ve been experimenting with multithreading to handle both camera streams concurrently, but I’m encountering an issue where the imshow function only displays blank black windows for both cameras.
My code, simplified:
import cv2
import concurrent.futures
import time
def gen(src):
vid = cv2.VideoCapture(src)
if not vid.isOpened():
print(f"Error reading camera {src}")
return
while True:
time.sleep(0.1)
flag, frame = vid.read()
if not flag:
print(f"Failed to capture frame from camera {src}")
break
cv2.imshow(f"Camera {src}", frame)
cv2.moveWindow(f"Camera {src}", src*300, 0)
k = cv2.waitKey(1)
if k == ord('q'):
break
vid.release()
cv2.destroyAllWindows()
with concurrent.futures.ThreadPoolExecutor() as executor:
try:
executor.map(gen, (0, 2))
except Exception as e:
print(f"Error executing thread function: {e}")
The windows for both cameras display as black, even though the cameras are correctly connected and functioning when tested individually.
Changing cv2.VideoCapture(src)
to cv2.VideoCapture(2)
or cv2.VideoCapture(0)
works, so cameras work individually in the code.
I adjusted time.sleep duration to see if it would make a difference. Nothing
Thanks in advance!
Also, crediting this older post for syntax help:
how to run multiple camera in threading using python
6
Because I only have one camera I had to test like this:
import cv2
sources = [
0,
'https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4'
]
capture_list = [cv2.VideoCapture(i) for i in sources]
frames_list = [None for i in sources]
while True:
for i, c in enumerate(capture_list):
_, frames_list[i] = c.read()
cv2.imshow(f'Window: {sources[i]}', frames_list[i])
if cv2.waitKey(1) & 0xFF == ord('q'):
break
for capture_item in capture_list:
capture_item.release()
cv2.destroyAllWindows()
Instead of actual parallel processing, creating threads, using multiprocessing or else, we just write the frames into a list and take them from a list to display them. If it’s only about displaying n
streams, this should be working.
9