【问题标题】:Matching Kinect Audio with Video将 Kinect 音频与视频匹配
【发布时间】:2011-09-28 20:25:12
【问题描述】:

我有一个使用 Kinect(或者更有可能是其中四个)处理视频会议的项目。现在,我的公司在我们的 VTC 房间里使用这些极其昂贵的摄像头。希望是,使用连接在一起的几个 Kinect,我们可以降低成本。计划是让其中四个/五个覆盖一个 180 度的弧线,以便 Kinect 可以看到整个房间/桌子(仍然比我们目前的相机便宜很多!)。应用程序会根据桌边的谈话者来选择来自 Kinect 的视频流。计划在理论上很好,但我遇到了障碍。

据我所知,没有办法知道哪个麦克风阵列对应于 Kinect Runtime 对象。我可以使用以下方法获取代表每个 Kinect 的对象:

Device device = new Device();
Runtime[] kinects = new Runtime[device.Count];
for( int i = 0; i < kinects.Length; i ++ )
    kinects[i] = new Runtime(i);

每个麦克风阵列使用:

var source = new KinectAudioSource();
IEnumerable<AudioDeviceInfo> devices = source.FindCaptureDevices();
foreach( AudioDeviceInfo in device in devices)
{
    KinectAudioSource devSpecificSource = new KinectAudioSource();
    devSpecificSource.MicrophoneIndex = (short)device.DeviceIndex;
}

但是我找不到任何方法来知道运行时 A 对应于 KinectAudioSource B。这对于我正在使用的两个 Kinect 来说不是一个大问题(我只是猜测哪个是哪个,如果它们则切换它们'错了),但是当我们使用多达四五个 Kinect 时,我不想在每次应用程序运行时都进行任何类型的校准。我考虑过假设 Runtime 和 KinectAudioSource 对象的顺序相同(运行时索引 0 对应于设备中的第一个 AudioDeviceInfo),但这似乎有风险。

所以,问题是:有什么方法可以将运行时对象与其 KinectAudioSource 匹配?如果不是,是否保证它们的顺序正确,以便我可以将 Runtime 0 与设备中的第一个 KinectAudioSource 麦克风索引匹配?

更新: 最后,我猛烈抨击了 WPF 的单线程单元要求和 Kinect 音频的多线程单元要求,足以让两者一起行动。问题是,据我所知,Kinect Runtime 对象和 KinectAudioSources 的顺序排列。我在一个相当吵闹的实验室里(我是房间里可能有 40 名实习生之一),所以很难测试,但我相当肯定我插入的两个 Kinect 的顺序已经切换。我有两个 Runtime 对象和两个 KinectAudioSource 对象。当第一个 KinectAudioSource 报告声音直接来自它前面时,我实际上是站在与第二个 Runtime 对象关联的 Kinect 前面。所以不能保证两人的订单会排成一行。所以现在,重复这个问题:我如何将 KinectAudioSource 对象与 Nui.Runtime 对象匹配?现在,我只连接了两台 Kinect,但由于目标是四五个……我需要一个具体的方法来做到这一点。

更新 2: 把我工作中的两台 Kinect 带回家玩。三台 Kinect,一台电脑。有趣的东西(一次安装它们实际上很痛苦,而且其中一个视频源似乎不起作用,所以我现在回到 2)。 musefan 的回答让我希望我错过了 AudioDeviceInfo 对象中的某些内容,这些内容可以阐明这个问题,但没有运气。我在名为 NuiCamera.UniqueDeviceName 的运行时对象中发现了一个有趣的字段,但我找不到它与 AudioDeviceInfo 中的任何内容之间的任何链接。

这些字段的输出,希望福尔摩斯能看到线程并注意到一个连接:

Console.WriteLine("Nui{0}: {1}", i, nuis[i].NuiCamera.UniqueDeviceName);
//Nui0: USB\VID_0409&PID_005A\6&1F9D61BF&0&4
//Nui1: USB\VID_0409&PID_005A\6&356AC357&0&3

Console.WriteLine("AudioDeviceInfo{0}: {1}, {2}, {3}", audios.IndexOf(audio), device.DeviceID, device.DeviceIndex, device.DeviceName);
//AudioDeviceInfo0: {0.0.1.00000000}.{1945437e-2d55-45e5-82ba-fc3021441b17}, 0, Microphone Array (Kinect USB Audio)
//AudioDeviceInfo1: {0.0.1.00000000}.{6002e98f-2429-459a-8e82-9810330a8e25}, 1, Microphone Array (2- Kinect USB Audio)

更新 3: 我不是在寻找校准技术。我正在寻找一种在运行时将 Kinect 摄像头与应用程序内的麦克风阵列相匹配的方法,而无需之前的设置。请停止发布可能的校准技术。发布问题的全部目的是找到一种方法来避免需要用户进行设置。

更新 4: WMI 似乎绝对是要走的路。不幸的是,我没有太多时间来处理它,因为我一直在努力让 3 个 Kinect 相互配合。关于 USB 集线器无法处理带宽的问题?我已经告诉我的老板,似乎没有任何简单的方法可以将 3+ Kinects 连接到普通计算机而不是蓝屏。我可能仍然会在空闲时间尝试做这件事,但就工作而言.. 这几乎是一条死胡同。

感谢大家的回答,抱歉我无法发布有效的解决方案。

【问题讨论】:

  • 认为 我在某处听说 SDK 目前只允许您一次从一个设备获取音频...我可能错了,但您可能想验证在这条路走得太远之前。
  • 骨骼跟踪和深度图有限制(只能从主 Kinect 获取),但据我所知,音频没有任何此类限制。我会尽快确认的。
  • 致任何阅读我评论的人:我错了,您可以从任何 Kinect 获取深度信息。尽管如此,骨骼信息仍然仅限于主要 Kinect,因此玩家索引信息也是如此。
  • 这看起来是一个非常有趣的项目。祝你好运。我自己还没有机会弄乱 Kinect!

标签: c# kinect


【解决方案1】:

我查看了 SDK 文档,老实说,它并不是很好。此外,我没有任何 Kinect 设备可以对此进行测试。

我要做的第一件事是为每个设备创建一个包含所有有用属性值的输出列表,然后我会开始在这两者之间寻找看起来可以用于链接的匹配项。对于我找到的每一个,我都会测试它是否能胜任。

所以我会有一个简单的控制台应用程序来输出以下属性值:

对于每个 AudioDeviceInfo

  • 设备 ID = X
  • DeviceIndex = X
  • 设备名称 = X

对于每个 KinectAudioSource

  • 麦克风索引 = X

对于每个运行时

  • InstanceIndex = X

然后查找值中的任何匹配项。 SDK 中似乎没有其他任何东西真正有用。但是SDK返回AudioDeviceInfo和Runtime数组时,必须有内部逻辑。

无论如何,我希望你能以某种方式做对

【讨论】:

  • 不幸的是,我设置了 KinectAudioSource.MicrophoneIndex 和 Runtime.InstanceIndex 字段,所以这些都没用。其余的看起来应该很有用,但没有什么可以比较的。有关这些字段的内容,请参阅上面的更新。
【解决方案2】:

我会从所有人那里获取音频流,然后比较音量。 一旦你有了它,你就可以确定实际在说话的 kinects 3d 空间中的“对象”或人。

从那里您需要确定该对象/人在哪些摄像机中可见......

是的,这是一个复杂的项目......不过 kinect 非常棒......我对 API 了解不多,但它不会给你带来距离之类的人吗?

祝你好运:)

【讨论】:

  • 这需要在每次启动应用程序时进行校准,或者至少在每台新计算机上进行校准。这是我正在努力避免的事情。
【解决方案3】:

我会一一校准 kinect,将唯一的设备标识符对(相机 ID、麦克风 ID)写入文件。然后,在您的应用程序中,您可以在启动时使用该文件来同步麦克风实例和摄像头实例(即,创建一个将一个摄像头实例与一个麦克风实例相关联的表)。由于 kinect 内部的摄像头和麦克风可能各有自己的 USB 接口 ic(通过内部 USB 集线器连接),因此在技术上没有事先校准的情况下无法将两者关联起来,因为这两个设备标识符可能完全不相关。此外,您可能希望在 Kinect 单元上放置标签并在初始化文件中引用这些标签。

【讨论】:

  • 将单个 Kinect 插入多个不同的 USB 端口后,我可以说 NuiCamera.UniqueDeviceName 取决于 Kinect 插入的 USB 端口。我还看到在切换 USB 端口时 AudioDeviceInfo.DeviceID 发生了变化,尽管它确实有时会切换回原始数字......奇怪。这个解决方案比沃迪的答案更适合校准......这将是一个史诗般的痛苦。我正在寻找不需要校准的东西
  • LewisBenge 写的访问 WMI 设备驱动程序接口可能是一个想法,你肯定需要从摄像头/麦克风的 USB 芯片中获取一些信息。在我看来,使用你现在拥有的硬件设置,没有某种唯一标识符校准或类似的东西是不可能的。另一种可能性可能是您打开 kinect,移除内部 USB 集线器并自己构建一个简单的 USB 集线器,将数据字段附加到两个 USB 流,将相机和麦克风标识为一个单元。使用合适的 MCU,这可能不会太难实现。
【解决方案4】:

Microsoft Research 提供的 API 实际上并未提供此功能。 Kinect 本质上是多个摄像头和一个麦克风阵列,每个传感器都有一个独特的驱动程序堆栈,因此没有与物理硬件设备的链接。实现这一点的最佳方法是使用 Windows API,通过 WMI 并获取您为 NUI 相机和麦克风获取的设备 ID,并使用 WMI 查找它们连接到哪个 USB 总线(因为每个 Kinect传感器必须在自己的总线上)然后你就会知道哪个设备匹配什么。这将是一项昂贵的操作,因此我建议您在启动或检测设备时执行此操作,并保持信息持续存在,直到您知道硬件配置更改或应用程序重置为止。通过 .NET 使用 WMI 有很好的文档,但这里有一篇专门讨论通过 WMI/.NET 的 USB 设备的文章:http://www.developerfusion.com/article/84338/making-usb-c-friendly/

【讨论】:

    【解决方案5】:

    听起来很有趣,也许你需要一些“自动校准”。

    也许有一些“每个 USB 连接的远程电源开关”(连接到 USB 电源线的 io 卡)。因此,您可以一个接一个地自动打开 Kinect,现在您就知道哪个麦克风属于哪个摄像头了。

    或者类似的...

    问候! 斯蒂芬

    【讨论】:

      【解决方案6】:

      曼尼马克,

      我看到的唯一链接是相机的 UniqueDeviceName 属性等于它的“设备实例路径”。

      在我计算机上的设备管理器中进行一些研究,我可以看出相机 UniqueDeviceName 末尾的最后 2 个数字(0&3、0&4)是递增值(基于控制器 + 端口?)。

      我的建议是您根据最后一位数字对摄像机列表进行排序,并根据其 DeviceID 属性对音频设备进行排序。这样我想当你遍历你的相机列表时,你可以使用音频设备列表中的相应索引来匹配 2 一起。

      顺便说一句,这是我的第一篇文章,所以如果我错了,请温柔...

      【讨论】:

        猜你喜欢
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-13
        • 1970-01-01
        • 2015-03-25
        相关资源
        最近更新 更多