2012-01-09 89 views
15

我使用Microsoft Kinect SDK从Kinect获取深度和颜色信息,然后将该信息转换为点云。我需要深度信息与摄像头中心的真实世界坐标作为原点。Microsoft Kinect SDK深度数据到现实世界坐标

我见过一些转换函数,但这些显然是OpenNI和非微软驱动程序。我已经读过来自Kinect的深度信息已经以毫米为单位,并且包含在11位...或其他内容中。

如何将此位信息转换为我可以使用的真实世界坐标?

在此先感谢!

回答

10

这是使用Microsoft.Research.Kinect.Nui.SkeletonEngine类照顾Kinect的内用于Windows库,以及下面的方法:

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

此方法将通过映射产生深度图像基于现实世界的测量,将Kinect整合到可扩展的向量中。

从那里(当我创建了一个过去目),枚举通过Kinect的深度图像创建位图中的字节数组后,创建载体的新列表指向类似以下内容:

 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; 
      } 
     } 

通过这样做,最终结果是以毫米为单位存储的向量列表,并且如果您希望厘米乘以100(等等)。

+0

谢谢刘易斯!这正是我所追求的,尽管我仍然不明白这个不好的业务来获得深度价值。 – 2012-01-10 02:53:13

+1

我相信DepthImageToSkeleton方法已被重构为KinectSensor对象上的MapDepthToSkeletonPoint – 2012-07-03 18:52:50

+0

仅供参考:http://arena.openni.org/OpenNIArena/Applications/ViewApp.aspx?app_id=426 – EdgarT 2012-09-01 00:01:02