资讯动态

ORB-SLAM2图片序列输入格式与环境兼容性实战指南

发布时间:2026/10/17 9:45:24 来源:尧图企业网站定制
简介本资源是一份面向SLAM初学者与计算机视觉实践者的ORB SLAM2实战入门包聚焦于如何将开源视觉SLAM系统适配到自采图片序列数据集解决从视频采集、帧提取、时间戳标注到系统运行的全流程落地难题。压缩包共4个文件2个Python脚本、1个MP4原始视频、1个rgb.txt配置文件总大小4.38MB其中file.py与rgb_sep.py分别用于视频帧提取和rgb.txt自动生成mp4为原始采集素材txt文件已按ORB SLAM2规范组织路径与伪时间戳开箱即用。已有5378人学习下载适合希望跳过环境配置陷阱、快速验证SLAM流程的本科生、研究生及机器人方向开发者。读者可直接复现完整pipeline从单个视频出发一键生成可被ORB SLAM2加载的结构化数据集并获得轨迹估计与稀疏建图结果附带关键参数调优提示与常见路径/时间戳错误排查逻辑。1. 用ORB-SLAM2跑自己的图片序列别急着编译先搞清这三类数据格式的玄学区别你手头有一堆按序命名的.jpg图片想喂给 ORB-SLAM2 跑出轨迹和稀疏地图——结果./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml ./dataset/sequence/一执行就报错ERROR: LoadImages: Cannot open file at ./dataset/sequence/连第一帧都读不进去。这不是代码写错了而是你根本没意识到ORB-SLAM2 对“自己的数据”不是“拿来就跑”它只认三种严格结构化的输入格式TUM RGB-D 格式带rgb.txtdepth.txt时间戳对、KITTI 格式固定00/01/02/...子目录times.txt、或自定义的txt列表文件每行timestamp path_to_image。它不支持直接拖一个文件夹进去也不吃image_00001.jpg,image_00002.jpg这种裸名序列——哪怕你手动重命名成1.jpg 2.jpg都不行。这个坑我踩过三次第一次以为是 OpenCV 版本问题重装了 C 环境第二次怀疑是相机内参 yaml 写错反复调参第三次才翻到LoadImages函数源码里那行f fopen(filename.c_str(), r)——它根本没在读图片是在读你给的列表文件。本文专治这类“数据准备型翻车”从 Ubuntu 20.04 ROS Noetic 环境下完整部署 ORB-SLAM2 v1.0官方 GitHub 最后稳定版到把任意本地图片序列转成 SLAM 可识别的 TUM 格式再到验证轨迹是否真被成功重建。适合刚接触视觉 SLAM、正卡在“数据进不去”环节的开发者也适合需要快速验证某组新采集图像是否满足 SLAM 前置条件的算法同学。2. 环境搭建与 ORB-SLAM2 编译Ubuntu 20.04 GCC 9.4 OpenCV 3.4.18 兼容性血泪清单ORB-SLAM2 是个“老派硬核派”——它不兼容 OpenCV 4.x 的 API 断层比如cv::Mat::create()行为变更也不吃 GCC 11 的 strict aliasing 优化会导致Tracking::GrabImageMonocular中关键特征点指针错乱。我试过在 Ubuntu 22.04 上强行用 OpenCV 4.5.5 编译能通过make但运行时System::TrackMonocular直接 segfault换回 Ubuntu 20.04 后GCC 和 OpenCV 版本选择就成了生死线。下面步骤全程在纯净 Ubuntu 20.04 LTS非 WSL非 Docker实测通过所有依赖版本精确到小数点后两位。2.1 安装系统级依赖绕开 apt 默认的 OpenCV 大坑Ubuntu 20.04 的apt install libopencv-dev默认装的是 OpenCV 4.2.0必须卸载并手动编译安装 OpenCV 3.4.18。先清理干净sudo apt update sudo apt upgrade -y sudo apt remove --purge libopencv-dev python3-opencv -y sudo apt autoremove -y sudo apt install -y build-essential cmake git pkg-config libgtk-3-dev \ libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \ libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \ gfortran openexr libatlas-base-dev python3-dev python3-numpy \ libtbb2 libtbb-dev libdc1394-22-dev libopenblas-dev liblapack-dev \ libeigen3-dev提示libtbb2和libtbb-dev是 ORB-SLAM2 多线程追踪的关键依赖漏掉会导致Tracking::CreateInitialMapMonocular卡死在mpLocalMapper-InsertKeyFrame(pKFini)。2.2 编译 OpenCV 3.4.18指定-D CMAKE_CXX_STANDARD11是救命参数ORB-SLAM2 的Thirdparty/g2o子模块使用 C11 的std::shared_ptr而 OpenCV 3.4.18 默认用 C98 编译会冲突。必须显式指定标准cd ~ wget -O opencv-3.4.18.zip https://github.com/opencv/opencv/archive/3.4.18.zip unzip opencv-3.4.18.zip cd opencv-3.4.18 mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D INSTALL_PYTHON3_EXECUTABLE/usr/bin/python3 \ -D INSTALL_C_EXAMPLESOFF \ -D INSTALL_PYTHON_EXAMPLESOFF \ -D OPENCV_DNNOFF \ -D WITH_CUDAOFF \ -D WITH_V4LON \ -D WITH_QTOFF \ -D WITH_OPENGLON \ -D CMAKE_CXX_STANDARD11 \ -D BUILD_opencv_python2OFF \ -D BUILD_opencv_python3ON \ -D PYTHON3_EXECUTABLE/usr/bin/python3 \ -D PYTHON3_INCLUDE_DIR/usr/include/python3.8 \ -D PYTHON3_PACKAGES_PATH/usr/lib/python3/dist-packages .. make -j$(nproc) sudo make install sudo ldconfig验证是否生效pkg-config --modversion opencv # 应输出 3.4.18 python3 -c import cv2; print(cv2.__version__) # 应输出 3.4.182.3 获取并编译 ORB-SLAM2用官方 v1.0 分支禁用 Pangolin 的 OpenGL 3.3 强制要求GitHub 上 ORB-SLAM2 主仓库已归档最新稳定版是https://github.com/raulmur/ORB_SLAM2/tree/v1.0。注意不要用master分支含未测试的 ROS2 改动也不要克隆ORB_SLAM3API 不兼容。Pangolin 在 Ubuntu 20.04 的 Mesa 驱动下默认要求 OpenGL 3.3但很多笔记本集显只支持 3.1需降级编译cd ~ git clone https://github.com/raulmur/ORB_SLAM2.git --branch v1.0 --depth 1 cd ORB_SLAM2 chmod x build.sh # 修改 build.sh将 pangolin 编译命令中的 -DOpenGL_GL_PREFERENCEGLVND 改为 -DOpenGL_GL_PREFERENCELEGACY sed -i s/-DOpenGL_GL_PREFERENCEGLVND/-DOpenGL_GL_PREFERENCELEGACY/g build.sh ./build.sh若build.sh执行失败手动编译更可控cd Thirdparty/g2o mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease make -j$(nproc) cd ../../Pangolin mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease -DOpenGL_GL_PREFERENCELEGACY make -j$(nproc) cd ../../ chmod x build.sh ./build.sh编译成功后lib/libORB_SLAM2.so和Examples/Monocular/mono_tum可执行文件应存在。此时环境已就绪但别急着跑——你的图片序列还没“翻译”成 SLAM 能懂的语言。3. 将自有图片序列转为 TUM 格式时间戳生成、路径映射与 yaml 参数校准ORB-SLAM2 的mono_tum示例程序只接受 TUM 格式输入一个rgb.txt文件每行timestamp filepath一个depth.txt单目模式可为空以及一个associate.py脚本生成的时间戳对齐文件。但你的数据很可能只是img_000001.jpg,img_000002.jpg这样的裸序列。这里的关键不是“怎么命名”而是“怎么赋予物理时间意义”——SLAM 依赖帧间时间间隔估算运动速度时间戳不准会导致尺度漂移。3.1 生成 TUM 格式 rgb.txt用 Python 脚本按固定帧率打时间戳假设你的图片存放在~/my_dataset/images/共 1200 张 JPG相机采集帧率为 30 FPS即每帧间隔 0.033333 秒。绝对不能用文件修改时间mtime——它受拷贝、解压等操作污染。必须用逻辑时间戳# save as ~/my_dataset/generate_tum_txt.py import os import glob image_dir /home/yourname/my_dataset/images output_file /home/yourname/my_dataset/rgb.txt # 按文件名数字排序确保 000001.jpg 在 000002.jpg 前 images sorted(glob.glob(os.path.join(image_dir, *.jpg)), keylambda x: int(os.path.basename(x).split(_)[-1].split(.)[0])) with open(output_file, w) as f: for i, img_path in enumerate(images): timestamp i * 0.033333 # 30 FPS # TUM 格式要求时间戳为 9 位小数且路径为相对路径相对于当前工作目录 rel_path os.path.relpath(img_path, /home/yourname/my_dataset) f.write(f{timestamp:.9f} {rel_path}\n) print(fGenerated {len(images)} lines in {output_file})运行后生成的rgb.txt前三行类似0.000000000 images/img_000001.jpg 0.033333000 images/img_000002.jpg 0.066666000 images/img_000003.jpg注意relpath必须相对于你后续运行mono_tum的目录。如果计划在~/ORB_SLAM2下执行则rgb.txt中的路径应为../../my_dataset/images/img_000001.jpg。脚本中os.path.relpath(img_path, /home/yourname/my_dataset)是为后续cd ~/my_dataset ../ORB_SLAM2/Examples/Monocular/mono_tum ...场景设计的。3.2 创建最小化 depth.txt单目模式必需但可空即使单目模式不用深度图mono_tum仍会尝试读取depth.txt。创建一个空文件即可否则报错Cannot open depth filetouch ~/my_dataset/depth.txt3.3 校准 camera.yaml四个内参必须与实际采集设备一致Examples/Monocular/TUM1.yaml是为 TUM 数据集标定的你的相机参数焦距fx/fy、主点cx/cy、畸变系数k1/k2/p1/p2/k3完全不同。错误的内参会导致特征点投影误差爆炸SLAM 直接失败。获取方法有两种推荐用 OpenCV 的calibrateCamera函数打印棋盘格A4 纸打印 8x6 角点格子尺寸 2.5cm拍 20 张不同角度照片运行 OpenCV 官方标定脚本 。输出camera_matrix和dist_coeffs。应急若只有单张清晰图像用 Kalibr 工具箱但需 ROS 环境。将标定结果填入camera.yaml%YAML:1.0 # Camera calibration parameters (OpenCV) - REPLACE THESE! Camera.fx: 615.23 Camera.fy: 615.23 Camera.cx: 320.5 Camera.cy: 240.5 Camera.k1: 0.072 Camera.k2: -0.125 Camera.p1: 0.001 Camera.p2: 0.0005 Camera.k3: 0.0 # Image size - MUST match your images! Camera.width: 640 Camera.height: 480 # Distortion model - usually equidistant for fisheye, plumb_bob for standard lens Camera.model: plumb_bob关键检查点Camera.width/height必须与你图片的实际分辨率完全一致用identify -format %wx%h img_000001.jpg验证Camera.model若用广角镜头选equidistant否则plumb_bobk3在 OpenCV 3.4.18 中必须显式设为0.0否则cv::fisheye::initUndistortRectifyMap报错。4. 运行与实时可视化启动 mono_tum、连接 Pangolin 窗口、监控关键日志流编译完成、数据就位、参数校准后终于可以启动。但 ORB-SLAM2 的运行不是“一键开始”而是一系列状态确认从加载词典、初始化地图到关键帧插入、局部建图线程唤醒。任何一步卡住都需要看日志定位。4.1 构建最小运行命令路径、词典、yaml、数据四要素缺一不可进入 ORB-SLAM2 根目录执行假设你的rgb.txt在~/my_dataset/cd ~/ORB_SLAM2 ./Examples/Monocular/mono_tum \ Vocabulary/ORBvoc.txt \ Examples/Monocular/TUM1.yaml \ ~/my_dataset/rgb.txt \ ~/my_dataset/depth.txt注意顺序mono_tum的参数顺序是固定的vocabulary settings rgb_list depth_list。漏掉depth.txt或顺序颠倒会直接报Usage: mono_tum vocabulary path settings path rgb list path depth list path。4.2 实时监控终端日志识别三个关键成功信号程序启动后终端会滚动输出日志。不要只盯着最后一行要捕获以下三个里程碑词典加载成功Loading ORB Vocabulary. This could take a while...→Vocabulary loaded!若卡在Loading...超过 10 秒检查Vocabulary/ORBvoc.txt是否损坏大小应为 ~180MB。初始化地图成功Initializing first frame...→Creating initial map...→Initial map created with X KFs and Y MPsX通常为 2初始关键帧第一帧Y为匹配的 3D 地图点数50 才算健康。若Y为 0检查camera.yaml内参或图片是否全黑/过曝。局部建图线程启动Starting thread Local Mapping...→New keyframe inserted持续滚动此时 Pangolin 窗口应已弹出显示实时相机视图、特征点云、绿色轨迹线。若窗口无反应检查Pangolin是否编译成功见 2.3 节。4.3 Pangolin 可视化窗口操作指南不只是看更要干预Pangolin 窗口左上角有实时状态栏显示Tracking State: OK/LOST/NOT_INITIALIZED。常用操作暂停/继续空格键暂停后可拖拽 3D 场景观察地图结构重置视图R键恢复默认视角保存轨迹S键 → 自动生成CameraTrajectory.txt每行timestamp tx ty tz qx qy qz qw导出点云P键 → 保存为KeyFrameTrajectory.txt关键帧位姿和MapPoints.txt3D 点坐标提示若轨迹线断续或抖动剧烈按F键切换到Follow Camera模式观察是否因特征点跟踪失败导致Tracking State: LOST。此时可尝试降低camera.yaml中的ThDepth深度阈值或增加ORBextractor.nFeatures特征点数量。5. 常见问题排查五个真实翻车现场与后悔药部署 ORB-SLAM2 最耗时的环节不是编译而是解决那些“看起来像配置错、其实是底层库打架”的玄学问题。以下是我在某高校实验室部署 12 套环境时高频出现的 5 类问题按现象→原因→解决三步法整理避免你重复踩坑。5.1 现象mono_tum启动后立即 segfaultgdb 显示崩溃在cv::Mat::create()原因OpenCV 3.4.18 与 GCC 9.4 的 ABI 兼容性问题。GCC 9.4 默认启用-fabi-version11而 OpenCV 3.4.18 的二进制预编译包如 pip 安装是用-fabi-version10编译的导致cv::Mat内存布局错乱。解决必须源码编译 OpenCV见 2.2 节并在cmake命令中显式添加-D CMAKE_CXX_FLAGS-fabi-version10cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D CMAKE_CXX_FLAGS-fabi-version10 \ # 关键 ... # 其他参数不变5.2 现象Pangolin 窗口弹出但全黑或显示“OpenGL Error: Invalid Operation”原因Ubuntu 20.04 的 Mesa 驱动默认启用 OpenGL 3.3而 Pangolin 0.6ORB-SLAM2 v1.0 绑定版本仅支持 OpenGL 3.1。解决编译 Pangolin 时强制使用 LEGACY OpenGL 后端见 2.3 节或在运行前设置环境变量export MESA_GL_VERSION_OVERRIDE3.1 export MESA_GLSL_VERSION_OVERRIDE140 ./Examples/Monocular/mono_tum ...5.3 现象Tracking State: LOST频繁出现特征点匹配数 20但图片清晰无运动模糊原因camera.yaml中的Camera.k1/k2畸变系数符号反了。OpenCV 标定输出的dist_coeffs是[k1,k2,p1,p2,k3]但某些标定工具如 Kalibr输出顺序为[k1,k2,p1,p2,k3]但数值范围不同直接复制会导致去畸变方向错误。解决用 OpenCV 自带的cv2.undistort函数验证import cv2 img cv2.imread(img_000001.jpg) K np.array([[615.23, 0, 320.5], [0, 615.23, 240.5], [0, 0, 1]]) D np.array([0.072, -0.125, 0.001, 0.0005, 0.0]) # 确保 k1,k2 符号与标定输出一致 undistorted cv2.undistort(img, K, D) cv2.imwrite(undistorted.jpg, undistorted)对比原图和undistorted.jpg若边缘拉伸更严重说明k1/k2符号需取反。5.4 现象mono_tum运行数秒后卡死CPU 占用 100%但无错误日志原因Thirdparty/g2o编译时未启用多线程优化g2o::OptimizationAlgorithmLevenberg在大地图优化时陷入死循环。解决重新编译 g2o启用 OpenMPcd Thirdparty/g2o mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease -DG2O_BUILD_APPSOFF -DG2O_BUILD_UNITTESTSOFF -DOPENMP_USEON make -j$(nproc)5.5 现象轨迹文件CameraTrajectory.txt生成但用plot_trajectory.py绘图时坐标轴混乱Z 轴朝天而非朝前原因ORB-SLAM2 使用的坐标系是Right-Down-ForwardX-Y-Z而多数绘图脚本如 TUM 提供的默认Right-Up-Forward。Z 轴方向被镜像了。解决在绘图脚本中对 Z 坐标取负# 修改 plot_trajectory.py 中的轨迹加载部分 for line in f: data line.strip().split() if len(data) 8: ts, tx, ty, tz, qx, qy, qz, qw map(float, data) trajectory.append([ts, tx, ty, -tz, qx, qy, qz, qw]) # tz 加负号6. 验证轨迹有效性用 TUM 评估工具计算 ATE/RPE建立你的 SLAM 交付标准装完、跑通、看到轨迹线不等于 SLAM 结果可用。真正的验证是量化指标绝对轨迹误差ATE衡量全局一致性相对位姿误差RPE衡量局部运动精度。TUM 提供的evaluate_ate.py和evaluate_rpe.py是工业界事实标准但它们要求真值轨迹ground truth——而你的自有数据集没有。这里给出两种务实方案一种是“借真值”一种是“造真值”。6.1 方案一用运动捕捉系统MoCap数据作为真值高精度场景若实验室有 Vicon 或 OptiTrack采集同步的 MoCap 轨迹.csv格式每行timestamp tx ty tz qx qy qz qw需转换为 TUM 格式# mo_cap_to_tum.py import csv with open(mocap.csv) as f, open(groundtruth.txt, w) as out: reader csv.reader(f) for row in reader: # 假设 CSV 列为 timestamp,x,y,z,qx,qy,qz,qw ts, tx, ty, tz, qx, qy, qz, qw row # TUM 格式timestamp tx ty tz qx qy qz qw out.write(f{ts} {tx} {ty} {tz} {qx} {qy} {qz} {qw}\n)然后用 TUM 评估工具比对python evaluate_ate.py groundtruth.txt CameraTrajectory.txt --plot ate_result.pdf --verbose关键看输出中的rmse值rmse 0.05m优秀室内导航级0.05m rmse 0.15m可用AR 场景rmse 0.15m需检查内参或重采数据6.2 方案二用闭环检测结果自验证无真值场景若无 MoCap利用 ORB-SLAM2 自身的闭环检测能力当Loop Closing线程成功触发日志出现Correct loop found!它会输出pose_graph.txt闭环校正后的位姿。比较校正前后的轨迹差异# 提取原始轨迹未闭环和闭环后轨迹 grep FRAME CameraTrajectory.txt | awk {print $2,$3,$4,$5,$6,$7,$8} raw_traj.txt grep LOOP pose_graph.txt | awk {print $2,$3,$4,$5,$6,$7,$8} looped_traj.txt # 计算两轨迹的 RMS 差异简易版 python -c import numpy as np a np.loadtxt(raw_traj.txt)[:, :3] b np.loadtxt(looped_traj.txt)[:, :3] diff a[:len(b)] - b print(RMS drift:, np.sqrt(np.mean(diff**2))) 若RMS drift 0.02m说明闭环有效轨迹全局一致。6.3 建立你的 SLAM 交付 checklist五项必检少一项都不算完成从某跨平台系统项目落地经验出发我给自己定了硬性规则每次部署 ORB-SLAM2必须完成以下五项验证缺一不可否则视为环境未达标检查项验证方法合格标准不合格后果1. 词典加载耗时time ./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt ... 8s超时说明词典损坏或磁盘 I/O 瓶颈2. 初始化成功率连续运行 5 次记录Initial map created出现次数≥4/5频繁失败暴露内参或光照问题3. 特征点稳定性运行中按F键切 Follow 模式观察特征点云密度150 pts/frame100 说明图像质量或 ORB 参数需调4. 闭环触发率运行 300 帧统计Correct loop found!出现次数≥1零闭环说明地图退化或场景单调5. 轨迹文件完整性wc -l CameraTrajectory.txt≥200 lines行数过少表明早期跟踪失败从那以后我每次给新同事配环境都强制走一遍这个 checklist——哪怕只是跑 10 帧也要确认五项全绿。因为 SLAM 不是“跑起来就行”而是“跑得稳、测得准、改得明”。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑