当前位置: 首页 > news >正文

Opencv根据USB摄像头PID\VID号,获取对应摄像头索引

1.引言

电脑插多个USB摄像头时,当插拔或者开机之后,Opencv对应的摄像头索引会发生改变,导致Opencv打开摄像头会开错,比如笔记本自带一个摄像头,插上一个USB摄像头时,有时自带的摄像头索引是0,有时是1。十分困扰,因此本文通过获取摄像头设备的VID与PID号(这两个号是出厂自带的,不会发生改变),获取对应的Opencv索引值,打开摄像头。为了方便使用,本人将其导出动态库文件,并采用C++或Python调用该动态库。

温馨提示:同一厂家出的同一型号摄像头,他的vid和pid是一样的,利用上述方法就不得行,所以你可以在购买摄像头的时候跟客服说,让他们给每个摄像头不同的vidpid号,我经常在淘宝买摄像头,他们可以提供这个服务。

2.C++程序导出动态库

windows下获取所有摄像头VIDPID,及其索引的程序参考【通过Opencv打开指定摄像头的方法】。本人环境为vs2019,注意在属性设置里面,高级→字符集→使用多字节字符集

#include <iostream>
#include <string>
#include <vector>
#include <DShow.h>
#include <CString>
#include <atlstr.h>
#pragma   comment(lib,"Strmiids.lib")#define LRDLLTEST_EXPORTS //先定义宏#ifdef LRDLLTEST_EXPORTS
#define LRDLLTEST_API __declspec(dllexport)
#else
#define LRDLLTEST_API __declspec(dllimport)
#endifextern "C" LRDLLTEST_API int getCamIDFromPidVid(const char* pidvid);LRDLLTEST_API int getCamIDFromPidVid(const char* pidvid)
{// example std::string pidvid = "0001";std::vector<std::string> devList; //设备列表int iCameraNum = 0;			//设备个数CString str;ICreateDevEnum* pDevEnum = NULL;IEnumMoniker* pEnum = NULL;HRESULT hr = NULL;CoInitialize(NULL);hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pDevEnum));if (SUCCEEDED(hr)){hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);if (hr == S_OK){//枚举捕获设备IMoniker* pMoniker = NULL;ULONG cFetched;while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&pPropBag));if (SUCCEEDED(hr)){//获取设备路径,路径里包含pidvid的信息VARIANT varName;varName.vt = VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"DevicePath", &varName, 0);		//read函数只能够读取CLSID, FriendlyName, DevicePath这三种CString sdev(varName);std::string strStr;strStr = sdev.GetBuffer(0);//std::cout << "----:\n" << strStr<<std::endl;devList.push_back(strStr);iCameraNum++;pPropBag->Release();}pMoniker->Release();}}}//std::cout << devList.size() << std::endl;for (int i = 0; i < devList.size(); i++) {std::cout << devList[i] << std::endl;}int iRet = -1;//对比,得到id,没有符合的就返回-1for (int i = 0; i < devList.size(); i++){int index = devList[i].find(pidvid);if (index != -1){iRet = i;break;}}CoUninitialize();return iRet;
}

程序编写完毕之后,在配置一下属性,方便导出动态库,如下。然后生成解决方案

 生成完毕,将在x64/Release文件夹下生成python_ues_cpp.dll与python_ues_cpp.lib,python_ues_cpp是我自己的名字,实际名字是根据你的方案来的。

3.python调用

查看usb设备的vid和pid,输出是这样的,也可以在设备管理器里面看

 

设备管理器里面的vid和pid是大写的字母(其实是16进制),在程序中我们使用的时候要改成小写

所以我们在程序中指定一些关键词就可,简单的调用程序如下:

# -*- coding: utf-8 -*-
from ctypes import *
import cv2
fileName="python_use_cpp.dll"
func=cdll.LoadLibrary(fileName)
string=bytes("vid_0001&pid_0001",encoding="utf-8")
#string="vid_0001&pid_0001".encode()
a=func.getCamIDFromPidVid(string)
print(a)
cap = cv2.VideoCapture(a,cv2.CAP_DSHOW) # 摄像头的ID不同设备上可能不同while 1:ret,img0=cap.read()if not ret:continuecv2.imshow('result', img0)key =cv2.waitKey(1)  # 1 millisecondif key & 0xFF == ord('q') or key == 27:break
cv2.destroyAllWindows()

3.C++调用

#include <iostream>
#include <opencv2/opencv.hpp>
//
//#pragma comment (lib,"python_use_cpp.lib")
extern "C" __declspec(dllexport) int getCamIDFromPidVid(const char* pidvid);
int main(int avgc, char** argv) {const char* pidvid = "vid_0001&pid_0001";int A = getCamIDFromPidVid(pidvid);//int A=getCamIDFromPidVid(argv[1]);std::cout << A << std::endl;cv::VideoCapture camera0(A, cv::CAP_DSHOW);if (!camera0.isOpened()) {std::cout << "can not open" << std::endl;return 1;}while (true){cv::Mat frame0;camera0 >> frame0;cv::imshow("frame", frame0);char c = cv::waitKey(1);if (c == 27){break;cv::destroyAllWindows();}}return 0;
}


http://www.taodudu.cc/news/show-6102266.html

相关文章:

  • rk3588调试之imx415摄像头
  • 推荐用于环境识别的机器人摄像头
  • python opencv 摄像头_opencv python中摄像头参数的设置
  • 树莓派CSI摄像头使用
  • leetcode 968 监控摄像头
  • 根据硬件ID查看摄像头型号方案,可查任何一款摄像头芯片来源
  • android查看摄像头信息,获取Android设备上的详细的摄像头信息
  • python获取摄像头型号_python opencv设置摄像头分辨率以及各个参数的方法_python
  • python获取摄像头型号,python3.6 opencv获取摄像头代码
  • 我的世界服务器自动被踢怎么可以进去,我的世界中国版服务器中如何解决玩家作弊的简单方法...
  • VS2019+WDK10编写xp平台的驱动
  • Windows XP中手动安装驱动程序的方法
  • xp驱动和Win7驱动的区别
  • windows XP 驱动开发环境搭建
  • 戴尔1420装XP方法和驱动
  • window XP驱动开发(一)如何下载WDK
  • Window XP驱动开发(十) 驱动程序的基本结构
  • (14)[驱动开发]配置环境 VS2019 + WDK10 写 xp驱动
  • Window XP驱动开发(二) 环境搭建(VS2008+WDK+DDKWzard)及示例源码分析
  • DBA必知的170张Oracle常用动态性能表介绍
  • Linux-tcpdump
  • 【Linux】定时任务crontab和at命令详解
  • Java8 通关攻略
  • taro小程序直播
  • 计蒜客--蒜头君的新游戏
  • 原生小程序转Taro开发
  • 手把手系列之三十——手把手教你做番薯小煎饼
  • 夏彭年老夫子论孔子
  • 【C++进阶知识】C++类的继承和派生
  • 小红书怎么涨粉最快?小红书涨粉最快的方法分享