对于一个项目,我一直在尝试将libfreenect(480×640矩阵,深度值为0-255)给出的深度图转换为更可用的(x,y,z)坐标。
我原先假设每个像素的深度变量d
表示传感器和找到的点之间的欧几里德距离。通过将相机表示为一个点,将矩阵表示为虚拟图像平面,并且跟随从相机到平面上的像素的矢量距离d
,我重建了我认为的实际坐标。 (每个点沿着通过相应像素投射的光线位于距离d
处)。如下面图1中所示,重建的房间地图(如上所示)是扭曲的。
图1:d
是欧几里德距离
如果我改为假设d
表示从相机到每个点的前向距离,结果如下图所示。请注意三角形,因为测量点位于机器人投射的光线上。的立场。 x和y坐标当然是根据深度缩放的,z是深度值d
。
图2:d
是相机的深度,或z坐标
作为参考,如果我不按深度缩放x和y坐标,假设d
是z坐标,则绘制(x,y,z),这里是生成的地图。请注意房间地图的矩形形状,因为不假定点位于传感器投射的光线上。
图3:原始图片
根据上面的图像,似乎图2或图3都是正确的。有谁知道预处理libfreenect对捕获的数据点做了什么?我已经在网上查了一下,但是没有找到关于在存储到这个矩阵之前如何预处理深度的文档。感谢您提前提供任何帮助,我很乐意提供任何其他所需信息。
答案 0 :(得分:2)
所有libfreenect的depth formats都会产生值,其中每个VLOOKUP
表示距离相机的距离。有两种特殊格式,包括一些有用的预处理。
d
以毫米为单位产生距离。FREENECT_DEPTH_MM
生成以毫米为单位的距离,其中FREENECT_DEPTH_REGISTERED
深度与视频的(x, y)
匹配。结果可以是scaled manually到世界坐标,但在不同的硬件模型中可能不完全准确。更强大的方法是使用通过libfreenect_registration.h
公开的帮助程序。
(x,y)
给定FREENECTAPI void freenect_camera_to_world(freenect_device* dev,
int cx, int cy, int wz, double* wx, double* wy);
数组,我们可以将其转换为点云。
depth
这应该产生类似于图2的结果。要从Python调用,该函数需要通过Python wrapper转发。