top of page

Quick and Inefficient Way to Stream Multiple Webcams with Python

In this post, we will use Python and OpenCV to inefficiently find all available webcams in our system and display their image. OpenCV works in mysterious ways when looking for installed USB camera devices in your system, depending on the backend and the operating system. We are going to loop through a sensible range of possible camera indexes, -100 to 100 in this case, using this function:


def explore_cameras(search_range=100):
    found_cam_ids = []
    for i in range(-search_range, search_range):
        print(f"Testing camera index: {i}")
        cam = cv2.VideoCapture(i)
        while True:
            ret, img = cam.read()
            if ret:
                found_cam_ids.append(i)
                cam.release()
                break
            else:
                break

    return found_cam_ids

This function, explore_cameras, will loop through indexes -100 to 100, trying to obtain a returning frame. If it can grab a frame, we will add the found index to found_cam_ids and return a list with all these camera indexes that answer with a frame. We will pass this list to our main function that will start parallel threads for each of these camera indexes that have been found:

import cv2
import threading

def main():
    cams = explore_cameras()
    if len(cams) == 0:
        print("No cameras found. Exiting")
        return
    threads = []
    for cam in cams:
        threads.append(threading.Thread(target=show_webcam, args=(cam,)))
    for thread in threads:
        thread.start()

The target function for each thread is show_webcam, which will create a new display window for each camera and proceed to display its feed:


def show_webcam(idx):
    cam = cv2.VideoCapture(idx)
    window_name = f"Cam{idx}"
    cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE)
    while True:
        ret, img = cam.read()
        if not ret:
            print("Not Capturing")
            continue
        cv2.imshow(window_name, img)
        if cv2.waitKey(1) == 27:
            break  # esc to quit

Running this code will result in multiple windows with the stream from each USB camera; note that the cameras cannot be connected to the same USB hub or concentrator as they will share an address and bandwidth that can become exhausted, resulting in no image being fed.



The complete code is here, using Python 3.11 and opencv-contrib-python 4.8.1.78:

import cv2
import threading


def show_webcam(idx):
    cam = cv2.VideoCapture(idx)
    window_name = f"Cam{idx}"
    cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE)
    while True:
        ret, img = cam.read()
        if not ret:
            print("Not Capturing")
            continue
        cv2.imshow(window_name, img)
        if cv2.waitKey(1) == 27:
            break  # esc to quit


def explore_cameras(search_range=100):
    found_cam_ids = []
    for i in range(-search_range, search_range):
        print(f"Testing camera index: {i}")
        cam = cv2.VideoCapture(i)
        print(cam)
        while True:
            ret, img = cam.read()
            if ret:
                found_cam_ids.append(i)
                cam.release()
                break
            else:
                break

    return found_cam_ids


def main():
    cams = explore_cameras()
    if len(cams) == 0:
        print("No cameras found. Exiting")
        return
    threads = []
    for cam in cams:
        threads.append(threading.Thread(target=show_webcam, args=(cam,)))
    for thread in threads:
        thread.start()


if __name__ == '__main__':
    main()

Do not hesitate to contact us if you require quantitative model development, deployment, verification, or validation. We will gladly help you with your machine learning or artificial intelligence challenges when applied to asset management, automation, or intelligence gathering from satellite, drone, or fixed-point imagery.

21 views0 comments

Recent Posts

See All
bottom of page