Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从接口名称而不是相机编号创建openCV VideoCapture_Python_Opencv_Interface_Udev - Fatal编程技术网

Python 从接口名称而不是相机编号创建openCV VideoCapture

Python 从接口名称而不是相机编号创建openCV VideoCapture,python,opencv,interface,udev,Python,Opencv,Interface,Udev,创建视频捕获的正常方法如下: cam=cv2.VideoCapture(n) 其中n对应于/dev/video0,dev/video1 但是因为我正在建造一个机器人,它使用多个摄像头来完成不同的任务,我需要确保它被分配到正确的摄像头,我创建了udev规则,创建了带有符号链接的设备,每当插入特定的摄像头时,都指向正确的端口 它们似乎在工作,因为当我查看/dev目录时,我可以看到以下链接: /dev/front\u cam->video1 但是我不知道现在该如何使用它 我想我可以从文件名打开它,就像

创建视频捕获的正常方法如下:

cam=cv2.VideoCapture(n)

其中n对应于
/dev/video0
dev/video1

但是因为我正在建造一个机器人,它使用多个摄像头来完成不同的任务,我需要确保它被分配到正确的摄像头,我创建了udev规则,创建了带有符号链接的设备,每当插入特定的摄像头时,都指向正确的端口

它们似乎在工作,因为当我查看
/dev
目录时,我可以看到以下链接:

/dev/front\u cam->video1

但是我不知道现在该如何使用它

我想我可以从文件名打开它,就像它是一个视频一样,但是
cam=cv2.VideoCapture('/dev/front\u-cam')
不起作用

cv2.VideoCapture('/dev/video1')

它不会抛出错误,它会返回一个VideoCapture对象,而不是一个打开的对象(
cam.isOpened()
返回
False
)。

import re
导入子流程
进口cv2
导入操作系统
device_re=re.compile(“总线\s+(?P\d+)\s+设备\s+(?P\d+)。+ID\s(?P\w+:\w+)\s(?P+)$”,re.I)
df=子进程。检查_输出(“lsusb”,shell=True)
对于df.split('\n')中的i:
如果我:
信息=设备匹配(i)
如果信息:
dinfo=info.groupdict()
如果dinfo['tag']中的“Logitech,Inc.网络摄像头C270”:
打印“找到照相机”
总线=dinfo[“总线”]
设备=dinfo[“设备”]
打破
设备索引=无
对于os.listdir(“/sys/class/video4linux”)中的文件:
real_file=os.path.realpath(“/sys/class/video4linux/”+文件)
打印真实文件
打印“/”+str(总线[-1])+“-”+str(设备[-1])+“/”
如果real_文件中的“/”+str(总线[-1])+“-”+str(设备[-1])+“/”:
设备索引=实际文件[-1]
打印“万岁,设备索引为”+str(设备索引)
摄像机=cv2.视频捕获(int(设备索引))
尽管如此:
(抓取,帧)=相机。读取()#抓取第一帧
cv2.imshow(“摄像机”,帧)
key=cv2.waitKey(1)和0xFF
首先在USB设备列表中搜索所需字符串。获取总线和设备号


在video4linux目录下查找符号链接。从realpath中提取设备索引并将其传递给VideoCapture method。

我找到了一个较短的解决方案,而不是建议的解决方案,这感觉有点粗糙

我只是看看符号链接点的位置,找到其中的整数,然后使用它

import subprocess

cmd = "readlink -f /dev/CAMC"
process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)

# output of form /dev/videoX
out = process.communicate()[0]

# parse for ints
nums = [int(x) for x in out if x.isdigit()]

cap = cv2.VideoCapture(nums[0])

如果您知道相机的型号,可以在
/dev/v4l/by id/…
中查找。我们使用的是HDMI-USB视频转换器,连接方式如下:

#! /usr/bin/env python
import os
import re
import cv2

DEFAULT_CAMERA_NAME = '/dev/v4l/by-id/usb-AVerMedia_Technologies__Inc._Live_Gamer_Portable_2_Plus_5500114600612-video-index0'

device_num = 0
if os.path.exists(DEFAULT_CAMERA_NAME):
    device_path = os.path.realpath(DEFAULT_CAMERA_NAME)
    device_re = re.compile("\/dev\/video(\d+)")
    info = device_re.match(device_path)
    if info:
        device_num = int(info.group(1))
        print("Using default video capture device on /dev/video" + str(device_num))
cap = cv2.VideoCapture(device_num)

这将跟随设备名称符号链接到
/dev/video
名称,然后解析该名称作为设备编号。

我的每个video4linux设备都创建了2个设备节点。例如,
/dev/video0
/dev/video1
都与我的内部网络摄像头相关。当我插入第二个USB网络摄像头时,
/dev/video2
/dev/video3
都会出现。但是,我只能使用每对中编号较低的设备进行视频捕获(即
/dev/video0
/dev/video2

我用
udevadm监视器
观看了我的设备到达,然后用
udevadm信息--path=$path\u FROM_udevadm\u监视器--attribute walk检查了每个摄像头设备。用于视频捕获的设备具有
ATTR{index}==“0”

也许您不需要尝试打开
/dev/video1
,而只需要打开
/dev/video0

cam = cv2.CaptureVideo("/dev/video0")

其他答案中未探讨的一种可能性是使用/sys/class/video4linux/video*/目录中的“name”文件

例如:

def get_camera(camera_name):
    cam_num = None
    for file in os.listdir("/sys/class/video4linux"):
        real_file = os.path.realpath("/sys/class/video4linux/" + file + "/name")
        with open(real_file, "rt") as name_file:
            name = name_file.read().rstrip()
        if camera_name in name:
            cam_num = int(re.search("\d+$", file).group(0))
            found = "FOUND!"
        else:
            found = "      "
        print("{} {} -> {}".format(found, file, name))
    return cam_num
其中:

get_camera('HUE')
FOUND! video1 -> HUE HD Pro Camera: HUE HD Pro C
    video0 -> HP HD Camera: HP HD Camera

能否从程序中读取符号链接,以便以编程方式获取字符串“/dev/video1”?如果是的话,你能从字符串(1)中提取数字并将其输入到你的openCV捕获对象吗?我对你的问题投了赞成票,我想这是个不错的问题。
get_camera('HUE')
FOUND! video1 -> HUE HD Pro Camera: HUE HD Pro C
    video0 -> HP HD Camera: HP HD Camera