铅笔

在你的害怕中坚持的越多,你就会越自信
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

opencv根据摄像头名称获取索引值

Posted on 2019-10-14 16:59  黑色の铅笔  阅读(5159)  评论(0编辑  收藏  举报

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