Listing Multiple Cameras for OpenCV-Python on Windows

Xiao Ling
3 min readAug 21, 2017

--

Using OpenCV APIs to capture video from a camera is convenient. However, OpenCV does not provide an API for listing all available devices. If you have multiple cameras connected to your PC, you have no idea how to choose the right one. To get device information on Windows, you need to invoke DirectShow APIs. In this post, I will share how to create a Python extension that lists camera devices for OpenCV-Python on Windows.

Bridging DirectShow APIs to OpenCV-Python

How to run DirectShow sample

To use DirectShow APIs, read the Microsoft’s tutorial — Selecting a Capture Device, which shares how to list video and audio devices in C++.

To run the sample, create an empty Win32 Console Application in Visual Studio: File > New > Project > Templates > Visual C++ > Win32.

Create main.cpp, and copy all codes snippets from the tutorial page to the C++ file.

Build and run the project.

How to wrap up DirectShow C++ code

Define Python module and change main() function to a Python method:

static PyObject *getDeviceList(PyObject *self, PyObject *args){PyObject* pyList = NULL;HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);if (SUCCEEDED(hr)){IEnumMoniker *pEnum;hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);if (SUCCEEDED(hr)){pyList = DisplayDeviceInformation(pEnum);pEnum->Release();}CoUninitialize();}return pyList;}static PyMethodDef Methods[] ={{"getDeviceList", getDeviceList, METH_VARARGS, NULL},{NULL, NULL, 0, NULL}};PyMODINIT_FUNCinitdevice(void){(void) Py_InitModule("device", Methods);}

Create Python list to save device information:

PyObject* pyList = PyList_New(0);Char *pValue = _com_util::ConvertBSTRToString(var.bstrVal);HRESULT hr = PyList_Append(pyList, Py_BuildValue("s", pValue));

Note: you have to convert BSTR to string. To use ConvertBSTRToString, we need a header file #include <comutil.h>, and the corresponding library #pragma comment(lib, “comsuppw.lib”).

How to build and use Python extension

Create setup.py:

from distutils.core import setup, Extensionmodule_device = Extension('device',sources = ['device.cpp'],library_dirs=['G:\Program Files\Microsoft SDKs\Windows\v6.1\Lib'])setup (name = 'WindowsDevices',version = '1.0',description = 'Get device list with DirectShow',ext_modules = [module_device])

Build and install the extension:

python setup.py build install

If you see the error ‘Unable to find vcvarsall.bat’, set Visual Studio environment:

  • Visual Studio 2010 (VS10): SET VS90COMNTOOLS=%VS100COMNTOOLS%
  • Visual Studio 2012 (VS11): SET VS90COMNTOOLS=%VS110COMNTOOLS%
  • Visual Studio 2013 (VS12): SET VS90COMNTOOLS=%VS120COMNTOOLS%
  • Visual Studio 2015 (VS14): SET VS90COMNTOOLS=%VS140COMNTOOLS%

Create test.py to use the extension for OpenCV-Python:

import deviceimport cv2def select_camera(last_index):number = 0hint = "Select a camera (0 to " + str(last_index) + "): "try:number = int(input(hint))# select = int(select)except Exception ,e:print("It's not a number!")return select_camera(last_index)if number > last_index:print("Invalid number! Retry!")return select_camera(last_index)return numberdef open_camera(index):cap = cv2.VideoCapture(index)return capdef main():# print OpenCV versionprint("OpenCV version: " + cv2.__version__)# Get camera listdevice_list = device.getDeviceList()index = 0for name in device_list:print(str(index) + ': ' + name)index += 1last_index = index - 1if last_index < 0:print("No device is connected")return# Select a cameracamera_number = select_camera(last_index)# Open cameracap = open_camera(camera_number)if cap.isOpened():width = cap.get(3) # Frame Widthheight = cap.get(4) # Frame Heightprint('Default width: ' + str(width) + ', height: ' + str(height))while True:ret, frame = cap.read();cv2.imshow("frame", frame)# key: 'ESC'key = cv2.waitKey(20)if key == 27:breakcap.release()cv2.destroyAllWindows()if __name__ == "__main__":main()

Source Code

https://github.com/yushulx/python-capture-device-list

Originally published at www.codepool.biz on August 21, 2017.

--

--

Xiao Ling
Xiao Ling

Written by Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

No responses yet