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

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

本文关键字:转换 距离 Kinect 深度 数据      更新时间:2023-10-16

我想利用Kinect 2.0 SDK的深度传感器,但不是因为这些数据是以图像格式绘制或显示的,而是整数或类似的格式。举个例子,如果我的手离Kinect很近,我会得到一个整数值,告诉我相机和障碍物之间的大致距离。也许是这样的。当障碍物移动时,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

这可能吗?我搜索了教程,但我能找到的是,表示通常使用点云或黑白深度图像。

尽管这个问题早就被问过了,提问者很可能自己解决了这个问题,但我只想给其他可能有同样问题的人用C++代码来解决这个问题。

注意:这个解决方案是基于Kinect 2.0 SDK的,如果我没记错的话,我从Kinect 2.0软件开发工具包附带的SDK浏览器2.0中提供的一个例子中得到了它。我删除了我所做的所有特殊修改,只留下了最重要的方面(因此,您很可能必须修改void并给它一个某种返回参数)。

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

Kinect确实使用了点云。点云中的每个像素都有一个无符号的短整数值,表示与Kinect的距离(mm)。据我所知,相机已经能够进行补偿,或者视图两侧的物体比前面的物体更远,所以所有数据都表示这些物体距离Kinect相机观察平面的深度。Kinect可以看到8米左右的图像,但只有4-5米之间的可靠数据,不能看到超过0.5米的图像。由于这听起来像是你把它用作障碍物检测系统,我建议监测点云中的所有数据点,并平均出与其他数据点不同的分组数据点,然后将它们解释为距离大约的自己的物体。Kinect还以每秒30帧的速度更新(假设您的硬件能够处理密集的数据流)。因此,您只需不断监测点云中距离变化的对象。

如果你从下载SDK和Kinect Studio开始,你可以使用深度/IR编程示例和工作室来更好地了解如何使用数据。

这非常简单。我不知道C++中的确切代码,但在C#中,一旦你有了深度框架,你就需要做以下事情:我假设您已经知道要计算深度值的Y和X点。

一旦知道了这一点,就需要首先将深度帧的每个字节转换为ushort。

之后,您需要计算depthPixels内部对应于X和Y点的索引。通常这是使用的方程式:

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

我希望这能有所帮助。