如何将TangoXyxIjData转换为z值的矩阵

时间:2015-04-08 19:52:48

标签: opencv google-project-tango

我目前正在使用Project Tango平板电脑避免机器人避障。我想创建一个z值的矩阵,就像它们出现在Tango屏幕上一样,这样我就可以使用OpenCV来处理矩阵了。当我说z值时,我的意思是每个点距离Tango的距离。但是,我不知道如何从TangoXyzIjData中提取z值并将值组织到矩阵中。这是我到目前为止的代码:

    public void action(TangoPoseData poseData, TangoXyzIjData depthData) {
    byte[] buffer = new byte[depthData.xyzCount * 3 * 4];
    FileInputStream fileStream = new FileInputStream(
            depthData.xyzParcelFileDescriptor.getFileDescriptor());
    try {
        fileStream.read(buffer, depthData.xyzParcelFileDescriptorOffset, buffer.length);
        fileStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    Mat m = new Mat(depthData.ijRows, depthData.ijCols, CvType.CV_8UC1);
    m.put(0, 0, buffer);
}

有谁知道怎么做?我真的很感激帮助。

3 个答案:

答案 0 :(得分:1)

简短的回答是它无法完成,至少不是简单的。 Tango API中的XYZij结构尚未完全正常工作。没有“ij”数据。您对缓冲区的检索将在编码时起作用。内容是测量深度点的一组X,Y,Z值,每个回调大约10000+。每个X,Y和Z值都是float类型,因此不是CV_8UC1。问题是这些点没有以任何方式排序,因此它们不对应于“图像”或xy栅格。它们是深度点的随机列表。有办法让他们进入一些xy顺序,但这并不简单。我做了这两件事:

  1. 将它们渲染为图像,深度编码为颜色,并将图像拉出像素
  2. 使用OpenGL中的模型/视图/透视图,并将每个点的位置相乘,然后计算出它们的屏幕空间位置(就像OpenGL在渲染过程中一样)。按xy屏幕空间对点进行排序。而不是计算的屏幕空间深度,只需保留原始缓冲区的Z值。
    1. 等到(如果)XYZij结构被修复,以便返回ij值。

答案 1 :(得分:1)

我也希望使用Tango来避免机器人的物体。通过简化用例只对位于Tango设备中心视图的任何对象的距离感兴趣,我取得了一些成功。

在Java中:

private Double centerCoordinateMax = 0.020;
private TangoXyzIjData xyzIjData;
final FloatBuffer xyz = xyzIjData.xyz;
double cumulativeZ = 0.0;
int numberOfPoints = 0;
for (int i = 0; i < xyzIjData.xyzCount; i += 3) {
    float x = xyz.get(i);
    float y = xyz.get(i + 1);
    if (Math.abs(x) < centerCoordinateMax && 
        Math.abs(y) < centerCoordinateMax) {
        float z = xyz.get(i + 2);
        cumulativeZ += z;
        numberOfPoints++;
    }
}

Double distanceInMeters;
if (numberOfPoints > 0) {
    distanceInMeters = cumulativeZ / numberOfPoints;
} else {
    distanceInMeters = null;
}

简单地说,这段代码取的是位于x和y轴原点的小方块的平均距离。

centerCoordinateMax = 0.020被确定为基于观察和测试工作。正方形通常在理想条件下包含50个点,在靠近地板时通常包含较少的点数。

我使用tango-caminada应用程序的第2版对此进行了测试,深度测量似乎非常准确。站在距离门口1/2米的地方,我滑向敞开的门,距离变为0.5米到2.5米,这是走廊尽头的墙。

模拟正在导航的机器人我将设备移向路径中的垃圾桶,直到0.5米分离,然后向左旋转直到距离超过0.5米并向前行进。一个过于简化的模拟,但是使用Tango深度感知避免物体的基础。

答案 2 :(得分:0)

你可以通过使用相机内在函数将XY坐标转换为标准化值来实现这一点 - 请看这篇文章 - Google Tango: Aligning Depth and Color Frames - 它正在谈论纹理坐标,但它是完全相同的问题

一旦标准化,移动到屏幕空间x [1280,720],然后Z坐标可用于生成openCV咀嚼的像素值。在使用深度信息进一步着色像素之前,您需要决定如何为与您自己的深度点不对应的像素进行着色,并且建议使用。

最重要的是要记住返回的原始坐标已经使用了你想要的基础向量,即你不想要姿势态度或位置