👑主页:吾名招财
👓简介:工科学硕,研究方向机器视觉,爱好较广泛...
💫签名:面朝大海,春暖花开!
ubuntu 20.04 配置FAST-LIVO2教程(内含官方数据集及自定义楼梯长廊数据集)
- 引言
- 数据集
- [ubuntu 20.04 配置FAST-LIVO2](#ubuntu 20.04 配置FAST-LIVO2)
- slam结果高斯化测试
引言
之前手里有个TOF的深度相机,想着基于RGBD数据集来进行点云GS重建,尝试过各种基于RGBD数据的gs-slam相关算法如splatam、MonoGS、Loopsplat等等,但对于带有楼梯的、长廊的、颜色单一的场景效果都不是很好,最后发现要想能实时的比较精确的重建出比较好的点云效果,不仅需要视觉、雷达/点云的数据,还需要IMU惯性测量的数据。
后面又研究了一下相关的slam算法,大体上可以分为纯视觉、视觉+IMU、激光雷达+IMU、激光雷达+视觉+IMU等等,在slam算法中IMU惯性计量单元是必不可少的,它可以计算当前角速度和加速度,辅助后面的全局定位及位姿估计,能快速精确的建图,所以要想在复杂场景下进行更好的slam点云重建需要激光雷达+视觉+IMU的slam方案,其中的代表就是FAST-LIVO2。
那么slam出来的点云如何再进行高斯训练呢,本人也从多方面进行了相关测试,大家可以参考看看。
数据集
因为目前的官方数据集已经无法通过官方链接下载了,本人将其保存在了自己的百度网盘上,有需要可以下载
https://download.csdn.net/download/qq_44870829/92972728
(1)官方数据集


(2)自定义楼梯数据集
下方是本人搜集到的自定义楼梯长廊数据集,可以很好的测试验证算法在楼梯、长廊、昏暗等极端条件下的效果
https://download.csdn.net/download/qq_44870829/92972749

ubuntu 20.04 配置FAST-LIVO2
本人之前测试过在Ubuntu 22.04上采用ROS2 HUMBLE的环境来配置FAST-LIVO2但是失败了,也试过wsl+linux20.04+ros1的方式配置,也没有成功,最后是在Ubuntu 20.04 + ROS Noetic 的环境下配置成功了。
具体配置步骤大家可以参考此教程
https://www.scan2.world/blog/1
启动
分两个终端启动,一个终端启动可视化界面,另一个用来读取数据包
使用bash的setup脚本
javascript
source ~/catkin_ws/devel/setup.bash
roslaunch fast_livo mapping_avia.launch
新建一个终端,播放数据包:
javascript
rosbag play Retail_Street.bag
注意:
mid360
要是bag数据是使用mid360采集的话,还得使用mid360的启动脚本,具体配置可以看https://github.com/hku-mars/LIV_handhold_2
javascript
source ~/catkin_ws/devel/setup.bash
roslaunch fast_livo mapping_mid360.launch
javascript
rosbag play mid360.bag
跑出来的楼梯数据如下



slam结果高斯化测试
(1)点云转colmap数据集测试
在log文件夹中就存在着colmap相关数据等

需要注意的是colmap中的sparse中的points3D.txt是空的,需要用pcd中的lidar_poses.txt作为初始化点云进行3DGS训练
注意:若是log文件夹下面没有pcd文件夹,则需要手动创建,每次修改万成配置文件,都要关闭终端重新启动终端运行(注意其对应的pcl库也要对应安装,若是无法生成pcd点云可能也与此有关)


可以在参数文件中自动隔着多少帧保存,或者在程序退出的时候保存
pcd_save:
pcd_save_en: true # 必须为 true
pcd_save_interval: -1 # 保存所有关键帧的点云,或设置为正整数(如10)表示每隔N帧保存
filter_size_pcd: 0.15 # 点云滤波参数(可选)
将生成的pcd点云转化成points3D.txt文件
重要注意事项
· 颜色信息:FAST-LIVO2生成的 .pcd通常不包含颜色。上述脚本会使用默认的白色 (255, 255, 255)填充。如果您需要真实的颜色,必须通过其他方式(例如,将点云与同步拍摄的图像进行关联着色)为点云上色,这是一个独立且复杂的步骤。
· · · 缺失信息:转换得到的 points3D.txt不包含真正的 ERROR(重投影误差)和 TRACK(观测轨迹)信息。因此,该文件不能直接用于COLMAP的增量式三维重建(SfM),因为它缺少点与图像特征之间的关联。
· · 主要用途:此转换主要用于可视化、作为3DGS训练的初始几何,或与其他仅需坐标和颜色的工具进行交互。若要进行完整的COLMAP重建,您需要原始的图像序列,并通过COLMAP的标准流程(特征提取、匹配、稀疏重建)来生成包含完整关联信息的 points3D.txt。
javascript
#!/usr/bin/env python3
import open3d as o3d
import numpy as np
def pcd_to_colmap_points3d(pcd_path, output_txt_path="points3D.txt", default_color=(255, 255, 255)):
"""
将 .pcd 文件转换为 COLMAP 格式的 points3D.txt。
注意:生成的 points3D.txt 不包含 ERROR 和 TRACK 信息,仅包含坐标和颜色。
参数:
pcd_path: 输入的 .pcd 文件路径。
output_txt_path: 输出的 points3D.txt 文件路径。
default_color: 当点云没有颜色时使用的默认 RGB 值(0-255)。
"""
# 1. 读取点云
pcd = o3d.io.read_point_cloud(pcd_path)
if not pcd.has_points():
print("错误:点云文件为空或无法读取。")
return
points = np.asarray(pcd.points) # (N, 3) 的 XYZ 坐标
# 2. 获取颜色信息
if pcd.has_colors():
# open3d 的颜色值范围是 [0, 1],需要转换为 [0, 255] 的整数
colors = (np.asarray(pcd.colors) * 255).astype(np.uint8)
else:
# 如果没有颜色,使用默认颜色(例如白色)
colors = np.tile(default_color, (points.shape[0], 1))
print(f"警告:点云不包含颜色信息,已使用默认颜色 {default_color}。")
# 3. 写入 points3D.txt
with open(output_txt_path, 'w') as f:
# 写入文件头(可选)
f.write("# 3D point list with one line of data per point:\n")
f.write("# POINT3D_ID, X, Y, Z, R, G, B, ERROR, TRACK[] as (IMAGE_ID, POINT2D_IDX)\n")
f.write(f"# Number of points: {points.shape[0]}, mean track length: 0.0\n")
# 逐点写入
for i in range(points.shape[0]):
point_id = i + 1 # ID 从 1 开始
x, y, z = points[i]
r, g, b = colors[i]
error = 0.0 # 无真实重投影误差,设为 0
track = "" # 无观测轨迹,留空
# 格式:ID X Y Z R G B ERROR [TRACK]
line = f"{point_id} {x:.6f} {y:.6f} {z:.6f} {r} {g} {b} {error} {track}\n"
f.write(line)
print(f"转换完成!共处理 {points.shape[0]} 个点。")
print(f"输出文件:{output_txt_path}")
if __name__ == "__main__":
# 请修改以下路径为您的实际文件路径
input_pcd = "~/catkin_ws/src/FAST-LIVO2/Log/2025-07-03-12-30-00/GlobalMap.pcd" # 示例路径
output_txt = "points3D.txt"
pcd_to_colmap_points3d(input_pcd, output_txt)
测试转换的colmap数据集是否存在问题(有问题,但相机位姿正确可以倒推colmap数据集)

E:\C++Project\3DGSGUI\opengs\x64\Release\external\COLMAP-3.8-windows-cuda>colmap model_converter --input_path H:/BaiduNetdiskDownload/mid360_colmap/Colmap/sparse/0 --output_path model.ply --output_type PLY
使用colmap命令能直接将其转换成ply文件,也能打开,应该是没问题的
使用colmap查看此colmap文件的完整性
E:\C++Project\3DGSGUI\opengs\x64\Release\external\COLMAP-3.8-windows-cuda>colmap model_analyzer --path H:/BaiduNetdiskDownload/mid360_colmap/Colmap/sparse/0
Cameras: 1
Images: 7036
Registered images: 7036
Points: 218204
Observations: 0
Mean track length: 0.000000
Mean observations per image: 0.000000
Mean reprojection error: 0.000000px
检查杯子信息的时候是完整的,那说明一开始从fastlivo2生成的colmap数据集本身就有问题,所以images.txt有问题,且points3D.txt是空的

生成的images.txt文件有问题,points3D.txt文件也有问题,没有关联信息




所以现在fastlivo2生成的colmap数据格式不完整,无关联信息,无法应用与opensplat中,可以使用特定的工具直接使用激光雷达点云作为高斯的初始位置训练3DGS-Calib(无开源)


采用colmap point_triangulator,倒推完整colmap数据集用于后续高斯训练(视觉特征匹配点太少,放弃)
只需要fastlivo2输出的cameras.txt、images.txt以及images文件夹图像即可重建完整colmap数据集


已有


广场路边生成的点云数量还行(前期的特征提取比较好)

广场路边生成的gs(勉强还行吧)

楼梯通过此方式倒推生成的点云太稀疏(特征提取点太少,不如点云)

楼梯生成的gs如下效果并不好

所以说还是得通过雷达的点云及对应的相机视角来倒推完整的coolmap数据集格式,对其进行关联,然后高斯训练
(2)基于PCD和位姿的关联方案

投影关联的方法是可行的,可以将点云及相机位姿相关文件进行投影关联得到可用于colmap的数据集,雷达的点云要比视觉的点好多了

使用opensplat对这种1面墙的进行高斯训练失败,尝试使用原生3DGS的代码,可以训练,也是有问题的

投影关联方案改进



Colmap-PCD(采用此程序对slam进行2D-3D关联)
https://blog.csdn.net/u013019296/article/details/134566518
Colmap-PCD:一种用于图像到点云配准的开源工具-CSDN博客
后面的操作直接略过(。。。)
发现文件夹下并没有对应的点云文件,并且RVIZ也没有界面操作直接保存点云,需要手动调用程序订阅话题保存点云
1,确定点云话题名称:
在终端中运行以下命令,查看FAST-LIVO2发布了哪些点云话题:
rostopic list | grep -E "(cloud|points|laser|pcl)"
zhaocai@zhaocai-Kuangshi16-Series-GM6PG0X:~/catkin_ws/src/FAST-LIVO2/Retail_Street$ rostopic list | grep -E "(cloud|points|laser|pcl)"
/cloud_effected
/cloud_registered
/cloud_visual_sub_map_before
2,创建并运行保存脚本:
将以下代码保存为 save_pointcloud.py,并将 TOPIC_NAME替换为您上一步找到的话题(例如 /cloud_registered)。

javascript
#!/usr/bin/env python3
import rospy
import sensor_msgs.point_cloud2 as pc2
import numpy as np
import open3d as o3d
def callback(pointcloud_msg):
# 将 ROS PointCloud2 消息转换为 numpy 数组
pc_data = pc2.read_points(pointcloud_msg, field_names=("x", "y", "z"), skip_nans=True)
pc_array = np.array(list(pc_data), dtype=np.float32)
if pc_array.shape[0] == 0:
print("警告:接收到空的点云。")
return
# 创建 open3d 点云对象
cloud = o3d.geometry.PointCloud()
cloud.points = o3d.utility.Vector3dVector(pc_array)
# 尝试读取颜色信息(如果存在)
# 注意:FAST-LIVO2 的点云可能不包含颜色,这里先尝试读取
try:
color_data = pc2.read_points(pointcloud_msg, field_names=("r", "g", "b"), skip_nans=True)
color_array = np.array(list(color_data), dtype=np.float32) / 255.0 # 归一化到 [0,1]
if color_array.shape[0] == pc_array.shape[0]:
cloud.colors = o3d.utility.Vector3dVector(color_array)
except:
# 如果没有颜色信息,可以赋予默认颜色(如白色)或跳过
# cloud.paint_uniform_color([1, 1, 1]) # 如果需要,取消注释此行
pass
# 保存点云
o3d.io.write_point_cloud("saved_map.pcd", cloud)
print(f"点云已保存为 saved_map.pcd,包含 {pc_array.shape[0]} 个点。")
# 保存一次后退出(可选)
# rospy.signal_shutdown("保存完成")
if __name__ == '__main__':
rospy.init_node('pcd_saver')
# !!!请将以下话题名修改为 FAST-LIVO2 实际发布点云的话题 !!!
TOPIC_NAME = "/cloud_registered" # 常见话题:/cloud_registered, /laser_cloud_surf, /full_cloud_projected
rospy.Subscriber(TOPIC_NAME, pc2.PointCloud2, callback)
print(f"正在监听话题: {TOPIC_NAME},等待点云数据...")
rospy.spin()
3,运行脚本:
在一个新的终端中,确保ROS环境已配置,然后运行:
python save_pointcloud.py
当FAST-LIVO2发布点云数据时,脚本会自动保存一次并退出。您可以将 rospy.signal_shutdown行注释掉,以持续保存。