经过几周的等待,我终于有了我的Project Tango。我的想法是创建一个应用程序,生成我的房间的点云,并将其导出到.xyz数据。然后,我将使用.xyz文件在浏览器中显示点云!我开始编写和调整Google的github上的点云示例。
现在我使用onXyzIjAvailable(TangoXyzIjData tangoXyzIjData)
来获取x y和z值的帧;要点。然后我以Vector3
的形式将这些帧保存在PCLManager中。在我完成扫描房间后,我使用以下方法将所有Vector3
从PCLManager写入.xyz文件:
OutputStream os = new FileOutputStream(file);
size = pointCloud.size();
for (int i = 0; i < size; i++) {
String row = String.valueOf(pointCloud.get(i).x) + " "
+ String.valueOf(pointCloud.get(i).y) + " "
+ String.valueOf(pointCloud.get(i).z) + "\r\n";
os.write(row.getBytes());
}
os.close();
一切正常,而不是编译错误或崩溃。唯一似乎出错的是云中点的旋转或平移。当我看到点云时,一切都搞砸了;我扫描的区域无法识别,但点数与记录的相同。
我不能将PoseData与XyzIjData一起使用吗?我是这个主题的新手,并且很难理解PoseData究竟做了什么。有人可以向我解释并帮我修复点云吗?
答案 0 :(得分:3)
是的,您必须使用TangoPoseData
。
我猜您正在使用TangoXyzIjData
;但是这样得到的数据与设备的位置以及拍摄时设备的倾斜程度有关。
这是我如何解决这个问题:
我从java_point_to_point_example开始。在这个例子中,他们用2个不同的坐标系得到2个不同点的坐标,然后用基准坐标系对写出那些坐标。
首先,您必须设置您的exstrinsics,以便您能够执行您需要的所有转换。为此,我在mExstrinsics = setupExtrinsics(mTango)
函数的末尾调用setTangoListener()
函数。这是代码(您可以在我上面链接的示例中找到)。
private DeviceExtrinsics setupExtrinsics(Tango mTango) {
//camera to IMU tranform
TangoCoordinateFramePair framePair = new TangoCoordinateFramePair();
framePair.baseFrame = TangoPoseData.COORDINATE_FRAME_IMU;
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_CAMERA_COLOR;
TangoPoseData imu_T_rgb = mTango.getPoseAtTime(0.0,framePair);
//IMU to device transform
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_DEVICE;
TangoPoseData imu_T_device = mTango.getPoseAtTime(0.0,framePair);
//IMU to depth transform
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_CAMERA_DEPTH;
TangoPoseData imu_T_depth = mTango.getPoseAtTime(0.0,framePair);
return new DeviceExtrinsics(imu_T_device,imu_T_rgb,imu_T_depth);
}
然后当你得到点Cloud时,你必须&#34;标准化&#34;它。使用你的exstrinsics非常简单:
public ArrayList<Vector3> normalize(TangoXyzIjData cloud, TangoPoseData cameraPose, DeviceExtrinsics extrinsics) {
ArrayList<Vector3> normalizedCloud = new ArrayList<>();
TangoPoseData camera_T_imu = ScenePoseCalculator.matrixToTangoPose(extrinsics.getDeviceTDepthCamera());
while (cloud.xyz.hasRemaining()) {
Vector3 rotatedV = ScenePoseCalculator.getPointInEngineFrame(
new Vector3(cloud.xyz.get(),cloud.xyz.get(),cloud.xyz.get()),
camera_T_imu,
cameraPose
);
normalizedCloud.add(rotatedV);
}
return normalizedCloud;
}
这应该足够了,现在你有一个基于参考框架的点云。 如果你过度使用了这两个或更多的&#34;标准化&#34;云,您可以获得房间的3D表示。
还有另一种方法可以使用旋转矩阵,here解释。
我的解决方案非常慢(开发工具包需要大约700毫秒来规范化大约3000点的云),因此它不适合用于3D重建的实时应用。
Atm我尝试使用NDK和JNI在C中使用Tango 3D重建库。该库已有详细记录,但设置环境并开始使用JNI非常痛苦。 (事实上,我现在被困住了。)
当我转动设备时仍然存在问题。点云似乎扩散了很多。
我猜你正在经历一些漂移
当您单独使用运动跟踪时会发生漂移:它会在估算您的姿势时出现很多非常小的错误,这些错误会导致相对于世界的姿势出现重大错误。例如,如果您使用探戈装置并且走一圈跟踪您的TangoPoseData
,然后您在电子表格或任何您想要的任何内容中绘制轨迹,您将注意到平板电脑永远不会在他的起点返回因为他正在飘走
解决方法是使用区域学习。
如果您对此主题没有明确的想法,我建议您从Google I / O 2016中观看此talk。它将涵盖很多内容,并为您提供一个很好的介绍。
使用区域学习非常简单
您只需在TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION
中更改基本参考框架即可。通过这种方式,您可以告诉Tango估计他的姿势,而不是在您启动应用程序时的位置,而是在该区域的某个固定点。
这是我的代码:
private static final ArrayList<TangoCoordinateFramePair> FRAME_PAIRS =
new ArrayList<TangoCoordinateFramePair>();
{
FRAME_PAIRS.add(new TangoCoordinateFramePair(
TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION,
TangoPoseData.COORDINATE_FRAME_DEVICE
));
}
现在您可以像往常一样使用此FRAME_PAIRS
。
然后,您必须修改TangoConfig
才能使用密钥TangoConfig.KEY_BOOLEAN_DRIFT_CORRECTION
向Tango发出区域学习。请记住,使用TangoConfig.KEY_BOOLEAN_DRIFT_CORRECTION
时,您可以使用学习模式并加载ADF(区域描述文件)。
所以你不能使用:
TangoConfig.KEY_BOOLEAN_LEARNINGMODE
TangoConfig.KEY_STRING_AREADESCRIPTION
以下是我在我的应用中初始化TangoConfig
的方法:
TangoConfig config = tango.getConfig(TangoConfig.CONFIG_TYPE_DEFAULT);
//Turning depth sensor on.
config.putBoolean(TangoConfig.KEY_BOOLEAN_DEPTH, true);
//Turning motiontracking on.
config.putBoolean(TangoConfig.KEY_BOOLEAN_MOTIONTRACKING,true);
//If tango gets stuck he tries to autorecover himself.
config.putBoolean(TangoConfig.KEY_BOOLEAN_AUTORECOVERY,true);
//Tango tries to store and remember places and rooms,
//this is used to reduce drifting.
config.putBoolean(TangoConfig.KEY_BOOLEAN_DRIFT_CORRECTION,true);
//Turns the color camera on.
config.putBoolean(TangoConfig.KEY_BOOLEAN_COLORCAMERA, true);
使用这种技术,你将摆脱这些传播。
<强> PS 强>
在上面链接的Talk i中,在22:35左右,它们向您展示了如何将应用程序移植到区域学习。在他们的示例中,他们使用 。此密钥不再存在(至少在Java API中)。请改用TangoConfig.KEY_BOOLEAN_ENABLE_DRIFT_CORRECTION
TangoConfig.KEY_BOOLEAN_DRIFT_CORRECTION
。