【问题标题】:Python's libfreenect Kinect 1 Depth Map Data FormatPython 的 libfreenect Kinect 1 深度图数据格式
【发布时间】:2018-04-14 02:39:35
【问题描述】:

对于一个项目,我一直在尝试将 libfreenect 给出的深度图(深度值为 0-255 的 480 x 640 矩阵)转换为更可用的 (x,y,z) 坐标。

我最初假设每个像素处的深度变量d 表示传感器与找到的点之间的欧几里得距离。通过将相机表示为一个点,矩阵表示为一个虚拟图像平面,并按照从相机到平面上像素的矢量距离d,我重建了我认为的实际坐标。 (每个点位于沿通过相应像素的光线投射的距离d 处)。如下图 1 所示,重建的房间地图(如上图所示)被扭曲了。

图 1:d 是欧几里得距离

如果我假设d 表示从相机到每个点的前向距离,则结果如下图 2 所示。请注意三角形,因为测量点位于从机器人位置投射的光线上。 x和y坐标当然是根据深度缩放的,z就是深度值d

图 2:d 是相机的深度,或 z 坐标

作为参考,这里是如果我不按深度缩放 x 和 y 坐标生成的地图,假设 d 是 z 坐标,并且 plot(x,y,z)。请注意房间地图的矩形形状,因为不假定点位于传感器投射的光线上。

图 3:原始图像

根据以上图像,图 2 或图 3 似乎都是正确的。有谁知道预处理 libfreenect 对捕获的数据点做了什么?我在网上查看过,但没有找到关于在存储在这个矩阵中之前如何预处理深度的文档。感谢您提前提供任何帮助,我很乐意提供任何其他所需信息。

【问题讨论】:

    标签: python kinect openkinect


    【解决方案1】:

    所有 libfreenect 的 depth formats 都会产生值,其中每个 d 代表与相机的距离。有两种特殊格式,其中包括一些有用的预处理。

    • FREENECT_DEPTH_MM 以毫米为单位生成距离。
    • FREENECT_DEPTH_REGISTERED 产生以毫米为单位的距离,其中深度的 (x, y) 与视频的 (x,y) 匹配。

    结果可以是scaled manually 到世界坐标,但这在不同的硬件模型中可能并不完全准确。更健壮的方法是使用通过libfreenect_registration.h 公开的助手。

    FREENECTAPI void freenect_camera_to_world(freenect_device* dev,
                   int cx, int cy, int wz, double* wx, double* wy);
    

    给定一个depth 数组,我们可以将其转换为点云。

    int i = 0;
    std::vector<cv::Point3d> points(mode.width * mode.height);
    for (int y = 0; y < mode.height; y++) {
      for (int x = 0; x < mode.width; x++) {
        double wx, wy;
        double z = depth[i];
        freenect_camera_to_world(x, y, z, &wx, &wy);
        points[i] = cv::Point3d(wx, wy, z);
        i++;
      }
    }
    

    这应该会产生类似于图 2 的结果。要从 Python 调用该函数,需要通过 Python wrapper 转发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-17
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-17
      相关资源
      最近更新 更多