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

OpenCV指定pid和vid通过MSMF打开摄像头

在基于OpenCV的项目中,实际开发过程会面临设备上存在多个摄像头,需要指定摄像头的pid和vid打开摄像头。在OpenCV通过MSMF打开摄像头时,需要传入摄像头的index,因此需要在打开该摄像头前需要找出摄像头的index,下面给出通过微软的MF API找出MSMF枚举摄像头index的代码:

#include <windows.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <string>
#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfreadwrite.lib")
#pragma comment(lib, "mfuuid.lib")struct CameraInfo {int index;      // OpenCV 摄像头索引int vid;        // Vendor ID (e.g., 0x046D for Logitech)int pid;        // Product ID (e.g., 0x0825 for C920)std::string symbolicLink; // 设备符号链接
};// 获取所有 Media Foundation 摄像头的 PID/VID
std::vector<CameraInfo> getMFCameraList() {std::vector<CameraInfo> cameras;IMFAttributes* pAttributes = nullptr;IMFActivate** ppDevices = nullptr;UINT32 count = 0;// 初始化 Media FoundationMFStartup(MF_VERSION);// 配置设备枚举参数(仅视频采集设备)MFCreateAttributes(&pAttributes, 1);pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);// 枚举设备MFEnumDeviceSources(pAttributes, &ppDevices, &count);for (UINT32 i = 0; i < count; i++) {WCHAR* symbolicLink = nullptr;UINT32 length = 0;// 获取设备 Symbolic Link(包含 VID/PID)ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,&symbolicLink,&length);if (symbolicLink) {std::wstring ws(symbolicLink);std::string devicePath(ws.begin(), ws.end());// 解析 VID/PID(格式:\\?\usb#vid_xxxx&pid_xxxx...)size_t vidPos = devicePath.find("vid_");size_t pidPos = devicePath.find("pid_");if (vidPos != std::string::npos && pidPos != std::string::npos) {std::string vidStr = devicePath.substr(vidPos + 4, 4);std::string pidStr = devicePath.substr(pidPos + 4, 4);int vid = std::stoi(vidStr, nullptr, 16);int pid = std::stoi(pidStr, nullptr, 16);cameras.push_back({-1, vid, pid, devicePath});}CoTaskMemFree(symbolicLink);}ppDevices[i]->Release();}if (pAttributes) pAttributes->Release();if (ppDevices) CoTaskMemFree(ppDevices);MFShutdown();return cameras;
}// 匹配 OpenCV 摄像头索引
int findOpenCVCameraIndex(int targetVid, int targetPid) {auto cameras = getMFCameraList();int opencvIndex = 0;while (true) {cv::VideoCapture cap(opencvIndex, cv::CAP_MSMF);if (!cap.isOpened()) {break; // 没有更多摄像头}// 检查当前摄像头是否匹配目标 PID/VIDfor (const auto& cam : cameras) {if (cam.vid == targetVid && cam.pid == targetPid) {std::cout << "Found camera at OpenCV index: " << opencvIndex << std::endl;cap.release();return opencvIndex;}}cap.release();opencvIndex++;}return -1; // 未找到
}int main() {// 示例:查找 Logitech C920(VID=0x046D, PID=0x0825)int targetVid = 0x046D;int targetPid = 0x0825;int cameraIndex = findOpenCVCameraIndex(targetVid, targetPid);if (cameraIndex != -1) {cv::VideoCapture cap(cameraIndex, cv::CAP_MSMF);if (cap.isOpened()) {std::cout << "Successfully opened target camera!" << std::endl;// 进行视频捕获...}} else {std::cerr << "Target camera not found." << std::endl;}return 0;
}

http://www.lqws.cn/news/443179.html

相关文章:

  • Spring AOP @Before (前置通知): 在目标方法执行前做什么?
  • 智能家居HA篇 二、配置Home Assistant并实现外部访问
  • android 省市区联动选择
  • 计算机视觉阶段一:CV入门基础
  • Xsens动作捕捉技术用于研究机器人的运动控制、姿态调整以及人机交互
  • .NET 的配置系统
  • 【Mini-F5265-OB开发板试用测评】2、PWM驱动遥控车RX2接收解码带马达驱动控制IC
  • 华为OD机试_2025 B卷_构成正方形数量(Python,100分)(附详细解题思路)
  • 如何获取Java对象的大小
  • MQTT 消息队列传输协议(Message Queuing Telemetry Transport)
  • 【深度学习】生成对抗网络(GANs)深度解析:从理论到实践的革命性生成模型
  • 优化 Python 爬虫性能:异步爬取新浪财经大数据
  • 46道Jenkins高频题整理(附答案背诵版)
  • Jenkins通过Pipeline流水线方式编译Java项目
  • IP 地理库的使用指南:从基础应用到深度实践​
  • Redis 持久化机制详解:RDB、AOF 原理与面试最佳实践(AOF篇)
  • IntersectionObserver API应用场景示例代码详解
  • 医疗低功耗智能AI网络搜索优化策略
  • jquery 赋值时不触发change事件解决——仙盟创梦IDE
  • Kafka性能压测报告撰写
  • Outlook邮箱开通发信服务及OAuth2验证开通
  • 靶场(二十五)---小白心得靶场体会---Access
  • 基于Python+PySide6构建的夸克网盘批量工具,支持批量转存与分享
  • 使用NPOI库导出多个Excel并压缩zip包
  • Qt 解析复杂对象构成
  • 基于C#的Baumer相机二次开发教程
  • VACM 详解:SNMPv3 的访问控制核心
  • 基于大模型的急性结石性胆囊炎全流程预测与诊疗方案研究
  • 小白畅通Linux之旅-----Rsync+sersync实现数据实时同步
  • 九九乘法表