0
点赞
收藏
分享

微信扫一扫

python调用exe获取windows多USB个摄像头的名称,以及对应opencv的ID号的土办法

天行五煞 2022-03-12 阅读 42

插拔usb摄像头时候,调用cap=cv2.VideoCapture(ID)时,其ID会改变,查了网上的做法,很多都是C++的程序编的,那么如果用python怎么获取,想到一个土办法,就是将c++获取USB摄像头的名称及ID号输出到控制台编译成exe,python调用exe,截取控制台输出字符串,就可以得到windows下的所有摄像头名称及对应cv2.VideoCapture(ID)的ID。
c++的程序根据网上提供的代码改了改,如有侵权请联系,C++代码如下:

#include<iostream>
#include "strmif.h"
#include <initguid.h>
#include<vector>
#include<string>
#include "windows.h"
#include "tchar.h"
#include <setupapi.h>
#include <functional>
#include <map>


#pragma comment(lib, "setupapi.lib")

using namespace std;

#define VI_MAX_CAMERAS  20

DEFINE_GUID(CLSID_SystemDeviceEnum, 0x62be5d10, 0x60eb, 0x11d0, 0xbd, 0x3b, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86);
DEFINE_GUID(CLSID_VideoInputDeviceCategory, 0x860bb310, 0x5d01, 0x11d0, 0xbd, 0x3b, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86);
DEFINE_GUID(IID_ICreateDevEnum, 0x29840822, 0x5b84, 0x11d0, 0xbd, 0x3b, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86);

int listDevices(vector<string>& list){


	ICreateDevEnum *pDevEnum = NULL;
	IEnumMoniker *pEnum = NULL;
	int deviceCounter = 0;
	CoInitialize(NULL);
	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
		CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
		reinterpret_cast<void**>(&pDevEnum));


	if (SUCCEEDED(hr))
	{
	
		hr = pDevEnum->CreateClassEnumerator(
			CLSID_VideoInputDeviceCategory,
			&pEnum, 0);

		if (hr == S_OK){

	
			IMoniker *pMoniker = NULL;

			while (pEnum->Next(1, &pMoniker, NULL) == S_OK){

				IPropertyBag *pPropBag;
				hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
					(void**)(&pPropBag));

				if (FAILED(hr)){
					pMoniker->Release();
					continue;  
				}


	
				VARIANT varName;
				VariantInit(&varName);
				hr = pPropBag->Read(L"DevId", &varName, 0);
				
				if (FAILED(hr)) {
					hr = pPropBag->Read(L"FriendlyName", &varName, 0);
		
				}
	
				
				if (SUCCEEDED(hr)){
					hr = pPropBag->Read(L"FriendlyName", &varName, 0);
		
					
					int count = 0;
					char tmp[255] = {0};
	
					while (varName.bstrVal[count] != 0x00 && count < 255) {
						tmp[count] = (char)varName.bstrVal[count];
						count++;
					}

					list.push_back(tmp);
	
				}

				pPropBag->Release();
				pPropBag = NULL;

				pMoniker->Release();
				pMoniker = NULL;

				deviceCounter++;
			}

			pDevEnum->Release();
			pDevEnum = NULL;

			pEnum->Release();
			pEnum = NULL;
		}

	}



	return deviceCounter;
}
int  main()
{
	vector<string> CameraName; 

	int num = listDevices(CameraName);

	for (int i = 0; i < num;i++){
		cout <<"@camera"<< i << ":" << CameraName[i] << endl;
	}

	return 11;
	}

将以上代码编译成exe,然后通过python调用,即可获得摄像头和id:

import os
main='CameraEnum.exe'
rs=os.popen(main)
#print(rs.read())
a=rs.read()
sa = a.split('\n')
for line in sa:    
    if len(line)>=7:
        if line[:7]=='@camera':            
            camera=line[7:].split(":")
            print("摄像头名字:",camera[1])
            print("摄像头的ID:",camera[0])

输出如下:这样就可以不用担心USB摄像头插拔导致的ID变换,只要去匹配摄像头的友好名字就能找到对应的ID,输入cv2.VideoCapture(ID)
在这里插入图片描述

举报

相关推荐

0 条评论