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
