首页 文章

Python的libfreenect Kinect 1深度图数据格式

提问于
浏览
3

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

我原先假设每个像素的深度变量 d 表示传感器和找到的点之间的欧几里德距离 . 通过将相机表示为一个点,将矩阵表示为虚拟图像平面,并跟随从相机到平面上的像素的矢量距离 d ,我重建了我认为的实际坐标 . (每个点位于通过相应像素投射的光线的距离 d ) . 如下面在图1中所示,重建的房间 Map (从上面示出)是扭曲的 .

Euclidean Distance

Figure 1: d is Euclidean Distance

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

Depth

Figure 2: d is depth from camera, or z coordinate

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

Original

Figure 3: Original Image

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

1 回答

  • 2

    所有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 数组,我们可以将其转换为点 Cloud .

    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转发 .

相关问题