0

我目前正在使用 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);
}

有谁知道如何做到这一点?我真的很感激帮助。

4

3 回答 3

1

简短的回答是它不能做到,至少不能简单地做到。Tango API 中的 XYZij 结构还不能完全工作。没有“ij”数据。您对缓冲区的检索将在您对其进行编码时工作。内容是一组测量深度点的 X、Y、Z 值,每个回调大约 10000+。每个 X、Y 和 Z 值都是浮点类型,所以不是 CV_8UC1。问题是这些点没有以任何方式排序,因此它们不对应于“图像”或 xy 栅格。它们是深度点的随机列表。有一些方法可以让它们按 xy 顺序排列,但这并不简单。这两个我都做过:

  1. 将它们渲染为图像,深度编码为颜色,然后将图像提取为像素
  2. 使用来自 OpenGL 的模型/视图/透视图并乘以每个点的位置,然后计算出它们的屏幕空间位置(就像 OpenGL 在渲染期间那样)。按 xy 屏幕空间对点进行排序。而不是计算的屏幕空间深度,只需保留原始缓冲区中的 Z 值。

或者

  1. 等到(如果)XYZij 结构被修复,以便它返回 ij 值。
于 2015-04-08T20:41:55.290 回答
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 深度感知避免物体的基础。

于 2015-07-09T18:12:51.243 回答
0

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

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

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

于 2015-04-08T21:21:38.470 回答