OpenCV的VideoCapture是一个视频读取与解码的API接口,支持各种视频格式、网络视频流、摄像头读取。
针对一般摄像头的读取,opencv为了实现跨平台读取摄像头时是使用的摄像头索引,
1 VideoCapture capture(int index);
一般而言电脑自带的摄像头id=0,但是也存在一些特殊情况,有些usb的摄像头接入笔记本后,usb摄像头的id会变位0,原有的笔记本id则变为1,所以为了程序的稳定性,最好还是使用图像采集设备的名称获取对应的id最后在使用opencv接口打开对应的设备(摄像头、视频采集卡...)。
1 #include<opencv2/objdetect/objdetect.hpp>
2 #include<opencv2/highgui/highgui.hpp>
3 #include "windows.h"
4 #include "dshow.h"
5 #include <iostream>
6
7 #pragma comment(lib, "strmiids.lib")
8 #pragma comment(lib, "quartz.lib")
9
10 using namespace cv;
11 using namespace std;
12
13 int listDevices(vector<string>& list) {
14
15 //COM Library Initialization
16 //comInit();
17
18 ICreateDevEnum *pDevEnum = NULL;
19 IEnumMoniker *pEnum = NULL;
20 int deviceCounter = 0;
21 CoInitialize(NULL);
22
23 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
24 CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
25 reinterpret_cast<void**>(&pDevEnum));
26
27
28 if (SUCCEEDED(hr))
29 {
30 // Create an enumerator for the video capture category.
31 hr = pDevEnum->CreateClassEnumerator(
32 CLSID_VideoInputDeviceCategory,
33 &pEnum, 0);
34
35 if (hr == S_OK) {
36
37 printf("SETUP: Looking For Capture Devices\n");
38 IMoniker *pMoniker = NULL;
39
40 while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
41
42 IPropertyBag *pPropBag;
43 hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
44 (void**)(&pPropBag));
45
46 if (FAILED(hr)) {
47 pMoniker->Release();
48 continue; // Skip this one, maybe the next one will work.
49 }
50
51 // Find the description or friendly name.
52 VARIANT varName;
53 VariantInit(&varName);
54 hr = pPropBag->Read(L"Description", &varName, 0);
55
56 if (FAILED(hr)) hr = pPropBag->Read(L"FriendlyName", &varName, 0);
57
58 if (SUCCEEDED(hr))
59 {
60
61 hr = pPropBag->Read(L"FriendlyName", &varName, 0);
62
63 int count = 0;
64 char tmp[255] = { 0 };
65 //int maxLen = sizeof(deviceNames[0]) / sizeof(deviceNames[0][0]) - 2;
66 while (varName.bstrVal[count] != 0x00 && count < 255)
67 {
68 tmp[count] = (char)varName.bstrVal[count];
69 count++;
70 }
71 list.push_back(tmp);
72 //deviceNames[deviceCounter][count] = 0;
73
74 //if (!silent) DebugPrintOut("SETUP: %i) %s\n", deviceCounter, deviceNames[deviceCounter]);
75 }
76
77 pPropBag->Release();
78 pPropBag = NULL;
79
80 pMoniker->Release();
81 pMoniker = NULL;
82
83 deviceCounter++;
84 }
85
86 pDevEnum->Release();
87 pDevEnum = NULL;
88
89 pEnum->Release();
90 pEnum = NULL;
91 }
92
93 //if (!silent) DebugPrintOut("SETUP: %i Device(s) found\n\n", deviceCounter);
94 }
95
96 //comUnInit();
97
98 return deviceCounter;
99 }
100
101 int main()
102 {
103 vector<string> list;
104 listDevices(list);
105 int capid0 = 0, capid1 = 0;
106 cout << "dev_size = " << list.size() << endl;
107 for (int i = 0; i<list.size(); i++)
108 {
109 if (list[i] == "3D Camera")
110 capid1 = i;
111 if (list[i] == "USB2.0 HD UVC WebCam")
112 capid0 = i;
113 cout << "device lists:" << list[i] <<'\t'<<"i="<<i<< endl;
114
115 if (list[i]=="CY3014 USB, Analog 01 Capture")
116 {
117 cout<<"video..."<<'\n';
118 }
119 }
120 getchar();
121 return 0;
122 }

涉及的配置:
opencv的环境不用说自己配置还有两个系统库,需要额外的添加 #pragma comment(lib, “strmiids.lib”) #pragma comment(lib, “quartz.lib”)
note:库存在64位和32位的区别,使用时需要和自己的项目位数相同(以上两个库一般系统都是自带的,不需要额外指定库路径,可以直接引用)
参考博客:
https://blog.csdn.net/wangxiuwen12/article/details/87371359
http://theoractice.github.io/2015/09/18/[Win]%20OpenCV%20管理多摄像头的最简洁方法/
https://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=videocapture#reading-and-writing-images-and-video