2012-01-09 26 views
15

Estoy usando el SDK de Microsoft Kinect para obtener la información de profundidad y color de un Kinect y luego convertir esa información en una nube de puntos. Necesito que la información de profundidad esté en coordenadas del mundo real con el centro de la cámara como origen.Datos de profundidad de Microsoft Kinect SDK a coordenadas del mundo real

He visto una serie de funciones de conversión, pero aparentemente son para OpenNI y para controladores que no son de Microsoft. He leído que la información de profundidad que viene del Kinect ya está en milímetros, y está contenida en los 11 bits ... o algo así.

¿Cómo convierto la información de este bit en coordenadas del mundo real que puedo usar?

¡Gracias de antemano!

Respuesta

10

Esto se atiende dentro de la Kinect para la biblioteca de Windows utilizando la clase Microsoft.Research.Kinect.Nui.SkeletonEngine, y el siguiente método:

public Vector DepthImageToSkeleton (
    float depthX, 
    float depthY, 
    short depthValue 
) 

Este método mapeará la imagen de profundidad producida por el Kinect en uno que sea vectorial escalable, basado en mediciones del mundo real.

A partir de ahí (cuando he creado una malla en el pasado), después de enumerar el conjunto de bytes en el mapa de bits creado a imagen de la profundidad Kinect, se crea una nueva lista de vector apunta similar al siguiente:

 var width = image.Image.Width; 
     var height = image.Image.Height; 
     var greyIndex = 0; 

     var points = new List<Vector>(); 

     for (var y = 0; y < height; y++) 
     { 
      for (var x = 0; x < width; x++) 
      { 
       short depth; 
       switch (image.Type) 
       { 
        case ImageType.DepthAndPlayerIndex: 
         depth = (short)((image.Image.Bits[greyIndex] >> 3) | (image.Image.Bits[greyIndex + 1] << 5)); 
         if (depth <= maximumDepth) 
         { 
          points.Add(nui.SkeletonEngine.DepthImageToSkeleton(((float)x/image.Image.Width), ((float)y/image.Image.Height), (short)(depth << 3))); 
         } 
         break; 
        case ImageType.Depth: // depth comes back mirrored 
         depth = (short)((image.Image.Bits[greyIndex] | image.Image.Bits[greyIndex + 1] << 8)); 
         if (depth <= maximumDepth) 
         { 
          points.Add(nui.SkeletonEngine.DepthImageToSkeleton(((float)(width - x - 1)/image.Image.Width), ((float)y/image.Image.Height), (short)(depth << 3))); 
         } 
         break; 
       } 

       greyIndex += 2; 
      } 
     } 

Al hacerlo, el resultado final de esto es una lista de vectores almacenados en milímetros, y si quiere centímetros, multiplique por 100 (etc.).

+0

Gracias Lewis! Eso es exactamente lo que buscaba, aunque todavía no entiendo el negocio del cambio de bits para obtener el valor de profundidad. –

+1

Creo que el método DepthImageToSkeleton se ha refactorizado a MapDepthToSkeletonPoint en el objeto KinectSensor –

+0

Solo para el registro: http://arena.openni.org/OpenNIArena/Applications/ViewApp.aspx?app_id=426 – EdgarT

Cuestiones relacionadas