开源OpenREALM项目剖析

Lance,于 2023、04
开源OpenREALM项目剖析_第1张图片
总结(工程部分)
开源OpenREALM项目剖析_第2张图片

简介:OpenREALM是一个实时航空地图制作的框架,利用了视觉SLAM和3D重建的技术。它可以用于无人机的定位和导航,也可以用于生成高分辨率的影像和地形数据。它支持多种操作模式,包括平面拼接,3D重建,以及PSM(平面扫描匹配)。

本文提出的框架包含以下几个主要模块

Stage 1: Image Acquisition:这个模块负责从无人机的相机获取图像,并将它们存储在一个缓冲区中,等待后续处理。这个模块使用了一个线程安全的队列来存储图像,并且可以根据无人机的速度和方向动态调整图像的采样频率,以保证图像之间有足够的重叠度和视差。

Stage 2: Visual Odometry:这个模块负责根据图像序列估计无人机的相对位姿,并将其与全局定位系统(GPS)的数据进行融合,得到更精确的绝对位姿。这个模块使用了ORB-SLAM2作为视觉里程计的算法,并且利用GPS数据进行尺度校正和轨迹平滑。此外,这个模块还可以检测并修复视觉里程计的漂移和闭环。
Note:目前作者使用OpenVSLAM代替ORB-SLAM2,并将其设置成了default SLAM,详见官方仓库的Changelog部分

Stage 3: Map Update:这个模块负责根据当前图像和位姿更新地图,包括影像拼接和三维重建。不同的地图模式有不同的算法和输出,例如平面拼接模式(PSM),高程拼接模式(ESM)和结构拼接模式(SSM)。PSM假设地面是一个近似平面,并且使用基于特征点匹配的方法进行影像拼接,输出一个高分辨率的正射影像。ESM利用视差图和深度学习方法进行三维重建,并且输出一个高程图和一个几何校正的正射影像。SSM使用基于稠密匹配的方法进行三维重建,并且输出一个点云或网格模型和一个几何校正的正射影像。

Stage 4: Map Visualization:这个模块负责将地图数据发送给地面站,以便操作员实时查看地图的进展情况,并进行交互操作,例如放大、缩小、旋转等。这个模块使用了ROS作为通信框架,并且提供了一个基于Qt的可视化界面,可以显示无人机的实时位置、轨迹、地图等信息。
要使用本文提出的框架,需要安装ROS、QT、OpenCV、PCL、Fbow、g2o等相关库,并且下载本文提供的源代码。然后,需要配置好无人机的相机和GPS设备,并且在CMakeLists.txt文件中指定相应的参数。最后,你可以运行rosrun命令来启动框架,并且在地面站上观察地图结果。

laxnpander/OpenREALM: OpenREALM is a pipeline for real-time aerial mapping utilizing visual SLAM and 3D reconstruction frameworks. (github.com)
详见官方仓库代码

根据论文中提供的仓库¹,具体代码和上面四个模块功能的一一对应关系如下:

  • Stage 1: Image Acquisition:这个模块对应于 realm_ros 包中的 realm_exiv2_grabber 节点,它使用 exiv2_grabber 类来从文件夹中读取图像和GPS数据,并且发布到 /realm_exiv2_grabber/rgb_image 和 /realm_exiv2_grabber/camera_pose 话题上。

  • Stage 2: Visual Odometry:这个模块对应于 realm_vslam_base 包中的 realm_vslam_base_nodelet 节点,它使用 vslam_base 类来调用视觉里程计的算法,并且发布到 /realm_vslam_base_nodelet/pose 和 /realm_vslam_base_nodelet/keyframe_pose 话题上。目前支持的视觉里程计算法有ORB-SLAM2²和OpenVSLAM³。

  • Stage 3: Map Update:这个模块对应于 realm_stages 包中的多个节点,它们使用不同的类来实现不同的地图模式。例如,PSM对应于 realm_stages::StageSettings::Load(“plane_stitching”) ,ESM对应于 realm_stages::StageSettings::Load(“elevation”) ,SSM对应于 realm_stages::StageSettings::Load(“structure”) 。这些节点都会订阅视觉里程计的话题,并且发布地图数据到不同的话题上,例如 /plane_stitching/map_update , /elevation/map_update , /structure/map_update 等。

  • Stage 4: Map Visualization:这个模块对应于 realm_rviz_plugin 包中的一个RViz插件,它可以订阅地图更新的话题,并且在RViz中显示地图的结果,并且提供一些交互功能,例如保存地图,导出地图等。

这个库的实现主要分为四个模块:realm_core, realm_io, realm_vslam_base和realm_stages。每个模块的作用如下:

  • realm_core: 提供了一些基础的类和函数,如相机模型,地理坐标系,图像处理等。
  • realm_io: 提供了一些输入输出的接口,如读写图像,点云,地图等。
  • realm_vslam_base: 提供了一个视觉SLAM的抽象基类,以及对OpenVSLAM和ORB SLAM2的封装。
  • realm_stages: 提供了一些处理阶段的类,如拼接,重建,表面生成等。每个阶段都可以独立运行,也可以通过ROS或其他框架进行通信。如果你只需要简单的拼接,你可以只使用realm_ortho_rectification。

具体阶段说明

realm_pose_estimation是一个ROS节点,它实现了PoseEstimationStage类,用于从视觉SLAM获取图像和位姿,并将它们转换为地理坐标系下的位姿。它还可以根据图像的EXIF信息或GPS信息进行地理参考。它是OpenREALM框架的第一个阶段,为后续的拼接和重建提供输入数据,realm_pose_estimation是一个必须要有的阶段,因为它提供了图像和位姿的数据,如果没有这些数据,后续的拼接和重建就无法进行

realm_surface_generation是一个ROS节点,它实现了SurfaceGenerationStage类,用于从点云生成三维表面,并将其转换为网格或体素格式。它是OpenREALM框架的最后一个阶段,为后续的应用提供三维表面信息。realm_surface_generation阶段不是必须的,它只是为了生成三维表面信息,如果不需要这些信息,可以跳过这个阶段。

realm_ortho_rectification是一个ROS节点,它实现了OrthoRectificationStage类,用于将图像变换和拼接成正射影像,它是拼接阶段的实现。

realm_mosaicing是一个ROS节点,它实现了MosaicingStage类,用于将正射影像进一步处理,生成高程图和几何校正的正射影像。该阶段不是必须的,但如果你需要更高质量的拼接,你可以使用realm_mosaicing,它会在realm_ortho_rectification的基础上进行后处理,需要同时打开realm_mosaicing,同时也要打开realm_ortho_rectification,因为realm_mosaicing阶段需要realm_ortho_rectification阶段的输出作为输入。可以在配置文件中设置这两个阶段的参数,以达到你想要的效果。

官方demo示例说明

GNSS only mapping和2D mapping with visual SLAM在使用的不同的stage上有一些代码层面的区别。具体来说:

  • GNSS only mapping只使用realm_pose_estimation和realm_ortho_rectification两个阶段,它利用图像的EXIF信息或GPS信息进行地理参考,然后将图像变换和拼接成正射影像。
  • 2D mapping with visual SLAM使用realm_pose_estimation,realm_ortho_rectification和realm_mosaicing三个阶段,它利用视觉SLAM获取图像和位姿,并将它们转换为地理坐标系下的位姿,然后将图像变换和拼接成正射影像,并进行后处理,生成高程图和几何校正的正射影像。
  • 2.5D mapping with visual SLAM and surface reconstruction部分相比于上面这两者,多使用了realm_surface_generation阶段,它利用GPU进行立体视觉重建,从点云生成三维表面,并将其转换为网格或体素格式。这样可以得到更详细的三维信息,而不仅仅是二维的正射影像。

使用2D mapping with visual SLAM的方法来运行作者提供的数据并进行拼接,按照以下步骤:

  • 下载测试数据集:https://drive.google.com/open?id=1-2h0tasI4wzxZKLBbOz3XbJ7f5xlxlMe
  • 解压数据集,例如使用tar -xvzf open_realm_edm_dataset.tar.gz
  • 修改realm_ros/launch/alexa_noreco.launch文件中的输入路径,将其改为数据集的绝对路径
  • 启动realm_ros/launch/alexa_noreco.launch文件,它会使用realm_pose_estimation,realm_ortho_rectification和realm_mosaicing三个阶段进行拼接

官方github项目剖析【初步】
【1. 概览】
作者提供的这个开源代码的各个部分,以及和实际的代码文件的对应关系,如下:

  • cmake: 包含了一些cmake相关的文件,如FindOpenCV.cmake,用于在编译时找到OpenCV的路径
  • docker: 包含了一些docker相关的文件,如Dockerfile,用于构建一个基于Ubuntu 18.04的docker镜像,其中包含了OpenREALM所需的所有依赖
  • modules: 包含了OpenREALM的主要模块,分为四个子文件夹:
    • realm_core: 包含了一些基础的类和函数,如相机模型,地理坐标系,图像处理等。对应的代码文件在realm_core/include和realm_core/src中
    • realm_io: 包含了一些输入输出的接口,如读写图像,点云,地图等。对应的代码文件在realm_io/include和realm_io/src中
    • realm_vslam_base: 包含了一个视觉SLAM的抽象基类,以及对OpenVSLAM和ORB SLAM2的封装。对应的代码文件在realm_vslam_base/include和realm_vslam_base/src中
    • realm_stages: 包含了一些处理阶段的类,如拼接,重建,表面生成等。每个阶段都可以独立运行,也可以通过ROS或其他框架进行通信。对应的代码文件在realm_stages/include和realm_stages/src中
  • resources: 包含了一些资源文件,如logo图片
  • tools: 包含了一些工具脚本,如install_deps.sh,用于安装OpenREALM所需的依赖
  • travis: 包含了一些用于持续集成测试的文件,如.travis.yml
  • .gitignore: 用于指定git忽略的文件或目录
  • .gitmodules: 用于指定git子模块的路径和URL
  • CHANGELOG.md: 用于记录OpenREALM的更新日志
  • CMakeLists.txt: 用于指定OpenREALM的编译选项和依赖
  • README.md: 用于介绍OpenREALM的概述和使用方法

【2. modules文件夹内容详解】

  • realm_core: 这个模块是提供了一些基础的类和函数,如相机模型,地理坐标系,图像处理等。它的功能是为其他模块提供一些通用的数据结构和工具函数。它主要使用了C++标准库,OpenCV和GDAL等第三方库来实现。它对应的代码文件在realm_core/include和realm_core/src中,其中主要有以下几个类和函数:

    • camera: 这个类是用于表示相机模型的,它包含了相机的内参,外参,畸变参数等信息。它还提供了一些函数来进行图像坐标和世界坐标之间的转换,以及图像的去畸变和投影等操作。它对应的代码文件是camera.h和camera.cpp。
    • cv_grid_map: 这个类是用于表示网格地图的,它是一个多层的矩阵结构,每一层都有一个名称和一个类型。它可以存储不同类型的数据,如高程,正射影像,掩码等。它还提供了一些函数来进行网格地图之间的拼接,裁剪,插值等操作。它对应的代码文件是cv_grid_map.h和cv_grid_map.cpp。
    • frame: 这个类是用于表示无人机拍摄的图像帧的,它包含了图像数据,时间戳,位姿等信息。它还提供了一些函数来获取图像的元数据,如EXIF信息或GPS信息等。它对应的代码文件是frame.h和frame.cpp。
    • georeference: 这个类是用于表示地理参考信息的,它包含了地理坐标系,投影方式,转换矩阵等信息。它还提供了一些函数来进行地理坐标和世界坐标之间的转换,以及地理参考之间的比较等操作。它对应的代码文件是georeference.h和georeference.cpp。
    • settings_base: 这个类是用于表示设置信息的基类,它包含了一个字符串到字符串的映射表来存储各种设置参数。它还提供了一些函数来从文件中读取或写入设置信息,以及获取或设置参数值等操作。它对应的代码文件是settings_base.h和settings_base.cpp。
    • timer: 这个类是用于计时器功能的封装类,它使用了C++标准库中的chrono库来实现。它提供了一些函数来启动或停止计时器,以及获取计时器当前或总共经过的时间等操作。它对应的代码文件是timer.h和timer.cpp。
    • utilities: 这个命名空间下包含了一些工具函数,如字符串处理,文件操作,数学计算等。它们对应的代码文件是utilities.h和utilities.cpp。
  • realm_io: 这个模块是提供了一些输入输出的接口,如读写图像,点云,地图等。它的功能是为其他模块提供一些数据的加载和保存的方法。它主要使用了OpenCV,PCL和GDAL等第三方库来实现。它对应的代码文件在realm_io/include和realm_io/src中,其中主要有以下几个类和函数:

    • exif: 这个命名空间下包含了一些用于读取或写入图像的EXIF信息的函数,如获取或设置GPS信息,时间信息,相机信息等。它们对应的代码文件是exif.h和exif.cpp。
    • gdal: 这个命名空间下包含了一些用于读取或写入GDAL支持的地理数据格式的函数,如GeoTIFF,ESRI Shapefile等。它们对应的代码文件是gdal.h和gdal.cpp。
    • opencv: 这个命名空间下包含了一些用于读取或写入OpenCV支持的图像数据格式的函数,如JPG,PNG等。它们对应的代码文件是opencv.h和opencv.cpp。
    • pcl: 这个命名空间下包含了一些用于读取或写入PCL支持的点云数据格式的函数,如PCD,PLY等。它们对应的代码文件是pcl.h和pcl.cpp。
  • realm_vslam_base: 这个模块是提供了一个视觉SLAM的抽象基类,以及对OpenVSLAM和ORB SLAM2的封装。它的功能是为其他模块提供一些视觉SLAM的接口和功能。它主要使用了OpenVSLAM和ORB SLAM2等第三方库来实现。它对应的代码文件在realm_vslam_base/include和realm_vslam_base/src中,其中主要有以下几个类和函数:

    • visual_slam_IF: 这个类是视觉SLAM的抽象基类,它定义了一些纯虚函数来规范视觉SLAM的接口,如初始化,添加帧,获取位姿等。它还提供了一些信号槽机制来进行事件通知,如位姿更新,关键帧插入等。它对应的代码文件是visual_slam_IF.h和visual_slam_IF.cpp。
    • openvslam: 这个命名空间下包含了对OpenVSLAM库的封装类,如openvslam::system_IF,openvslam::camera_IF等。它们继承了visual_slam_IF类,并实现了相应的接口函数。它们还提供了一些特有的函数来进行OpenVSLAM相关的操作,如设置配置文件,重置地图等。它们对应的代码文件是openvslam/.h和openvslam/.cpp。
    • orbslam2: 这个命名空间下包含了对ORB SLAM2库的封装类,如orbslam2::system_IF,orbslam2::camera_IF等。它们继承了visual_slam_IF类,并实现了相应的接口函数。它们还提供了一些特有的函数来进行ORB SLAM2相关的操作,如设置词典文件,保存轨迹等。它们对应的代码文件是orbslam2/.h和orbslam2/.cpp。
  • realm_stages: 这个模块是提供了一些处理阶段的类,如拼接,重建,表面生成等。每个阶段都可以独立运行,也可以通过ROS或其他框架进行通信。realm_stages模块还有以下几个类和函数:

    • stage_base: 这个类是处理阶段的抽象基类,它定义了一些纯虚函数来规范处理阶段的接口,如添加帧,运行,停止等。它还提供了一些信号槽机制来进行事件通知,如结果更新,状态改变等。它对应的代码文件是stage_base.h和stage_base.cpp。
    • pose_estimation: 这个类是用于从视觉SLAM获取图像和位姿,并将它们转换为地理坐标系下的位姿的处理阶段。它继承了stage_base类,并实现了相应的接口函数。它还提供了一些特有的函数来进行地理参考,如根据EXIF信息或GPS信息进行地理参考,或者根据已知的地理参考进行坐标转换等。它对应的代码文件是pose_estimation.h和pose_estimation.cpp。
    • ortho_rectification: 这个类是用于将图像变换和拼接成正射影像的处理阶段。它继承了stage_base类,并实现了相应的接口函数。它还提供了一些特有的函数来进行图像变换和拼接,如根据位姿和相机模型进行图像变换,或者根据网格地图进行图像拼接等。它对应的代码文件是ortho_rectification.h和ortho_rectification.cpp。
    • mosaicing: 这个类是用于将正射影像进一步处理,生成高程图和几何校正的正射影像的处理阶段。它继承了stage_base类,并实现了相应的接口函数。它还提供了一些特有的函数来进行高程图和几何校正的生成,如根据点云进行高程估计,或者根据高程图进行几何校正等。它对应的代码文件是mosaicing.h和mosaicing.cpp。
    • surface_generation: 这个类是用于从点云生成三维表面,并将其转换为网格或体素格式的处理阶段。它继承了stage_base类,并实现了相应的接口函数。它还提供了一些特有的函数来进行表面生成和转换,如根据GPU立体视觉重建进行表面生成,或者根据PCL库进行网格或体素转换等。它对应的代码文件是surface_generation.h和surface_generation.cpp。

你可能感兴趣的:(开源,计算机视觉,人工智能)