2011-07-05 73 views
28

我有一个使用Kinect(或者更可能是其中四个)处理视频会议的项目。现在,我的公司为我们的VTC房间使用这些价格非常昂贵的相机。希望是,使用一对Kinect链接在一起,我们可以降低成本。计划中有四/五个覆盖180度弧线,因此Kinects可以看到整个房间/桌子(仍然比我们现有的相机便宜很多!)。应用程序会根据桌子上的对象选择来自Kinect的视频流。理论上计划很好,但我碰到了一个障碍。将Kinect音频与视频相匹配

据我所知,没有办法确定哪个麦克风阵列对应于Kinect运行时对象。使用

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

而且每个麦克风阵列:我可以使用代表每个Kinect的对象

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

,但我找不到任何办法知道运行时对应于KinectAudioSource B.这不是这是我使用的两个Kinect的一个大问题(我只是猜测哪个是哪个,如果他们错了就切换它们),但是当我们得到四个或五个Kinect时,我不需要每次应用程序运行时进行任何类型的校准。我考虑过假设运行时和KinectAudioSource对象的顺序是相同的(运行时索引0对应于设备中的第一个AudioDeviceInfo),但这似乎有风险。

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

UPDATE: 最后撞上我的脸对WPF的单线程单元要求和Kinect的声音的多线程公寓需求足以让两个表现在一起。问题是,据我所知,Kinect运行时对象和KinectAudioSources的排列顺序是而不是。我在一个相当响亮的实验室(我是其中一个,也许在这个房间里有40个实习生),所以很难测试,但我相当肯定,我插入的两个Kinect的顺序是切换的。我有两个运行时对象和两个KinectAudioSource对象。当第一个KinectAudioSource报告声音直接来自它前面时,我实际上站在与第二个Runtime对象关联的Kinect前面。所以不能保证两者的订单会一致。所以现在,重复这个问题:我如何使用Nui.Runtime对象匹配KinectAudioSource对象?现在,我只有两个Kinects,但由于目标是四到五个。我需要一个具体的方法来做到这一点。

更新2: 带来了我在工作回家的两个Kinects玩。三个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个Kinect连接到普通计算机,而不是蓝屏。我可能仍然会在空闲时间尝试解决这个问题,但就工作而言......这几乎是一个死路一条。

感谢您的答案,很抱歉,我无法发布工作解决方案。

+0

我觉得* *听说某处的SDK目前只允许您在同一时间从一个设备获取音频..我可能是错的,但是你可能想在这条道路上走得太远之前进行验证。 –

+0

骨骼跟踪和深度图有一个限制(只能从主要的Kinect中获得),但据我所知,音频没有任何限制。我会尽快确定的。 – Coeffect

+0

对任何阅读我的评论的人来说:我错了,你可以从任何Kinect获得深度信息。尽管如此,骨骼信息仍然局限于主要的Kinect,因此玩家指数信息也是如此。 – Coeffect

回答

11

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/

0

我看了一下SDK文档,并不是很诚实。更多我没有任何Kinect设备来测试这个。

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

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

对于每个AudioDeviceInfo

  • 的DeviceID = X
  • DeviceIndex = X
  • 设备名称= X

对于每个KinectAudioSource

  • MicrophoneIndex = X

为每个运行

  • InstanceIndex = X

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

无论如何,我希望你得到它的权利在某种程度上

+0

不幸的是,我设置了KinectAudioSource.MicrophoneIndex和Runtime.InstanceIndex字段,所以这些字段没用。其余的看起来应该是有用的,但没有什么可以比较的。请参阅上面的更新以了解这些字段的内容。 – Coeffect

0

我会得到所有他们的音频流,然后比较音量。 一旦你有了,你可以确定实际上讲话的kinects 3d空间中的“对象”或人物。

从那里,你需要确定哪些相机这个对象/人可见...

叶,这是一个复杂的工程...... Kinect的是相当真棒,但...我不知道很多有关API但它不会给你距离和这样的人?

好运吧:)

+0

每次启动应用程序或至少在每台新计算机上都需要进行校准。这是我努力避免的事情。 – Coeffect

0

我只想校准kinects一个接一个,写的唯一设备标识符对(摄像机ID,麦克风ID)到一个文件中。在您的应用程序中,您可以在启动时使用该文件来同步麦克风实例和相机实例(即创建一个将一个相机实例与一个麦克风实例关联的表格)。由于相机和麦克风内部的kinect可能每个都有自己的usb接口ic(通过内置usb集线器连接),因此两个设备标识符可能完全无关,因此在技术上无法将两者相关联,因为两个设备标识符可能完全无关。您也可以将标签放在Kinect设备上,并在初始化文件中引用这些标签。

+0

将单个Kinect插入多个不同的USB端口后,我可以说NuiCamera.UniqueDeviceName取决于Kinect插入的USB端口。我也看到AudioDeviceInfo.DeviceID在切换USB端口时发生了变化,尽管它有时会切换回原来的数字......奇怪。这个解决方案比起Wardy的答案来做更多的校准工作......这只会是一场史诗般的痛苦。我正在寻找一些不需要校准的东西。 – Coeffect

+0

以LewisBenge的方式访问WMI设备驱动程序界面可能是一个想法,您肯定需要从相机/麦克风的USB芯片获取一些信息。通过现在的硬件设置,在我看来,如果没有某种独特的标识符或类似的标识是不可能的。另一种可能性可能是您打开kinect,移除内部USB集线器并自行构建一个简单的USB集线器,将数据字段附加到两个将摄像头和麦克风标识为一个单元的USB流。用正确的单片机可能不难实现。 – trilion99

0

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

也许与一些“每个USB连接远程电源开关”(Io卡连接到USB电力线)。所以你可以自动打开一个Kinect,现在你知道哪个麦克风属于哪个摄像头。

或类似的东西...

关心! 斯特凡

3

Mannimarco,

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

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

我的建议是根据最后的数字对照相机列表进行排序,并将您的音频设备排序到其DeviceID属性中。这种方式,我想当你迭代你的相机列表,你可以使用audiodevice列表中的相应索引来匹配2。

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