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

本文关键字:显示 Kinect 深度 数据 为单位 | 更新日期: 2023-09-27 18:31:13

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

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

我的想法是访问变量短深度 = 深度像素[i]。深度;方法SensorDepthFrameReady中。但是为什么它不起作用呢?为什么深度图像以灰度而不是 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;
}

有什么想法可以解决问题吗?提前谢谢。

主程序截图:

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

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

一种选择是将每个深度值及其 x 和 y 值保存在全局变量中。也许是Dictionary<Point,short>.并且比在您的鼠标点击处理程序中阅读它: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;
 ...
}

编辑:另一种方法。创建一个保存当前DepthImageFrame的全局字段。将此DepthImageFrame保存在 SensorDepthFrameReady 方法中:

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