List available cameras OpenCV/Python

Question:

I have multiple webcams connected to my PC and I would like to select one camera based on its info (name, resolution etc.). Is there a way to list all the cameras available on a PC, instead of trying all the indices in cv2.VideoCapture()?

Asked By: SEU

||

Answers:

The answer is negative. OpenCV doesn’t have a method for listing the available video capture devices on your system. If you look at the code you see how currently OpenCV handles invalid device indices that don’t exist. For instance for MacOS here is the code:

if ( cameraNum < 0 || devices.count <= NSUInteger(cameraNum) ) {
    fprintf(stderr, "OpenCV: out device of bound (0-%ld): %dn", devices.count-1, cameraNum);
    [localpool drain];
    return 0;
}

You see devices.count returns the number of available devices but OpenCV doesn’t have a method to return that to the user.

The relevant code for Windows is here:

if ((unsigned)m_deviceID >= m_devices.Get()->Size)
{
    OutputDebugStringA("Video::initGrabber - no video device foundn");
    return false;
}

Again there is no function for returning m_devices.Get()->Size to the user. The Linux code is a bit more complex.

If you’re building OpenCV from code you could add a function that returns the number of available devices. Or even better submit a pull request to OpenCV with your patch.

Answered By: fireant

To answer the title of your question, you can use a while loop:

import cv2


def list_ports():
"""
Test the ports and returns a tuple with the available ports and the ones that are working.
"""
    is_working = True
    dev_port = 0
    working_ports = []
    available_ports = []
    while is_working:
        camera = cv2.VideoCapture(dev_port)
        if not camera.isOpened():
            is_working = False
            print("Port %s is not working." %dev_port)
        else:
            is_reading, img = camera.read()
            w = camera.get(3)
            h = camera.get(4)
            if is_reading:
                print("Port %s is working and reads images (%s x %s)" %(dev_port,h,w))
                working_ports.append(dev_port)
            else:
                print("Port %s for camera ( %s x %s) is present but does not reads." %(dev_port,h,w))
                available_ports.append(dev_port)
        dev_port +=1
    return available_ports,working_ports

It’s quite easy solution to implement on your code.

Version 2

As @ketza noticed, there might be cases in which the working ports are not sequential, this version will test at least 5 non working ports before exiting the while loop:

import cv2
    
    
def list_ports():
    """
    Test the ports and returns a tuple with the available ports and the ones that are working.
    """
    non_working_ports = []
    dev_port = 0
    working_ports = []
    available_ports = []
    while len(non_working_ports) < 6: # if there are more than 5 non working ports stop the testing. 
        camera = cv2.VideoCapture(dev_port)
        if not camera.isOpened():
            non_working_ports.append(dev_port)
            print("Port %s is not working." %dev_port)
        else:
            is_reading, img = camera.read()
            w = camera.get(3)
            h = camera.get(4)
            if is_reading:
                print("Port %s is working and reads images (%s x %s)" %(dev_port,h,w))
                working_ports.append(dev_port)
            else:
                print("Port %s for camera ( %s x %s) is present but does not reads." %(dev_port,h,w))
                available_ports.append(dev_port)
        dev_port +=1
    return available_ports,working_ports,non_working_ports
Answered By: G M

first install package :
pip install pygrabber==0.1

code #

from pygrabber.dshow_graph import FilterGraph

graph = FilterGraph()

print(graph.get_input_devices())# list of camera device 

try:
    device =graph.get_input_devices().index("name camera that I want to use it ")

except ValueError as e:

    device = graph.get_input_devices().index("Integrated Webcam")#use default camera if the name of the camera that I want to use is not in my list

vid=cv2.VideoCapture(device)
Answered By: lotfi_lofti
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.