当前位置: 首页 > news >正文

Lafida多目数据集实测

Lafida 数据集

paper:J. Imaging | Free Full-Text | LaFiDa—A Laserscanner Multi-Fisheye Camera Dataset
官网数据:https://www.ipf.kit.edu/english/projekt_cv_szenen.php
官网:KIT-IPF-Software and Datasets - LaFiDa
标定数据下载:http://www2.ipf.kit.edu/~pcv2016/downloads/calibration.zip

0 简介

该数据集由一个头戴式多鱼眼相机系统一个移动激光扫描仪组合而成,还从采样率为 360
Hz 的动作捕捉系统中获得了精确的六自由度(6 DoF)真值姿态。


rigid_body系即动作捕捉系统坐标系,三个白色的是被动球形反向反射标记的校准棒,用于动作捕捉系统

在室内和室外环境中记录了多个序列,包括不同的运动特征、照明条件和场景动态。

所提供的序列由三台硬件触发完全同步的鱼眼相机和同一平台上的移动激光扫描仪拍摄的图像组成。总共提供了六条轨迹。每个轨迹还包括所有传感器的内在和外在校准参数及相关测量值。

此外,我们还将最常用的外置激光扫描仪工具箱推广到相机校准,以便与任意中央相机(如全向或鱼眼投影)配合使用。

基准数据集以知识共享署名协议(CC-BY 4.0)在线发布,其中包含原始传感器数据以及时间戳、校准和评估脚本等规格。

所提供的数据集可用于多鱼眼相机和/或激光扫描仪同步定位与绘图(SLAM)。

对比其他数据集,我们有多个视角的硬同步触发的相机数据:

1 采集设备

设备参数:雷达/相机/动作捕捉

1.1 激光扫描仪

Hokuyo(日本大阪)公司的 UTM-30LX-EW 激光扫描仪,激光脉冲波长为 λ = 905nm,角度分辨率为 0. 25 ◦,视场(FoV)为 270 ◦。距离精度在0.1 米至 10 米之间为 ±30 毫米。指定的脉冲重复频率为 43 kHz,即每秒捕捉 40 条扫描线(40 Hz)。Laserscaner提供的激光扫描仪数据包括每个3D点的扫描角度、距离和强度。为了保持测量数量的恒定,只使用第一次激光返回和第一次强度。因此,每次激光扫描仪旋转的最终测量数量是1080个。

1.2 多相机系统

多鱼眼相机系统(MCS)由多传感器和集成的FPGA组成,硬件触发的图像采集和图像预处理由该平台处理,因此所有图像都是像素同步采集的。

三个分辨率为 754×480 像素的 CMOS相机传感器连接到以 25 Hz 采样率运行的平台上。

Lensagon 鱼眼镜头(BF2M12520),焦距为 1.25 毫米,视场角约为185 ◦。

1.3 动作捕捉系统rigid_body

为了获取多传感器头盔系统运动的精确 6 DoF 地面实况,我们使用了一套运动捕捉系统
(OptiTrack Prime 17W),该系统配有八个硬件触发的高速摄像头。

该系统需要事先进行校准,方法是在摄像机观察到的范围内挥动带有三个被动球形反向反射标记的校准棒。由于校准棒的精确度量尺寸是已知的,所有运动捕捉摄像机的姿势都可以通过度量恢复。运动捕捉系统校准后,可通过三角测量法以 360 Hz 和亚毫米精度跟踪标记的 3 DoF 位置。要确定头盔系统的 6 DoF 运动,至少需要三个标记来创建一个独特的坐标框架。

多个标记的组合称为rigid body,我们系统的刚体定义如图 1d 所示。

2 标定


标定数据下载:http://www2.ipf.kit.edu/~pcv2016/downloads/calibration.zip 

Calibration/
├── Extrinsic_Laserscanner_to_MCS_Calibration 激光扫描仪到MCS中心外参
│   ├── cam2_to_scanner.mat
│   └── cam2_to_scanner.txt
├── Extrinsic_MCS_Calibration 各个相机到MCS中心外参
│   ├── MCS_calibration_cayley.txt
│   ├── MCS_calibration.mat
│   └── MCS_calibration.txt
├── Extrinsic_Rigid_Body_to_MCS_Calibration MCS到RigidBody中心外参
│   ├── MCS_to_RigidBody.mat
│   └── MCS_to_RigidBody.txt
└── Intrinsic_Camera_Calibrations 各个相机的内参
    ├── calib_results_back.txt
    ├── calib_results_left_cam2.txt
    ├── calib_results_right.txt
    ├── Omni_Calib_Results_back.mat
    ├── Omni_Calib_Results_left.mat
    └── Omni_Calib_Results_right.mat

2.1 内参标定(Intrinsic_Camera_Calibrations)

使用Ocam-Toolbox计算每个摄像头的内参,再配合一些改进。具体过程和改进的代码:GitHub - urbste/ImprovedOcamCalib: This is an add-on to the OCamCalib toolbox by Scaramuzza et al.​​​​​​P

2.2 相机外参(Extrinsic_MCS_Calibration)

三个相机到MCS中心(其位置由 OptiTrack 系统给出)的变换矩阵,MCS坐标系和cam2(left camera)方向一致,位置不一致。

2.3 激光外参(Extrinsic_Laserscanner_to_MCS_Calibration)

给出的是cam2到激光的矩阵变换。

2.4 rigid body外参(Extrinsic_Rigid_Body_to_MCS_Calibration)

给出的是MCS到rigid的外参,rigid坐标系的原点设置在第一球形刚体标记上。

3 数据

3.1 场景


outdoor 和 indoor

http://www2.ipf.kit.edu/~pcv2016/downloads/indoor_dynamic.zip 采集设备在房间里绕圈移动,人们在周围漫步。
http://www2.ipf.kit.edu/~pcv2016/downloads/indoor_static.zip 在房间里没有人四处走动静态场景,采集设备在房间内绕圈移动,然后上下移动。
http://www2.ipf.kit.edu/~pcv2016/downloads/outdoor_rotation.zip 中庭被外墙包围,天气多云,静态场景,采集设备绕其垂直轴旋转。http://www2.ipf.kit.edu/~pcv2016/downloads/outdoor_static.zip 中庭被外墙包围,天气多云,静态场景,录制两段数据,操作者从后到前、从左到右。http://www2.ipf.kit.edu/~pcv2016/downloads/outdoor_static2.zip 中庭被外墙包围,天气多云,静态场景,随机游走。
http://www2.ipf.kit.edu/~pcv2016/downloads/outdoor_large_loop.zip 中庭被外墙包围,天气多云,采集设备正在移出跟踪系统的范围,并以闭环方式围绕整个中庭移动,包含一个闭环。移动出跟踪系统的范围没有真值。

3.2 文件

内部时间戳:通用时间戳,可与其他传感器同步。
传感器时间戳:传感器的时间戳,不可用于同步。

  • LS_Dist.txt

包含激光扫描仪和被照射表面之间的距离。
文件头部:内部时间戳* | 传感器时间戳** | 距离
距离以毫米为单位。

  • LS_Dir.txt

包含点的方向。
文件头部:内部时间戳* | 传感器时间戳** | 方向角度
角度以度为单位。

  • LS_Intensity.txt

包含每个点的强度。
文件头部:内部时间戳* | 传感器时间戳** | 强度

  • Lspoint.txt  (数据包中并未找到)

包含激光扫描仪坐标系中的点坐标。
文件头部:时间戳* | Lspoint
坐标以米为单位。

  • Quaternion.txt (数据包中并未找到)

包含传感器位置的四元数表示。
文件头部:内部时间戳* | (传感器位置)| (四元数:X Y Z W)
坐标以米为单位。

  • Tracker.txt (数据包中并未找到)

包含刚体标记2的位置。
文件头部:内部时间戳* | NatNet时间戳 | (传感器位置)| (传感器坐标系X轴)| (传感器坐标系Y轴)| (传感器坐标系Z轴)
坐标以米为单位。

  • 图片

三个鱼眼相机数据:/work/data/MultiCol/outdoor_static2
    ├── imgs
    │   ├── cam0
    │   ├── cam1
    │   └── cam2

  •  rigid_body.txt

动作捕捉系统给出的结果,可做真值。
文件头部:内部时间戳(单位ms) | (传感器坐标系X轴)| (传感器坐标系Y轴)| (传感器坐标系Z轴)|(四元数:X Y Z W)
坐标以米为单位。
PS:轨迹中有些动态捕捉很差,建议剔除,比如:indoor_dynamic :2228163,2234005~2234059
 

实际测试

1 MultiCol 运行

cd src/MultiCol-SLAM && ./Examples/Lafida/multi_col_slam_lafida ./Examples/small_orb_omni_voc_9_6.yml ./Examples/Lafida/Slam_Settings_indoor2.yaml ./Examples/Lafida/calibration /work/data/MultiCol/outdoor_static2

第一个是字典文件的路径。

第二个是slam设置文件的路径。代码提供的四个配置文件差不过,需要修改traj.StartFrame和traj.EndFrame,其他的暂时不用动。

第三个是校准文件的目录,自动读取InteriorOrientationFisheyeXXX.yaml(内参)和MultiCamSys_Calibration.yaml(到MCS系统的外参),ps:和calibration压缩包提供的数据不太一样,我是用代码提供的内外参测试的。

第四个是图像的目录,解压对应的数据压缩包即可。

最后轨迹保留在MultiCol-SLAM/MKFTrajectory.txt(只保留了关键帧位姿)中。

2 保存每一帧率轨迹

自己修改代码,需要将mpTracker->GetAllPoses()中的数据保存到MultiCol-SLAM/MFTrajectory.txt(也包含非关键帧率),同时保存时间戳。

3 坐标系转换

此处有坑,根据MCS_to_RigidBody.txt的外参数据,将MFTrajectory.txt数据通过外参转到rigid_body系,感觉不对。转换过程:

# 将MultiCol计算的轨迹,从MCS坐标系变换到rigid_body系
import numpy as np
import sys
# lafeda 数据采集的外参变换矩阵
transform_matrix = np.array([[0.700873705975431, -0.205304197154888, -0.683100457402023, 0.215786987214032],[0.112338918021076, -0.913957993213603, 0.38994968154727, -0.198947778789318],[-0.704383429511314, -0.350044244734219, -0.61750547443592, -0.00782434870701732],[0, 0, 0, 1]
])
# transform_matrix = np.linalg.inv(transform_matrix)if len(sys.argv) > 1:name = sys.argv[1]
else:name = "indoor_dynamic"# name = "indoor_static"# name = "outdoor_static"# name = "outdoor_static2"# name = "outdoor_rotation"# name = "outdoor_large_loop"
with open('MFTrajectory.txt', 'r') as file_a, open("Examples/Lafida/run/result/"+name+'2rigid.txt', 'w') as file_b:
# with open('MKFTrajectory.txt', 'r') as file_a, open("Examples/Lafida/run/result/"+name+'2rigid.txt', 'w') as file_b:for line in file_a:# 解析每行数据data = line.strip().split()time, position = data[0], np.array(data[1:4], dtype=float)quaternion = data[4:]# 变换位置坐标position_transformed = np.dot(transform_matrix, np.append(position, 1))[:3]# 写入新文件file_b.write(f"{time} {' '.join(map(str, position_transformed))} {' '.join(quaternion)}\n")

4 evo评价

可视化对比

evo_traj tum Examples/Lafida/run/rigid_body/indoor_dynamic.txt Examples/Lafida/run/result/indoor_dynamic2rigid.txt --plot

相对误差

evo_rpe tum Examples/Lafida/run/rigid_body/indoor_dynamic.txt Examples/L
afida/run/result/indoor_dynamic2rigid.txt 

绝对误差

evo_ape tum Examples/Lafida/run/rigid_body/indoor_dynamic.txt Examples/Lafida/run/result/indoor_dynamic2rigid.txt 

官方提供的外参数据有问题,无法获得论文中结论的误差,貌似很多人遇到了

The result of ATE · Issue #20 · urbste/MultiCol-SLAM · GitHub

RPE结果

  • indoor_dynamic
           max      0.530323
          mean      0.084492
        median      0.055422
           min      0.002419
          rmse      0.117373
           sse      3.361427
           std      0.081470

  • indoor_static
          max      0.500416
          mean      0.087160
        median      0.056563
           min      0.001138
          rmse      0.124921
           sse      4.119806
           std      0.089490

  • outdoor_static
           max      0.789802
          mean      0.095496
        median      0.062085
           min      0.002779
          rmse      0.137745
           sse      4.667522
           std      0.099269

  • outdoor_static2
           max      1.395575
          mean      0.088068
        median      0.055940
           min      0.008827
          rmse      0.137840
           sse      9.081932
           std      0.106037

  • outdoor_rotation
           max      0.256908
          mean      0.051913
        median      0.037711
           min      0.002241
          rmse      0.069227
           sse      1.246014
           std      0.045798

  • outdoor_large_loop 跟踪失败

相关文章:

  • Vue3从入门到实战:路由的query和params参数
  • 应用开发:python解析斗鱼弹幕
  • 蓝桥杯杯赛之深度优先搜索优化《1.分成互质组》 《 2.小猫爬山》【dfs】【深度搜索剪枝优化】【搜索顺序】
  • ZKP价值链路的垂直整合
  • Meta Pixel:助你实现高效地Facebook广告追踪
  • 【Figma】安装指南及基础操作
  • Unity Toggle组件
  • Tcl学习笔记(二)——表达式、字符串
  • vue快速入门(七)内联语句
  • VMware虚拟机(Rocky9.3)硬盘扩容详细图文教程
  • #{} 和 ${}区别
  • 算法刷题Day27 | 39. 组合总和、40.组合总和II、131.分割回文串
  • FastGpt流程
  • Redis 持久化个人总结
  • 【算法】两数之和(暴力求解+哈希表)
  • [case10]使用RSQL实现端到端的动态查询
  • CentOS从零开始部署Nodejs项目
  • github从入门到放弃(1)
  • jquery ajax学习笔记
  • Linux后台研发超实用命令总结
  • Median of Two Sorted Arrays
  • vue-router 实现分析
  • web标准化(下)
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 关于Flux,Vuex,Redux的思考
  • 警报:线上事故之CountDownLatch的威力
  • 开源地图数据可视化库——mapnik
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 如何胜任知名企业的商业数据分析师?
  • 数组大概知多少
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 温故知新之javascript面向对象
  • 学习Vue.js的五个小例子
  • 优化 Vue 项目编译文件大小
  • HanLP分词命名实体提取详解
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #git 撤消对文件的更改
  • #NOIP 2014#Day.2 T3 解方程
  • $.ajax()方法详解
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (6)设计一个TimeMap
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (五)Python 垃圾回收机制
  • ***监测系统的构建(chkrootkit )
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET中统一的存储过程调用方法(收藏)
  • @RequestMapping处理请求异常
  • [ C++ ] STL_list 使用及其模拟实现
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429