【SLAM】稠密建图的讨论与八叉树三维地图的构建

1.前言

我们已经讲过了单目相机构建稠密地图,当然,对于视觉,这是一个简单有效的办法,对于SLAM系统来讲,它还有很多不足。

> 稀疏地图反而更容易做导航,稠密地图作用一般是三维重建考虑的问题。

主要缺陷有如下几点:

  1. 像素梯度
  2. 深度参数
  3. 图像投影
  4. 多线程

我们接下来先讨论一下这些缺陷以及他的解决办法。

2.梯度与深度

1.像素梯度

对于极线约束,最简单就是使用单个像素的对比,找到最相似的一个作为匹配,但是这有很多误差,所以,诞生了使用块匹配作为匹配方式,虽然这个已经很大程度降低了他的误匹配率,但是任然不是一个很好的方法和解决方案。

比如,梯度问题,对于纹理明显的区域,他的像素梯度可以非常明显,但是,对于不明显的区域呢,比如白墙,天空等等。

这个问题依然需要更好的解决办法。

2.深度参数

在估计他的深度参数时,我们假设它是服从高斯分布的,但是,在实际系统中,它不一定服从高斯分布。

但是,深度有如下特点:

  1. 非负性;
  2. 广域性。

所以,很多研究者根据这两个特点,开发出逆深度这个概念,就是在深度估计时,使用逆深度假设服从高斯分布。

但这只是对于传统SLAM中,这是一个技巧,但是对于深度学习对于其的估计,通常得出的不再是逆深度了。

3.图像变化和多线程

1.图像变化

对于之前的块匹配,我们有一个前提,是只发生变化而没旋转变化,对于发生了旋转变化呢,就需要考虑图像间的变化而不是直接使用极线约束。

这里考虑的图像变化就是旋转矩阵和平移矩阵。

2.多线程

我们知道,上述的各种计算都是大批量的计算,但一个计算线程难以估计如此大规模的计算,对于实时性,这是个挑战。

但是多线程的计算可以大大缓解这个问题。

4.八叉树地图

>  把三维空间建模为许多个小方块(或体素)是一种常见的做法。如果把一个小方块的每个面都平均切成2片,那么这个小块就会变成同样大小的八个小方块。这个步骤可以不断的重复,直到最后的方块大小达到建模的最高精度。在这个过程中,把“将一个小方块分成同样大小的八个”看成”从一个结点展开成八个子节点”,那么整体从最大空间细分到最小空间的过程,就是一颗八叉树。整个大方块可以看成是根节点,而最小的块可以看作是“叶子节点”。于是在八叉树中,当我们由下一层结点往上走一层时,地图的体积就能扩大为原来的八倍。如果叶子结点的方块大小为1平方厘米,那么当我们限制八叉树为10层时,总共能建模的体积大约为8的10次幂立方厘米,也就是1073平方米。这足够建模一间屋子。由于体积与深度呈指数关系,所以当用更大的深度时,建模的体积会增长的非常快。

大家都应该了解二叉树的概念,一个节点,2个分支,而八叉树,顾名思义,就是一个节点,8个分支。

八叉树最大的优点就是它非常节约空间。

5.实践

//八叉树实例

int main( int argc, char** argv )
{
    if (argc != 3)
    {
        cout<<"Usage: pcd2colorOctomap <input_file> <output_file>"<<endl;
        return -1;
    }

    string input_file = argv[1], output_file = argv[2];
    pcl::PointCloud<pcl::PointXYZRGBA> cloud;
    pcl::io::loadPCDFile<pcl::PointXYZRGBA> ( input_file, cloud );

    cout<<"point cloud loaded, piont size = "<<cloud.points.size()<<endl;

    //声明octomap变量
    cout<<"copy data into octomap..."<<endl;
    // 创建带颜色的八叉树对象,参数为分辨率,这里设成了0.05
    octomap::ColorOcTree tree( 0.05 );

    for (auto p:cloud.points)
    {
        // 将点云里的点插入到octomap中
        tree.updateNode( octomap::point3d(p.x, p.y, p.z), true );
    }

    // 设置颜色
    for (auto p:cloud.points)
    {
        tree.integrateNodeColor( p.x, p.y, p.z, p.r, p.g, p.b );
    }

    // 更新octomap
    tree.updateInnerOccupancy();
    // 存储octomap, 注意要存成.ot文件而非.bt文件
    tree.write( output_file );
    cout<<"done."<<endl;

    return 0;
}

6.小结

这里,我们就讲完了,入门SLAM的最后一个知识点,相信大家对于SLAM系统有了全新的认识,从传感器数据、前端估计、后端优化、回环检测、地图重建。希望这一个系列可以帮助大家深入的理解相关的概念,但是研究人在不断探索,欢迎大家深入SLAM 方向,推动机器人感知领域的科技发展。

<think>嗯,用户想了解如何使用ORB-SLAM进行稠密,还提到了教程或实现。首先,我需要回忆一下ORB-SLAM的基本原理和它的方式。ORB-SLAM主要是基于特征点的SLAM系统,所以默认情况下生成的是稀疏地图,也就是特征点的位置。而用户需要的是稠密,这就涉及到如何从稀疏到稠密的转换。 首先,我应该考虑ORB-SLAM本身是否支持稠密。根据之前的知识,ORB-SLAM的官方版本(比如ORB-SLAM2)主要是稀疏的,所以可能需要额外的模块或者其他方法的结合。比如,可能有研究者在ORB-SLAM的基础上集成稠密算法,比如使用TSDF(截断符号距离函数)或者Surfel-based的方法。 接下来,用户需要教程或者实现,可能需要寻找相关的开源项目或者论文。例如,Multi-Level Mapping这篇论文提到了实时单目稠密SLAM,或许可以作为参考。另外,博客或GitHub上的资源可能会有实现。比如,用户提供的引用中有博主的GitHub和CSDN链接,可能需要查看是否有相关的代码或教程。 然后,我应该考虑实现的步骤。通常,稠密需要深度信息,而ORB-SLAM单目版本没有直接的深度,可能需要通过多视角几何或者其他深度估计方法。比如,使用深度相机(RGB-D)或者通过立体匹配来获取深度,或者结合深度学习模型预测深度。不过ORB-SLAM也有RGB-D的版本,可能更适合稠密。 另外,可能需要后处理步骤,比如使用泊松重或者其他表面重算法将稀疏点云转为稠密网格。或者,使用稠密SLAM系统如ElasticFusion,但用户特别提到ORB-SLAM,所以可能需要扩展ORB-SLAM的输出。 可能的实现方法包括:在ORB-SLAM的跟踪和线程之外,添加一个稠密线程,利用关键帧的姿态和像数据生成稠密点云。例如,使用每个关键帧的深度(如果是RGB-D)融合到全局模型中,或者对于单目,使用多视立体视觉(MVS)来生成稠密点云。 需要提醒用户,ORB-SLAM本身可能不支持实时稠密,尤其是单目情况下,计算量较大。可能需要参考一些开源项目,比如GitHub上的ORB-SLAM2 with dense mapping的fork,或者结合COLMAP进行离线稠密。 另外,用户提到的DeepVO是视觉里程计的端到端方法,可能和稠密不太直接相关,但可以作为补充信息。 总结回答的结构应该是:先指出ORB-SLAM默认是稀疏的,然后说明实现稠密的方法,比如结合深度相机、后处理、或其他算法集成,接着提供可能的实现步骤和参考资料,比如Multi-Level Mapping论文和相关GitHub项目,最后给出相关的问题。</think>### 如何使用ORB-SLAM进行稠密 ORB-SLAM系列(如ORB-SLAM2)是经典的基于特征点的SLAM系统,其默认输出为稀疏地图(特征点云)。若需实现稠密,需结合额外算法或扩展模块。以下是关键实现思路资源: --- #### 1. **ORB-SLAM的稀疏性稠密扩展** - **稀疏地图限制**:ORB-SLAM通过ORB特征点跟踪和BA优化生成稀疏点云,无法直接用于导航或三维[^1]。 - **稠密核心思路**: - **深度传感器融合**:使用RGB-D相机的深度数据,直接生成稠密点云(ORB-SLAM2支持RGB-D模式)。 - **单目深度估计**:通过深度学习模型(如Monodepth2)从单目像预测深度,再ORB-SLAM位姿结合[^2]。 - **多视立体几何(MVS)**:利用关键帧像和相机位姿,通过MVS算法(如COLMAP)离线生成稠密点云。 --- #### 2. **实现步骤示例(RGB-D模式)** 1. **运行ORB-SLAM2 RGB-D版本**: ```bash ./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml /path/to/dataset/ /path/to/associations.txt ``` 2. **提取关键帧位姿**:系统输出的关键帧位姿(`KeyFrameTrajectory.txt`)用于对齐深度。 3. **稠密点云融合**:使用TSDF(截断符号距离函数)或Surfel-based方法(如Open3D库)融合多帧深度: ```python import open3d as o3d volume = o3d.integration.ScalableTSDFVolume(voxel_length=0.01, sdf_trunc=0.05) for pose, rgb, depth in keyframes: volume.integrate(rgb, depth, intrinsic, pose) mesh = volume.extract_triangle_mesh() ``` --- #### 3. **开源资源教程** - **ORB-SLAM2扩展项目**: - [ORB-SLAM2 with Dense Mapping](https://github.com/tiagojc/orbslam2-dense-map):通过点云插值生成稠密地图的改进版本。 - [ORB-SLAM3](https://github.com/UZ-SLAMLab/ORB_SLAM3):支持多传感器,可结合IMU提升稠密稳定性。 - **论文参考**: - *Multi-Level Mapping: Real-time Dense Monocular SLAM* 提出分层稠密方法,可ORB-SLAM特征点结合。 - *ElasticFusion* 的稠密融合策略可借鉴(需调整实时性)[^2]。 --- #### 4. **挑战优化** - **实时性**:稠密计算量大,需GPU加速或简化模型(如八叉树地图)。 - **尺度一致性**:单目模式下需通过回环检测或物体先验尺寸约束尺度漂移。 - **动态环境处理**:结合语义分割(如Mask R-CNN)剔除动态物体干扰。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值