在Python中枚举摄影机

Enumerate over cameras in Python(在Python中枚举摄影机)
本文介绍了在Python中枚举摄影机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在枚举多个操作系统上的Python中的摄像头时遇到一些问题。

以下是我尝试过的一些方法:

import cv2 as cv
num = 0
while 1:
    cap = cv.VideoCapture(num)
    if cap.isOpened():
        # working capture
        num += 1
    else:
        break

使用OpenCV的缺点是OpenCV不提供任何友好的显示名称。此外,在相机上枚举速度很慢,因为您需要实际打开和关闭相机以检查它是否为有效的相机。

我也尝试过使用像PyPylon和pyuvc这样的库。它们有效,但仅适用于特定品牌。

我对堆栈溢出做了一些研究,有些人建议将Python的GStreamer绑定作为一种可能的独立于操作系统的解决方案。这就是我到目前为止所拥有的。

import pgi
pgi.require_version("Gtk", "3.0")
pgi.require_version("Gst", "1.0")
pgi.require_version("GstVideo", "1.0")
from pgi.repository import Gtk, GObject, Gst, GstVideo

Gst.init("")
dm = Gst.DeviceMonitor()
dm.set_show_all_devices(True)

dm.start()

print("Displaying devices.")
for device in dm.get_devices():
    print(device.get_display_name())
print("Displaying providers.")
for provider in dm.get_providers():
    print(provider)

dm.stop()

这是我得到的输出:

Displaying devices.
papalook Microphone
DisplayPort
HDMI
Built-in Output
Built-in Microph
Displaying providers.
osxaudiodeviceprovider

出于某种原因,我没有收到任何网络摄像头,只有音频设备。 你知道我做错了什么吗? 有什么不同的方法我应该采取吗? 谢谢。

推荐答案

我最近遇到了这个问题,甚至没有意识到它有多难! 在这里分享我的解决方案,希望能对某些人有所帮助。

正如已经指出的,没有以跨平台的方式实现这一点的简单方法,我们仍然需要编写特定于平台的代码。 我的解决方案实际上是这里提供的一些方法的组合,所以让我们将其细分。

1.获取摄像头的索引

我们要解决的第一件事是有多少摄像设备连接到计算机。 我们可以使用OpenCV进行此操作,也可以使用上面已经提到的方法。

2.Linux

Linux将有关视频设备的信息存储在/sys/class/video4linux 因为我们知道每个摄像头的索引,所以我们可以这样做来获取额外的信息。

cat /sys/class/video4linux/video1/name

3.Windows

Windows通过也称为WinRT的Windows Runtime提供了一系列有用的API。 Microsoft为此提供了Python library,要获取摄像头信息,我们需要使用DevicesEnumeration接口。

4.MacOS

对于MacOS,我们可以使用与Linux类似的方法。似乎ioreg和system_profiler命令可以提供摄像机名称信息。 不幸的是,我没有MacOS系统来测试这一点,所以我留下了一个TODO。如果有人可以尝试并分享它,那就太好了。

这是我的代码。

import asyncio
import platform
import subprocess

import cv2

if platform.system() == 'Windows':
    import winrt.windows.devices.enumeration as windows_devices

VIDEO_DEVICES = 4


class Camera:

    def __init__(self):
        self.cameras = []

    def get_camera_info(self) -> list:
        self.cameras = []

        camera_indexes = self.get_camera_indexes()

        if len(camera_indexes) == 0:
            return self.cameras

        self.cameras = self.add_camera_information(camera_indexes)

        return self.cameras

    def get_camera_indexes(self):
        index = 0
        camera_indexes = []
        max_numbers_of_cameras_to_check = 10
        while max_numbers_of_cameras_to_check > 0:
            capture = cv2.VideoCapture(index)
            if capture.read()[0]:
                camera_indexes.append(index)
                capture.release()
            index += 1
            max_numbers_of_cameras_to_check -= 1
        return camera_indexes

    # TODO add MacOS specific implementations
    def add_camera_information(self, camera_indexes: list) -> list:
        platform_name = platform.system()
        cameras = []

        if platform_name == 'Windows':
            cameras_info_windows = asyncio.run(self.get_camera_information_for_windows())

            for camera_index in camera_indexes:
                camera_name = cameras_info_windows.get_at(camera_index).name.replace('
', '')
                cameras.append({'camera_index': camera_index, 'camera_name': camera_name})

            return cameras

        if platform_name == 'Linux':
            for camera_index in camera_indexes:
                camera_name = subprocess.run(['cat', '/sys/class/video4linux/video{}/name'.format(camera_index)],
                                             stdout=subprocess.PIPE).stdout.decode('utf-8')
                camera_name = camera_name.replace('
', '')
                cameras.append({'camera_index': camera_index, 'camera_name': camera_name})

            return cameras

    async def get_camera_information_for_windows(self):
        return await windows_devices.DeviceInformation.find_all_async(VIDEO_DEVICES)


camera = Camera()

这篇关于在Python中枚举摄影机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)