【问题标题】:mapping the camera name to opencv camera index将相机名称映射到 opencv 相机索引
【发布时间】:2019-07-18 03:55:13
【问题描述】:

我曾经在 opencv 的 v3.4.1 中使用此功能将相机名称映射到相机索引,但我已将其升级到 v4.1.0。但是这个功能不再起作用了。相机索引不再匹配。知道为什么会这样以及如何正确映射吗?

我实际上正在使用 Emgu 4.1.0 和 c#。下面我使用 DirectShowLib nuget 来获取 VideoInput 设备的列表。在 v3 中,顺序与 opencv 相机索引完美匹配。 v4中没有,好像顺序不对。

using DirectShowLib;
private DsDevice[] directShowCameras = 
DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);

    private int getCameraIndexForName(string name)
    {
        for (int i = 0; i < directShowCameras.Count(); i++)
        {
            if(directShowCameras[i].Name.ToLower().Contains(name.ToLower()))
            {
                return i;
            }
        }
        return -1;
    }

【问题讨论】:

  • 似乎如果我在打开相机索引时指定 DShow,它匹配正常。但这是为什么呢?默认后端是否已更改,如果更改,现在是什么,是否更好?
  • 好吧,我发现 4.1.0 中的默认后端是 MSMF(微软媒体基金会)。任何人都知道如何使用此框架在 c# 中获取视频捕获设备列表?我怀疑索引会正确匹配

标签: c# opencv emgucv directshow


【解决方案1】:

原来 v4.1.0 优先考虑 MSMF 而不是 DirectShow。这些框架之间的相机枚举也不同。因此,使用此函数将相机友好名称转换为相机索引。这使用 SharpDx.MediaFoundation nuget 库在 c# 中调用 MSMF API

    using SharpDX.MediaFoundation;
    public static int GetCameraIndexForPartName(string partName)
    {
        var cameras = ListOfAttachedCameras();
        for(var i=0; i< cameras.Count(); i++)
        {
            if (cameras[i].ToLower().Contains(partName.ToLower()))
            {
                return i;
            }
        }
        return -1;
    }

    public static string[] ListOfAttachedCameras()
    {
        var cameras = new List<string>();
        var attributes = new MediaAttributes(1);
        attributes.Set(CaptureDeviceAttributeKeys.SourceType.Guid, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid);
        var devices = MediaFactory.EnumDeviceSources(attributes);
        for (var i = 0; i < devices.Count(); i++)
        {
            var friendlyName = devices[i].Get(CaptureDeviceAttributeKeys.FriendlyName);
            cameras.Add(friendlyName);
        }
        return cameras.ToArray();
    }

为了 100% 使用较新的 MSMF,我还会在创建相机对象时指定此后端。

capture = new VideoCapture(index, VideoCapture.API.Msmf);

这个后端似乎对包括 macbook air 的内置摄像头在内的摄像头工作得更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-19
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多