我是靠谱客的博主 忧郁大碗,这篇文章主要介绍OpenCV:如何获取摄像头的型号以及USB设备的VID和PID信息?,现在分享给大家,希望可以做个参考。

VID和PID

PID/VID唯一标识一个设备,HardwareID是为了给系统识别的 ,他是根据PID/VID而生成的。这个与序列号没什么关系,序列号一般都是厂家固化到芯片中的信息而已。GUID只是为了标志你安装的设备是属于一个什么类当中,这个类可以显示再设备管理器中。比如:你可以定义一个类,当然这个类有与系统中任何类都不同的GUID,然后选择一个图标和类名,就可以同网卡等其他设备一起显示在设备管理器下的根目录中了

根据USB规范的规定,所有的USB设备都有供应商ID(VID)和产品识别码(PID),主机通过不同的VID和PID来区别不同的设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向USB执行论坛申请,每个供应商的VID是唯一的,PID由供应商自行决定,理论上来说,不同的产品、相同产品的不同型号、相同型号的不同设计的产品最好采用不同的PID,以便区别相同厂家的不同设备。

VID和PID通常情况下有两种存储方式,第一种是主控生产商的VID和PID,存储在主控的bootcode中;第二种是设备生产商的VID和PID,该VID和PID存储在主控外部的非易失性存储设备中(EEPROM或Flash)的设备固件中,当USB设备连接主机时,如果固件中有设备生产商的VID和PID,会将该VID和PID报告给主机,而忽略主控生产商的VID和PID。所以理论上一个USB存储设备的VID应该是设备生产商的VID,而不是主控生产商的VID,这两个VID应该是不同的(主控生产商自己生产的设备除外)。

由于VID和PID重复并不会对产品的使用带来严重影响,很多USB设备生产商(山寨厂居多)为了方便,并不会向USB执行论坛申请自己的VID,而是依然沿用主控生产商的VID或随便向产品写入VID和PID;同时,正规厂家只需要申请VID,PID由厂家自行确定,所以存在相同型号的产品,可能采用了不同的主控(商业需要,很正常),而他们的PID是一样的,基于上述原因通过VID和PID就不能准确识别USB设备的主控型号,这个问题大家在使用USB设备的过程中需要注意。

 

查看设备信息

1、鼠标右键“我的电脑”,选择“管理”,进入“计算机管理”。

2、在“计算机管理”界面,依次选择“设备管理器”、“图像设备”、摄像头的型号,选中点击鼠标右键,选择“属性”。

3、进入“属性”页面,就可已查看USB设备的VID和PID了。

 

获取摄像头型号

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include "windows.h" #include "dshow.h" #include <iostream> #pragma comment(lib, "strmiids.lib") #pragma comment(lib, "quartz.lib") using namespace cv; using namespace std; int listDevices(vector<string>& list) { //COM Library Initialization //comInit(); //if (!silent) DebugPrintOut("nVIDEOINPUT SPY MODE!nn"); 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)) { // Create an enumerator for the video capture category. hr = pDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnum, 0); if (hr == S_OK) { printf("SETUP: Looking For Capture Devicesn"); 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; // Skip this one, maybe the next one will work. } // Find the description or friendly name. VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"Description", &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 }; //int maxLen = sizeof(deviceNames[0]) / sizeof(deviceNames[0][0]) - 2; while (varName.bstrVal[count] != 0x00 && count < 255) { tmp[count] = (char)varName.bstrVal[count]; count++; } list.push_back(tmp); //deviceNames[deviceCounter][count] = 0; //if (!silent) DebugPrintOut("SETUP: %i) %sn", deviceCounter, deviceNames[deviceCounter]); } pPropBag->Release(); pPropBag = NULL; pMoniker->Release(); pMoniker = NULL; deviceCounter++; } pDevEnum->Release(); pDevEnum = NULL; pEnum->Release(); pEnum = NULL; } //if (!silent) DebugPrintOut("SETUP: %i Device(s) foundnn", deviceCounter); } //comUnInit(); return deviceCounter; } int main() { vector<string> list; int capid0 = 0, capid1 = 0;//摄像头ID int divice_num = 0; divice_num = listDevices(list);//设备列表 cout << "divice_num:" << divice_num << endl; for (int i = 0; i < list.size(); i++) { /* if (list[i] == "3D Camera") { capid1 = i; cout << list[i]<< " is 3D Camera"<<endl; } if (list[i] == "USB2.0 HD UVC WebCam") { capid0 = i; cout << list[i] << " is USB2.0 HD UVC WebCam" << endl; } */ cout << "Device["<<i<<"]:"<< list[i] << endl; } VideoCapture cap; cout << "capid= " << capid1 << endl; cap.open(capid1); Mat frame; while (1) { cap >> frame; imshow("capshow", frame); if (waitKey(30) == 27) { break; } } return 0; }

 

 

获取设备的VID和PID

在使用多个摄像头的时候,如果使用同型号的摄像头,它们的VID和PID相同的。所以,依靠VID和PID不能区分同型号的摄像头,必须要知道设备的端口号,才可以确定调用的是哪个摄像头。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream> #include <windows.h> #include <string> #include <setupapi.h> #include <initguid.h> using namespace std; #pragma comment(lib,"setupapi.lib") DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed); //获取USB设备VID和PID string GetUsbInfo() { HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA spDevData; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail; BOOL bRes = TRUE; int nCount = 0; string csResult; hDevInfo = ::SetupDiGetClassDevs((LPGUID)&UsbClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (hDevInfo != INVALID_HANDLE_VALUE) { pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, 1024); pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); while (bRes) { spDevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID)&UsbClassGuid, nCount, &spDevData); if (bRes) { bRes = ::SetupDiGetInterfaceDeviceDetail(hDevInfo, &spDevData, pDetail, 1024, NULL, NULL); if (bRes) { string szStr = pDetail->DevicePath; csResult += szStr + "n"; nCount++; } } } ::GlobalFree(pDetail); ::SetupDiDestroyDeviceInfoList(hDevInfo); } return csResult; } int main(void) { string csStr = GetUsbInfo(); cout << csStr << endl; system("PAUSE"); return 0; }

注意:以上代码均在VS2015上测试通过,如果出现字符错误,请更换为“多字节字符集”,再进行调试。

最后

以上就是忧郁大碗最近收集整理的关于OpenCV:如何获取摄像头的型号以及USB设备的VID和PID信息?的全部内容,更多相关OpenCV:如何获取摄像头内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部