首页 文章

如何以毫米为单位显示Kinect深度数据

提问于
浏览
0

我正在创建一个程序,可以从Kinect获取两个屏幕截图(一个红外图像和一个深度图像),将其直接加载到两个图片框中,然后通过单击鼠标在红外屏幕截图中测量点的位置 .

我没有问题在红外屏幕截图中得到x-和y-位置,我需要的也是以毫米为单位的深度 - 考虑到红外线和深度图像是从同一台相机拍摄的,所以当我点击鼠标时应将x-和y-坐标链接到深度图像以获取深度值,单位为mm .

我的想法是访问方法 SensorDepthFrameReady 中的变量 short depth = depthPixels[i].Depth; . 但为什么它不起作用?为什么深度图像以灰度显示而不是RGB(与Kinect Studio不同)?

private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
 using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
 {
  if (depthFrame != null)
  {
  depthFrame.CopyDepthImagePixelDataTo(this.depthPixels);
  int colorPixelDDIndex = 0;
  for (int i = 0; i < this.depthPixels.Length; ++i)
  {
   short depth = depthPixels[i].Depth;
   ...
  }
  this.colorBitmapDD.WritePixels(new Int32Rect(0, 0, this.colorBitmapDD.PixelWidth, this.colorBitmapDD.PixelHeight),this.colorPixelsDD,this.colorBitmapDD.PixelWidth * sizeof(int),0);
  }
 }
}

private void imageIR_MouseClick(object sender, System.Windows.Input.MouseEventArgs e)
{
 System.Windows.Point mousePoint = e.GetPosition(imageIR);
 double xpos_IR = mousePoint.X;
 double ypos_IR = mousePoint.Y;
 lbCoord.Content = "x- & y- Koordinate [pixel]: " + xpos_IR + " ; " + ypos_IR;
 zpos.Content = "z- Koordinate [mm]: " + depth;
}

有什么想法来解决问题吗?提前致谢 .

主程序截图:

http://i.stack.imgur.com/bljQ9.jpg

1 回答

  • 0

    一种选择是使用全局变量中的x和y值保存每个深度值 . 也许是 Dictionary<Point,short> . 而在你的MouseClick-handler中读取它: zpos.Content = "z- Koordinate [mm]: " + _depthDic[new Point(xpos_IR,ypos_IR)];

    你通过 private Dictionary<Point,short> _depthDic = new Dictionary<Point,short>(); 声明你的全局变量

    并在SensorDepthFrameReady-handler中设置它:

    for (int i = 0; i < this.depthPixels.Length; ++i)
    {
       Point coords = new Point(depthPixels[i].X, depthPixels[i].Y);
       _depthDic[coords] = depthPixels[i].Depth;
     ...
    }
    

    Edit :另一种方法 . 创建一个包含当前 DepthImageFrame 的全局字段 . 在SensorDepthFrameReady方法中保存此 DepthImageFrame

    private DepthImageFrame _depthImageFrame;
    private bool _imageUsing;
    private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
    {
     using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
     {
      if (depthFrame != null)
      {
          if (!_imageUsing)
              _depthImageFrame = depthFrame;
    
          //your code
      }
     }
    }
    

    然后创建一个方法,将深度值返回到特定的x和y值:

    private int GetDepthValue(DepthImageFrame imageFrame, int x, int y)
    {
       _imageUsing = true;
       short[] pixelData = new short[imageFrame.PixelDataLength];
       imageFrame.CopyPixelDataTo(pixelData);
       var result = ((ushort)pixelData[x + y * imageFrame.Width])>>3 ;
       _imageUsing = false;
       return result;
    }
    

    最后在鼠标单击时显示值:

    private void imageIR_MouseClick(object sender, System.Windows.Input.MouseEventArgs e)
    {
     System.Windows.Point mousePoint = e.GetPosition(imageIR);
     double xpos_IR = mousePoint.X;
     double ypos_IR = mousePoint.Y;
     lbCoord.Content = "x- & y- Koordinate [pixel]: " + xpos_IR + " ; " + ypos_IR;
     if (_depthImageFrame != null)
         zpos.Content = "z- Koordinate [mm]: " + GetDepthValue(_depthImageFrame, Convert.toInt16(mousePoint.X),Convert.toInt16(mousePoint.Y));
    }
    

    也许这可以帮到你:http://www.i-programmer.info/ebooks/practical-windows-kinect-in-c/3802-using-the-kinect-depth-sensor.html

相关问题