2011-07-05 12 views
28

Tengo un proyecto que trata sobre videoconferencia usando Kinect (o, más probablemente, cuatro de ellos). En este momento, mi empresa utiliza estas cámaras estúpidamente caras para nuestras salas de VTC. La esperanza es que, usando un par de Kinects unidos entre sí, podamos reducir los costos. El plan es tener cuatro/cinco de ellos cubriendo un arco de 180 grados para que los Kinects puedan ver toda la habitación/mesa (¡aún mucho más barato que nuestras cámaras actuales!). Las aplicaciones elegirían un flujo de video proveniente de un Kinect en función de quién está hablando en la mesa. Plan está bien en teoría, pero me he encontrado con un problema.Coincidencia de audio Kinect con video

Por lo que puedo decir, no hay forma de saber qué matriz de micrófonos corresponde al objeto Kinect Runtime. Puedo conseguir un objeto que representa cada uno de Kinect usando:

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

Y cada conjunto de micrófonos usando:

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

pero no puedo encontrar ninguna manera de saber que en tiempo de ejecución A corresponde a KinectAudioSource B. Esto no es un gran problema para los dos Kinects que estoy usando (voy a adivinar cuál es cuál, y cambiarlos si están equivocados), pero cuando tengamos hasta cuatro o cinco Kinects, no quiero tener que hacer cualquier tipo de calibración cada vez que se ejecuta la aplicación. Considero suponer que los objetos Runtime y KinectAudioSource estarán en el mismo orden (el índice de tiempo de ejecución 0 corresponde al primer AudioDeviceInfo en dispositivos), pero parece riesgoso.

Entonces, la pregunta: ¿hay alguna forma de hacer coincidir un objeto Runtime con su KinectAudioSource? De lo contrario, ¿está garantizado que estarán en el orden correcto para que pueda hacer coincidir Runtime 0 con el primer índice de micrófono KinectAudioSource en dispositivos?

ACTUALIZACIÓN: Por último se estrelló contra la cara requisito apartamento individual hilo de WPF y múltiples requisito de que el audio de Kinect apartamento hilo suficiente para que los dos se comporten juntos. El problema es que, por lo que puedo ver, el orden de los objetos Kinect Runtime y KinectAudioSources no se alinea en . Estoy en un laboratorio bastante ruidoso (soy uno de ... tal vez 40 pasantes en la sala), así que es difícil de probar, pero estoy bastante seguro de que el orden se cambia para los dos Kinect que he conectado. Tengo dos objetos Runtime y dos objetos KinectAudioSource. Cuando el primer KinectAudioSource informa que un sonido proviene directamente de él, en realidad me encuentro frente al Kinect asociado con el segundo objeto Runtime. Por lo tanto, no hay garantía de que los pedidos de los dos se alineen. Entonces, para repetir la pregunta: ¿cómo puedo unir el objeto KinectAudioSource con el objeto Nui.Runtime? En este momento, solo tengo dos Kinects conectados, pero dado que el objetivo es cuatro o cinco ... Necesito una forma concreta de hacerlo.

ACTUALIZACIÓN 2: Trajé los dos Kinects que tengo en el trabajo a casa para jugar. Tres Kinects, una computadora. Cosas divertidas (en realidad fue un fastidio tenerlas todas instaladas a la vez, y una de las transmisiones de video no parece estar funcionando, así que estoy de vuelta a 2 por ahora). La respuesta de musefan me hizo esperar que me hubiera perdido algo en los objetos AudioDeviceInfo que arrojaría algo de luz sobre este problema, pero no tuve suerte. Encontré un campo de aspecto interesante en objetos Runtime llamado NuiCamera.UniqueDeviceName, pero no encuentro ningún vínculo entre eso y nada en AudioDeviceInfo.

La producción de estos campos, con la esperanza de Sherlock Holmes ve el hilo y da cuenta de una conexión:

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) 

Actualización 3: no estoy en busca de técnicas de calibración.Estoy buscando una manera de hacer coincidir la cámara Kinect con su matriz de micrófonos dentro de la aplicación en tiempo de ejecución, sin necesidad de configuración previa. Por favor deja de publicar posibles técnicas de calibración. El objetivo de publicar la pregunta fue encontrar la manera de evitar que el usuario tenga que configurarlo.

ACTUALIZACIÓN 4: WMI definitivamente parece ser el camino a seguir. Desafortunadamente, no he tenido mucho tiempo para trabajar en él, ya que he estado luchando solo para que 3 Kinects jueguen bien entre ellos. ¿Algo sobre los concentradores USB que no pueden manejar el ancho de banda? Le informé a mi jefe que no parece haber una manera fácil de conectar 3+ Kinects a una computadora normal y no a una pantalla azul. Todavía podría tratar de trabajar en esto en mi tiempo libre, pero en lo que respecta al trabajo ... es casi un callejón sin salida.

Gracias por las respuestas chicos, lo siento, no pude publicar una solución de trabajo.

+0

I * piensa * He oído en alguna parte que el SDK en la actualidad sólo le permite obtener audio de un dispositivo a la vez .. . Podría estar equivocado en eso, pero es posible que desee verificar antes de ir demasiado lejos en este camino. –

+0

Existe una limitación en el seguimiento del esqueleto y en el mapa de profundidad (solo puede obtenerlo desde el Kinect primario), pero no hay limitaciones en el audio hasta donde yo sé. Me aseguraré de eso pronto. – Coeffect

+0

Para cualquiera que lea mi comentario: me equivoqué, puede obtener información detallada de cualquier Kinect. La información esqueletal aún está limitada al Kinect primario, y por lo tanto, la información del índice del jugador también lo está. – Coeffect

Respuesta

11

La API proporcionada por Microsoft Research en realidad no proporciona esta capacidad. Kinect es esencialmente cámaras múltiples y una matriz de micrófonos con cada sensor que tiene una pila de controladores única, por lo que no existe un vínculo con el dispositivo de hardware físico. La mejor manera de lograr esto sería usar la API de Windows en su lugar, a través de WMI y tomar los ID del dispositivo que obtienes para la cámara NUI y micrófonos, y usar WMI para encontrar a qué bus USB están conectados (como cada Kinect el sensor debe estar en su propio bus) entonces sabrá qué dispositivo coincide con qué. Esta será una operación costosa, por lo que le recomendaría que haga esto en la puesta en marcha, o la detección de los dispositivos y mantenga la información persistente hasta que sepa que la configuración del hardware cambia o la aplicación se restablece. Usar WMI a través de .NET está bastante bien documentado, pero aquí hay un artículo que habla específicamente sobre dispositivos USB a través de WMI/.NET: http://www.developerfusion.com/article/84338/making-usb-c-friendly/.

0

He echado un vistazo a la documentación de SDK y no es genial con toda honestidad. Además, no tengo ningún dispositivo Kinect para probar esto.

Lo primero que haría es crear una lista de salida de todos los valores de propiedad útiles para cada dispositivo, luego comenzaría a buscar coincidencias entre los dos que parecieran que pueden usarse para enlaces. Para cada uno que encuentro, probaría para ver si hace el trabajo.

por lo que tendría una aplicación de consola sencilla para dar salida a los siguientes valores de la propiedad:

Para Cada AudioDeviceInfo

  • DeviceID = X
  • DeviceIndex = X
  • DeviceName = X

Para cada fuente de KinectAudio

  • MicrophoneIndex = X

Para cada tiempo de ejecución

  • InstanceIndex = X

luego buscar las coincidencias en los valores. Nada más en el SDK parece realmente útil. Pero debe haber una lógica interna para el SDK cuando devuelve las matrices de AudioDeviceInfo y Runtime.

De todos modos, espero que salga bien de alguna manera

+0

Desafortunadamente, establecí los campos KinectAudioSource.MicrophoneIndex y Runtime.InstanceIndex, por lo que son inútiles. El resto parece que deberían ser útiles, pero no hay nada con qué compararlos. Ver la actualización anterior para los contenidos de esos campos. – Coeffect

0

me gustaría tener el flujo de audio de todos ellos y luego comparar los niveles de volumen. Una vez que tienes eso, puedes determinar el "objeto" o la persona en el espacio 3D de kinects que realmente está hablando.

A partir de ahí es necesario determinar qué cámaras este objeto/persona es visible en ...

Yeh este es un proyecto complejo ... kinect es bastante impresionante, aunque ... No sé mucho acerca de la API, pero ¿no te da distancias y ese tipo de personas?

buena suerte con él :)

+0

Esto requeriría calibrar cada vez que se iniciara la aplicación, o al menos en cada computadora nueva. Esto es algo que estoy tratando de evitar. – Coeffect

0

me acaba de calibrar los KINECTS uno por uno, escribiendo los pares de identificador de dispositivo único (ID de la cámara, micrófono id) en un archivo. En su aplicación, puede usar ese archivo en el momento del inicio para sincronizar instancias de mircophone e instancias de cámara (es decir, crear una tabla que relacione una instancia de cámara con una instancia de micrófono). Como la cámara y el micrófono dentro del kinect probablemente tengan su propia interfaz usb ic (conectada a través de un concentrador USB interno), técnicamente no hay forma de relacionar los dos sin calibración previa, ya que los dos identificadores del dispositivo probablemente no estén relacionados. También es posible que desee colocar etiquetas en las unidades Kinect y hacer referencia a estas etiquetas dentro de su archivo de inicialización.

+0

Después de enchufar un solo Kinect en varios puertos USB diferentes, puedo decir que NuiCamera.UniqueDeviceName depende del puerto USB en el que está conectado el Kinect. También he visto el AudioDeviceInfo.DeviceID cambiar al cambiar los puertos USB, aunque volvió a cambiar al número original a veces ... raro. Esta solución sería mucho más trabajo para calibrar que la respuesta de Wardy ... sería simplemente un dolor épico. Estoy buscando algo que _no requiera calibración_. – Coeffect

+0

Acceder a la interfaz del controlador del dispositivo WMI como escribió LewisBenge podría ser una idea, definitivamente necesita obtener información del chip usb de la cámara/micrófono. Con la configuración de hardware que tiene ahora, en mi opinión, es imposible prescindir de algún tipo de clibración de identificador único o similar. Otra posibilidad podría ser que abra el kinect, retire el concentrador USB interno y construya un concentrador usb simple, que conecte un campo de datos a las dos transmisiones usb que identifican la cámara y el micrófono como una unidad. Con el mcu correcto esto podría no ser demasiado difícil de lograr. – trilion99

0

Suena interesante, tal vez necesita un poco de "calibración automática".

Tal vez con algunos "interruptores de alimentación remotos para cada conexión usb" (tarjeta io conectada a las líneas de alimentación usb). Entonces puedes encender un Kinect uno detrás del otro automáticamente y ahora sabes qué micrófono pertenece a cada cámara.

o algo así ...

Saludos! Stefan

3

Mannimarco,

el único vínculo que veo es que la propiedad UniqueDeviceName de una cámara es igual a su 'ruta de la instancia del dispositivo.

Investigando un poco en el administrador de dispositivos en mi computadora puedo decir que los últimos 2 números al final del UniqueDeviceName de la cámara (0 y 3, 0 y 4) son valores incrementales (¿controlador/puerto?).

Mi sugerencia es que ordene su lista de cámaras según esos últimos dígitos, y ordene sus dispositivos de audio en su propiedad DeviceID. De esta manera, supongo que cuando iteras sobre tu lista de cámaras, puedes usar el índice correspondiente en la lista de dispositivos de audio para unir los dos.

Por cierto, este es mi primer post así que por favor ser suave si estoy equivocado ...

Cuestiones relacionadas