ElasticFusion Slam 算法 运行 TUM RGB-D 基准上的位姿图

ElasticFusion Slam algorithm running with pose graph on TUM RGB-D benchmark

我从 TUM RGB-D SLAM Dataset and Benchmark 下载了 Freiburg desk 数据集并将其转换为 '.klg' 这是 slam 算法的自定义格式。我将这个 klg 文件加载到 ElasticFusion 并 运行 嵌入了 SLAM 算法。 3d 重建输出看起来足够好。

现在我想通过已经构建的轨迹信息构建 3d 重建。 我从 '.freibrug' 中检索了之前 运行 的轨迹数据,并通过 ElasticFusion 将其转换为所需格式。我只是将时间戳从秒更改为微秒,方法是将其乘以 1000000。并使用 ","" 而不是 " " space[=38= 拆分变量] 。 我 运行 这次的算法带有“-p”标志和轨迹文件的路径信息。下面是我的 运行ning 命令。

/path_to_EF/./ElasticFusion -l /path_to_data/rgbd_dataset_freiburg1_desk/test2.klg -p /path_to_data/rgbd_dataset_freiburg1_desk/modified_freiburg.txt

我期待得到相同的点云。但是我得到的结果与预期的数据相去甚远。

如你所见,它的准确性和重建水平远不如以前的运行。 我对轨迹没有问题。下图显示我从之前 运行 中检索到的轨迹接近于 TUM RGB-D Benchmark 提供的 groundtruth 数据。

即使我在 运行 中使用真实数据,它也无法构建漂亮的 3d 重建。这样的结果可能是什么原因和遗漏点?

好的建议和答案将不胜感激。

我进行了 3 次扫描:从左到右、从下到上和从后到前。我观察到思想轨迹文件似乎是正确的,建筑物出了问题。当我在 x 轴上移动相机时,在 EF 上它在 z 轴上移动,其他情况类似。我试图手动找到转换矩阵。我将此转换应用于平移和旋转。之后就开始工作了。

我成功了运行带轨迹文件的代码 (您的时间戳应该是整数,并用 space 分隔所有参数) 修改ElasticFusion/GUI/src/Tools/GroundTruthOdometry.cpp

void GroundTruthOdometry::loadTrajectory(const std::string & filename)
{
    std::ifstream file;
    std::string line;
    file.open(filename.c_str());
    while (!file.eof())
    {
        unsigned long long int utime;
        float x, y, z, qx, qy, qz, qw;
        std::getline(file, line);
        int n = sscanf(line.c_str(), "%llu %f %f %f %f %f %f %f", &utime, &x, &y, &z, &qx, &qy, &qz, &qw);

        if(file.eof())
            break;

        assert(n == 8);

        Eigen::Quaternionf q(qw, qx, qy, qz);
        Eigen::Vector3f t(x, y, z);

        Eigen::Isometry3f T;
        T.setIdentity();
        T.pretranslate(t).rotate(q);
        camera_trajectory[utime] = T;
    }
}

Eigen::Matrix4f GroundTruthOdometry::getTransformation(uint64_t timestamp)
{
    Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();

    if(last_utime != 0)
    {
        std::map<uint64_t, Eigen::Isometry3f>::const_iterator it = camera_trajectory.find(last_utime);
        if (it == camera_trajectory.end())
        {
            last_utime = timestamp;
            return pose;
        }


        pose = camera_trajectory[timestamp].matrix();
    }
    else
    {
        std::map<uint64_t, Eigen::Isometry3f>::const_iterator it = camera_trajectory.find(timestamp);
        Eigen::Isometry3f ident = it->second;
        pose = Eigen::Matrix4f::Identity();
        camera_trajectory[last_utime] = ident;
    }

    last_utime = timestamp;

    return pose;
}

基本上就是禁用M矩阵,大家可以试试