简体   繁体   English

如何将深度数据从Kinect 2.0转换为距离值?

[英]How to convert the depth data from a Kinect 2.0 to a distance value?

I would like to take advantage from the depth sensor of the Kinect 2.0 SDK, but not in the sense that this data is drawn or displayed in the format of an image but rather an integer or something alike. 我想从Kinect 2.0 SDK的深度传感器中受益,但不是从某种意义上说,这些数据是以图像的格式绘制或显示的,而是整数或类似的东西。 An example of that is if I have my hand very close to the Kinect, I would get an integer value telling me approximately the range between the camera and the obstacle. 例如,如果我的手非常接近Kinect,我将得到一个整数值,大约告诉我相机和障碍物之间的距离。 maybe something like this. 也许像这样。 As the obstacle moves the Kinect recalculates the distance and updates maybe every secnond or half a second. 随着障碍物的移动,Kinect会重新计算距离并可能每秒钟或半秒更新一次。

The distance between the kinect and the obstacle is 20 cm
The distance between the kinect and the obstacle is 10 cm 
The distance between the kinect and the obstacle is 100 cm

Is that possible? 那可能吗? I searched for tutorials, but al I could find is that the representation is usually using a point cloud or black and white depth image. 我搜索了教程,但我可以发现的是,该表示通常使用点云或黑白深度图像。

The Kinect does indeed use a point cloud. Kinect确实确实使用了点云。 And each pixel in the point cloud has an unsigned short integer value that represents the distance in mm from the Kinect. 而且点云中的每个像素都有一个无符号的短整数值,该值表示距Kinect的距离(以mm为单位)。 From what I can tell the camera is already able to compensate or objects to the sides of its view being further away then whats in front, so all the data represents the depth those objects are away from the plane the Kinects camera is viewing from. 据我所知,相机已经能够补偿物体,或者物体的视野远于前方,因此所有数据都表示这些物体距离Kinects相机所观察的平面的深度。 The Kinect will view up to about 8m but only has reliable data between 4-5m and can't see anything closer than 0.5m. Kinect可以看到大约8m的距离,但只有4-5m之间的可靠数据,看不到任何距离小于0.5m的东西。 Since it sounds like your using it as an obstacle detection system I'd suggest monitoring all the data points in the point cloud and averaging out grouped data points that stand apart from others and interpreting them as their own objects with an approximate distance away. 因为听起来像您将其用作障碍物检测系统,所以建议您监视点云中的所有数据点,并对彼此分开的分组数据点求平均,然后将它们解释为距离很近的自己的对象。 The Kinect also updates with 30 frames per second (assuming your hardware can handle the intensive data stream). Kinect还以每秒30帧的速度更新(假设您的硬件可以处理密集的数据流)。 So you'll simply be constantly monitoring your point cloud for the objects changing distance. 因此,您只需不断监视点云,即可发现距离变化的对象。

If you start by downloading both the SDK and Kinect Studio you can use the depth/IR programming examples and the studio to get a better understanding of how the data can be used. 如果首先下载SDK和Kinect Studio,则可以使用深度/红外编程示例和Studio,以更好地了解如何使用数据。

Even though this question has been asked some time ago and the person questioning most likely solved this by his own, I just wanted to give everyone else who might have the same problem/ question the C++ code to solve this problem. 即使这个问题已经问了一段时间,被询问的人最有可能自己解决了这个问题,但我只想给其他可能遇到相同问题的人/ C ++代码来解决这个问题。

Note: the solution is based on the Kinect 2.0 SDK and if I remember correctly, I took it from one of the examples provided in the SDK Browser 2.0, which comes with the Kinect 2.0 SDK. 注意:该解决方案基于Kinect 2.0 SDK,如果我没记错的话,我是从Kinect 2.0 SDK随附的SDK Browser 2.0中提供的示例中获得的。 I removed all special modifications I've done and just left the most important aspects (so, you most likely have to modify the void and give it a return parameter of some kind). 我删除了已经完成的所有特殊修改,仅保留了最重要的方面(因此,您很可能必须修改void并为其提供某种返回参数)。

The m_pDepthFrameReader is as initialized IDepthFrameReader* m_pDepthFrameReader如初始化的IDepthFrameReader*

void KinectFusionProcessor::getDistance() {
IDepthFrame* frame = NULL;
if (SUCCEEDED(m_pDepthFrameReader->AcquireLatestFrame(&frame))) {
    int width = 512;
    int height = 424;
    unsigned int sz=(512*424);
    unsigned short buf[525 * 424] = {0};
    frame->CopyFrameDataToArray(sz,buf);

    const unsigned short* curr = (const unsigned short*)buf;
    const unsigned short* dataEnd = curr + (width*height);

    while (curr < dataEnd) {
        // Get depth in millimeters
        unsigned short depth = (*curr++);
    }
}
if (frame) frame->Release();
}

This is pretty straightforward. 这很简单。 I do not know the exact code in C++ but in C#, once you have the depth frame you need to do the following: I'll assume that you already know that Y and X point where you want to evaluate the depth value. 我不知道C++的确切代码,但是在C#中,一旦有了深度框架,就需要执行以下操作:我假设您已经知道Y和X指向要评估深度值的位置。

Once you know that, you need to first convert each byte of the depth frame into ushort. 知道这一点后,您需要首先将深度帧的每个字节转换为ushort。

After that, you need to calculate the index inside the depthPixels that corresponds to your X and Y point. 之后,您需要计算depthPixels内与X和Y点相对应的索引。 Typically this is the equation used: 通常,这是使用的公式:

// Get the depth for this pixel
ushort depth = frameData[y * depthFrameDescription.Height + x];

I hope this can be helpful. 我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM