项目需求控制和打开两个USB摄像头,并且根据相机的PID和VID来打开指定的相机,来区分主副相机,在Windows下可以通过AForge.Video.DirectShow库来实现,但是Ubuntu下没这个库,找了很多资料也没找到Ubuntu下怎么实现,最后只能借助Libusb库来实现,虽然不是很理想,但是应该可以勉强实现。

第一步:  先来了解  什么是USB Device Path/ 什么是PID、VID

Windows操作系统通过一个“设备路径”来唯一“标识”接入系统中的USB设备/接口,这个"设备路径"就是USB Device Path。USB Device Path 常常被传入 Win32 的API函数 CreatFile() 来与USB设备建立通信。更多解释参见 Windows USB Device Path,当然Ubuntu下也有。

VID和PID唯一标识一个设备,HardwareID是为了给系统识别的 ,他是根据PID/VID而生成的。这个与序列号没什么关系,序列号一般都是厂家固化到芯片中的信息而已。GUID只是为了标志你安装的设备是属于一个什么类当中,这个类可以显示再设备管理器中。比如:你可以定义一个类,当然这个类有与系统中任何类都不同的GUID,然后选择一个图标和类名,就可以同网卡等其他设备一起显示在设备管理器下的根目录中了

根据USB规范的规定,所有的USB设备都有供应商ID(VID)和产品识别码(PID),主机通过不同的VID和PID来区别不同的设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向USB执行论坛申请,每个供应商的VID是唯一的,PID由供应商自行决定,理论上来说,不同的产品、相同产品的不同型号、相同型号的不同设计的产品最好采用不同的PID,以便区别相同厂家的不同设备。

VID和PID通常情况下有两种存储方式,第一种是主控生产商的VID和PID,存储在主控的bootcode中;第二种是设备生产商的VID和PID,该VID和PID存储在主控外部的非易失性存储设备中(EEPROM或Flash)的设备固件中,当USB设备连接主机时,如果固件中有设备生产商的VID和PID,会将该VID和PID报告给主机,而忽略主控生产商的VID和PID。所以理论上一个USB存储设备的VID应该是设备生产商的VID,而不是主控生产商的VID,这两个VID应该是不同的(主控生产商自己生产的设备除外)。

由于VID和PID重复并不会对产品的使用带来严重影响,很多USB设备生产商(山寨厂居多)为了方便,并不会向USB执行论坛申请自己的VID,而是依然沿用主控生产商的VID或随便向产品写入VID和PID;同时,正规厂家只需要申请VID,PID由厂家自行确定,所以存在相同型号的产品,可能采用了不同的主控(商业需要,很正常),而他们的PID是一样的,基于上述原因通过VID和PID就不能准确识别USB设备的主控型号,这个问题大家在使用USB设备的过程中需要注意。

第二步:查看USB Device Path的方法

Windows系统下

1、鼠标右键“我的电脑”,选择“管理”,进入“计算机管理”。

2、在“计算机管理”界面,依次选择“设备管理器”、“图像设备”、摄像头的型号,选中点击鼠标右键,选择“属性”

选择硬件id,就可以看到usb相机的vid,pid是0x18EC,0x3399(这个是我电脑这款usb相机的pid、vid,不同的设备pid、vid是不一样的)的设备,右击属性里找到 Device instance path,别急,这还不是全部的USB Device Path。

最终 USB Device Path 组成格式是:\\?\(第一部分,固定的), hid#vid_1fc9&pid_0130#a&2eb8245&0&0000(第二部分,即Device instance path,\用#替换), #{4d1e55b2-f16f-11cf-88cb-001111000030}"(第三部分,HID类型标识值前加个#)。另外注意在脚本里写入此参数时需要用双引号括起来,类似如下:

"\\?\hid#vid_1fc9&pid_0130#6&20AC856D&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

第三步:程序获取USB Device Path方法:

windows下,C#可以通过AForge.Video.DirectShow库来获取,并且非常方便,获取方法如下

 public static FilterInfoCollection videoDevices;// 枚举所有视频输入设备videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);videoDevices[i].MonikerString   //返回值就是Device instance path

Ubuntu下获取方法1:

因为python可以跨平台,Windows下可以Ubuntu下都可以用:但是Windows下需要把dll放到系统目录。Ubuntu下不需要

pip3 install PyQt5pip3 install pyqt5-toolspip install pyusbDownload libusb from libusb releases解压 libusb-xxx.7z并且把\MS64\dll\libusb-1.0.dll复制到C:\Windows\System32

代码如下:

# FileName : usbdemo.py
# Author   : Adil
# DateTime : 2019/9/1 10:26
# SoftWare : PyCharm
import usball_devs = usb.core.find(find_all=True)print(all_devs)
for d in all_devs:if (d.idVendor == 'VID_04F2') & (d.idProduct == 'PID_B541'):print(d)

用libusb库的时候需要用知道usb相机的个数,因为libusb获取到的usb设备很多不是摄像头设备

import cv2class Camera:def __init__(self, cam_preset_num=10):self.cam_preset_num = cam_preset_numdef get_cam_num(self):cnt = 0for device in range(0, self.cam_preset_num):stream = cv2.VideoCapture(device)grabbed = stream.grab()stream.release()if not grabbed:breakcnt = cnt + 1return cntif __name__ == '__main__':cam = Camera()cam_num = cam.get_cam_num()print(cam_num)

Ubuntu下获取方法2:

Ubuntu下所以的信息都是以文件形成储存,所以可以通过读取设备文件来区别索引号和pid 、vid

    def get_usb_camera_index(self):# 获取USB摄像头的索引camera_path = Path('/sys/class/video4linux/')camera_list = list(camera_path.glob('video*'))camera_list.sort()index = 0for i in range(len(camera_list)):camera = camera_list[i]name_file = camera.joinpath('name')with open(name_file, 'r') as f:info = f.readline()if 'USB' in info:index = ibreakreturn index

在Ubuntu下链接多个usb相机时,通过OpenCV打开,只能通过,cv2.VideoCapture(index)来打开指定相机,但是一般情况哪个先上电,哪个index就是0,没法确定打开的是哪个相机。

最后通过端口重映射到新的固定名字,并且设置其权限为可读。使用对应的id端口映射到固定的名字上(看不懂无所谓,按教程来,往下走)终端输入:

sudo vi /etc/udev/rules.d/rplidar.rules

1.按i,进入编辑模式

2.复制以下代码,修改ID,自定义设备的名字,在此特别注意

在我使用的 ubuntu 18.04 环境下,插入一个 usb 相机,会出现两个 /dev/video*,这不是 bug 而是 v4l2 的特性。这里直接给出解决办法,参考了这个问题下的回答,加入 ATTR{index}=="0"来获取真实设备,对于多个 usb 摄像头的话,采用类似规则,ID 号查找的方式不变

KERNEL=="video*", ATTR{index}=="0",ATTRS{idVendor}=="038f", ATTRS{idProduct}=="6001", MODE:="0777", SYMLINK+="people_video"

3.按Esc,输入 :wq (保存退出)创建生效后重新插拔一下USB摄像头或者执行一下命令

sudo service udev reload
sudo service udev restart

查看USB摄像头是否重映射:

ls -l /dev |grep video

可以看到已经映射成功

4.在Ubuntu下打开摄像头

平时是这样的

cap = cv2.VideoCapture(0) # 打开USB摄像头对象

现在就可以精准打开指定摄像头了

cap = cv2.VideoCapture("/dev/people_video")  # 打开人体识别摄像头
cap = cv2.VideoCapture("/dev/goods_video")  # 打开物体识别摄像头

这样就可以打开指定的摄像头,虽然有点曲线救国,但是完美解决问题

Ubuntu下如何获取usb相机的PID/VID并打开指定的相机相关推荐

  1. libusb获取usb设备的idVendor(vid),idProduct(pid),以及Serial Number

    发表于2015/6/23 21:55:11  4594人阅读 最近在做关于usb设备的项目,用到了libusb,发现关于这个的函数库的介绍,讲解很少,下面仅仅是简单展示一些基本的使用方法,以备后用. ...

  2. Linux(Ubuntu)下C++获取可用内存、当前最大内存等信息

    Linux(Ubuntu)下C++获取可用内存.当前最大内存等信息 使用sysconf函数获取当前可用内存大小 例程: /// @brief Get the available memory in M ...

  3. JAVA获取安卓系统下usb_Android 获取 usb 权限的两种方法

    前言: 最近工作上遇到几个USB模块在android平台上适配使用的情况,所以要用到USB权限获取问题 ##USB权限获取有以下2种方式: 一.直接在AndroidManifest.xml文件中进行如 ...

  4. ubuntu下安装Realtek usb无线网卡驱动(8821cu)

    写在前面:电脑内置无线网卡出了些小问题,尽管可以搜到网络但是信号很弱,这不能够啊,所以先买了一款tenda u9 usb无线网卡,奈何在ubuntu上无法自动安装驱动,并且官方并不支持其在ubuntu ...

  5. Linux —— Ubuntu下C++获取CPU使用率、GPU使用率、GPU温度

      非代码      首先介绍在Ubuntu下不使用代码查看的方式来查看CPU使用率.GPU使用率.GPU温度. 查看CPU使用率:top查看GPU使用率及温度:nvidia-smi   代码     ...

  6. ubuntu下如何使用USB转串口设备

    usb转串口使用总结: 首先看通用教程: 安装: sudo apt-get install minicom 配置: 1. 在终端中输入minicom以启动minicom: 2.先按下Ctrl+ a, ...

  7. 【VritualBox】虚拟机VirtualBox中ubuntu下加载USB设备报错:busy with a previous request.Plaease try again later

    1.问题描述 在VirtualBox中添加USB设备时,报错: USB device with 'SanDisk Crurer Blade'UUID {*} is busy with a previo ...

  8. ubuntu下安装无线USB网卡驱动 (磊科 NW336)

    本人在ubuntu14.04 亲测确认! 首先查询型号,找到对应的linux驱动代码,官方网址: http://www.realtek.com.tw/downloads/downloadsView.a ...

  9. 关于Android手机MTP模式连接的一些设置(win7和ubuntu下,以红米1s为例)

    有些手机的MTP模式在电脑上识别不了,需要一些设置才可以,下面就网上收集来的一些设置方法集中贴过来: 一. win7下 参考:http://blog.ammrli.com/?p=1117 1.在设备管 ...

最新文章

  1. Cannot run Eclipse; JVM terminated. Exit code=13
  2. Java 9:流API的增强
  3. 西安交大送大一新生这本书,你读过吗?12本有趣有料的科普书盘点
  4. 网站集成支付宝接口安装教程
  5. Buider模式应用实践
  6. 数论-某寒假训练赛 Round1 (Feb, 2018)
  7. Atitit 数据库视图与表的wrap与层级查询规范
  8. ROS——创建工作空间并编译示例
  9. cydia 未能连接服务器,iOS 越狱全过程,解决cydia或sileo无法联网问题
  10. 三维全景虚拟现实:现在的VR全景行业怎么样?|时空克隆 三维视频融合 投影融合 点卯 魔镜系列
  11. ZooKeeper官方Java例子解读
  12. AWS EFS vs EBS vs S3(差异和何时使用?)
  13. 控件:可见、隐身、走开
  14. xf0x9f java mysql_MySql导入数据报错Incorrect string value: ‘xF0x9Fx90x82’
  15. 数据库原理:了解范式(1NF、2NF、3NF、BCNF),做例题快速弄懂
  16. 银河麒麟4.0.2配置网络源
  17. USB2.0协议原文阅读笔记
  18. android 循环弹幕,Android弹幕效果
  19. 安装win8+Ubuntu双系统 传统BIOS方式引导模式 ubuntu引导windows
  20. mysql导入导出语句6_mysql的导入导出 | 吴老二

热门文章

  1. 【软件教程】如何将夸克网盘挂载为本地磁盘【Docker+AList+RaiDrive】
  2. xXx时间屏保+背景图片
  3. php手册下载后打开没有内容,word保存后内容不见了怎么办
  4. hdu 4379The More The Better
  5. 怎么在微信公众平台上传PPT?
  6. 无界——多元合作的发散思维
  7. TL437x-EVM评估板测试手册(2)
  8. 企业邮箱09年的十大新闻
  9. 【线程知识点】-- 自旋锁
  10. win10清理c盘_系统C盘磁盘空间不够用的解决办法