28

我有一个使用 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),但这似乎有风险。

那么问题来了:有什么方法可以将 Runtime 对象与其 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 中的任何内容之间的任何链接。

这些字段的输出,希望 Sherlock Holmes 看到线程并注意到连接:

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 连接到普通计算机而不是蓝屏。我可能仍然会在空闲时间尝试做这件事,但就工作而言……这几乎是一条死胡同。

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

4

6 回答 6

11

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

于 2011-07-13T04:22:32.693 回答
3

曼尼马尔科,

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

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

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

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

于 2011-07-13T14:58:44.770 回答
0

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

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

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

对于每个 AudioDeviceInfo

  • 设备 ID = X
  • 设备索引 = X
  • 设备名称 = X

对于每个 KinectAudioSource

  • 麦克风索引 = X

对于每个运行时

  • 实例索引 = X

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

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

于 2011-07-12T15:59:29.147 回答
0

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

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

是的,这是一个复杂的项目......虽然 kinect 非常棒......我对 API 了解不多,但它不会给你距离和这样的人吗?

祝你好运:)

于 2011-07-12T16:04:59.637 回答
0

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

于 2011-07-12T23:46:38.130 回答
0

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

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

或类似的东西...

问候!斯特凡

于 2011-07-13T14:11:25.373 回答