Opencv 区分摄像头 windows iserialNumber

在Windows下,使用OpenCV打开摄像头时,通常通过VideoCapture.open(index)按顺序选取。由于设备名不唯一,本文介绍如何通过摄像头的序列号(iserialNumber)来确定设备。由于DirectShow中的IPropertyBag无法直接获取序列号,作者通过获取设备实例路径,然后使用Windows API二次枚举以获取父设备的序列号,建立序列号与OpenCV枚举Index的对应关系,实现根据序列号准确打开摄像头。
摘要由CSDN通过智能技术生成

问题背景:

      根据摄像头序列号来获得Open(index)。

      使用Opencv打开多个摄像头的时候,一般都是用VideoCapture.open(index)的方式。这种方式虽然很方便,但是并不能传入其他信息来指定打开哪一个摄像头。

      windows平台下,Opencv打开USB摄像头的逻辑代码主要在cap_dshow.cpp中,阅读源码发现其打开设备的顺序,只与枚举顺序有关,使用的是DirectShow中的IPropertyBag类,可以获取DevicePath,FriendName等属性,而其中没有关于序列号(iserialNumber)的方法。而在实际使用过程中,一般我们用的摄像头都是一个厂商的,设备实例路径,设备名都一样,有工具能修改或者厂商可以修改设备名来加以区分,而设备名是不可靠的,会根据插拔的顺序和Hub变化,不是与设备唯一绑定的。在厂商提供了修改序列号的工具后,发现序列号是与设备唯一绑定的,是可靠的,可以用来区分USB摄像头。故我们只要找到能获取序列号的办法,和Opencv的directShow代码结合考虑,可以获取固定序列号的固定index,再用videoCapture打开该index设备。其中需要注意的一点是,只有camera所在的hub序列号可以修改,本身无法修改,所以我们在获取序列号的过程中,需要获取父设备。

代码如下:

       预解释:这里用了4位的序列号,格式为[L,R][版本号][行][列],例如L000,R010。程序中CheckSerialNumber即是对序列号的校验。代码分为2步,第一步利用directShow枚举设备,获得设备实例路径,第二步是获得实例路径之后,采用windows Api二次枚举,获取父设备的序列号,得到一个对应关系,例如L001,应该是第二个打开,他的Opencv枚举Index可能为3,那么我在打开这个摄像头的时候,就会Open(3)。


// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#pragma comment (lib, "setupapi.lib")
#pragma comment (lib, "cfgmgr32.lib")
#pragma comment (lib, "strmiids.lib")
#include <initguid.h>

#include <windows.h>  

#include <setupapi.h> 
#include <cfgmgr32.h>
#include <usbiodef.h>

#include <regex>

#include <stdio.h>    


#include <dshow.h>
#include <atlconv.h>
#include "DistinguishCamera.h"
#include <iostream>

#define GUID_CAMERA_STRING L"{65e8773d-8f56-11d0-a3b9-00a0c9223196}"

static char* GuidToString(const GUID &guid)
{
	int buf_len = 64;
	char *buf = (char *)malloc(buf_len);
	_snprintf(
		buf,
		buf_len,
		"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1],
		guid.Data4[2], guid.Data4[3],
		guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	//printf("%s\n",buf);
	
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值