简介面向需要在Windows环境下运行ORBSLAM的计算机视觉研究者和学生这份实验包解决了第三方库编译繁琐、环境配置困难的问题预先完成所有依赖库的编译并整理好属性表下载后简单设置即可直接运行适用于特征点法SLAM的入门与进阶实验。代码经过基本封装单目SLAM主流程清晰便于开展二次开发和算法调试可灵活调整特征提取、跟踪策略等环节。压缩包共898个文件包含600余个头文件与130余个hpp声明、32个cpp源码、12个lib静态库和12个dll动态库以及6个props属性表、6个yaml配置参数按功能模块组织可快速定位特征提取、跟踪、建图等核心代码。附带的16张张氏标定板图片jpg格式可用于相机内参标定辅助评估系统精度。已有362人学习下载适合希望跳过繁重编译过程、直接聚焦SLAM实验与研究的开发者。1. 在Windows下跑通ORBSLAM实验为什么这件事比装个依赖库难两倍如果你在Linux上编译过ORB-SLAM大概二十分钟就能跑起来可一旦把阵地换到Windows这件事可能耗掉你整个周末。我用三个晚上踩完所有坑之后最大的感受是Windows下跑通ORBSLAM实验难点根本不在SLAM算法本身而在依赖编译和环境对齐。这个实验要解决的是让你在Windows环境下编译并运行一个基于ORB特征、包含跟踪、局部建图、回环检测三大线程的完整视觉SLAM系统它既能跑公开数据集也能吃实时摄像头数据。适合刚入门SLAM的研究生、需要在Windows上做离线评估的工程师以及想在动手调算法前先把一套完整系统跑起来的人。下面这套流程我按自己复现过的组合从头写起。2. 依赖选型与安装顺序ORB-SLAM的三条依赖链路和一套版本组合2.1 依赖链路OpenCV、Eigen、Pangolin、g2o、DBoW2各管哪一段ORB-SLAM2的代码结构不算复杂三个核心线程各司其职Tracking线程做ORB特征提取、特征匹配和位姿估计LocalMapping线程负责局部Bundle Adjustment优化地图点LoopClosing线程用词袋模型检测回环并触发全局优化。这条链路上每个关键环节都对应一个第三方库Windows下装依赖其实就是把这几个库逐个编译出来。OpenCV管的是图像读取、ORB特征提取、PnP求解和部分可视化辅助Eigen3提供矩阵运算基础是g2o和Sophus的前提Pangolin负责画窗口和轨迹显示g2o做图优化DBoW2做回环检测的词袋匹配。需要注意DBoW2和g2o在ORB-SLAM2源码的Thirdparty目录里自带一份编译时直接用这份不要去系统里另装版本否则很容易出现链接冲突。这套依赖链的麻烦之处在于在Linux上apt或源码编译都是标准流程而在Windows上每个库都要自己做CMake生成工程、再用Visual Studio编译任何一个版本错位都会导致后面对不上。尤其是Pangolin它还要依赖GLEW、GLUT这些OpenGL相关的Windows实现装的时候又多一层变量。2.2 版本组合表VS2019 OpenCV3.4 Pangolin0.6的搭配理由我常用的版本组合如下这是我在多次编译里试出来的相对稳定的搭配组件推荐版本说明Visual Studio2019 Communityv142工具集VS2022也能用但需要把平台工具集手动调低CMake3.16 ~ 3.25太新的CMake对旧Pangolin有策略类警告OpenCV3.4.10 ~ 3.4.16不要用4.xORB-SLAM2大量使用旧APIEigen33.3.7 ~ 3.3.93.4能用但有较多编译警告3.3最稳Pangolinv0.6master分支要求C17配旧代码不如0.6省心DBoW2 / g2o使用ORB-SLAM2源码内Thirdparty自带版本不要替换成系统安装版本OpenCV选3.4而不是4.x是因为ORB-SLAM2代码里用到不少OpenCV 3时代的接口比如CV_WINDOW_AUTOSIZE这种宏在4.x里被改名还有一些特征匹配的参数结构也变了。Eigen选3.3是考虑到g2o和Pangolin在编译时默认按3.3的宏展开如果装了3.4Pangolin调用Eigen的某些头文件会多出大量警告虽然多数不影响结果但排错时非常干扰视线。2.3 安装过程用CMake命令行编译OpenCV与Pangolin参数怎么设OpenCV的编译建议用命令行配置好后再到Visual Studio里按顺序生成ALL_BUILD和INSTALL。下面是我常用的命令cmake .. -G Visual Studio 16 2019 -A x64 \ -DCMAKE_BUILD_TYPERelease \ -DBUILD_opencv_worldON \ -DWITH_OPENMPON \ -DBUILD_SHARED_LIBSON \ -DCMAKE_INSTALL_PREFIXC:/opencv/installBUILD_opencv_worldON是关键它会把所有OpenCV模块合成为一个opencv_world库文件后面链接时只需要指一个库目录省掉几十个.lib匹配的麻烦。BUILD_SHARED_LIBSON保证生成DLL方便运行时替换和排查。CMAKE_INSTALL_PREFIX是安装路径编译完在VS里对INSTALL项目生成一次OpenCV的头文件和DLL会统一拷贝到这个目录。有个参数是新手容易忽略的VS里必须把解决方案配置切到Release再对ALL_BUILD右键生成。如果前面CMake里指定Release后面VS里却选了Debug生成的.lib名字带d后缀后面主程序链接时会直接报LNK2019。Pangolin的编译命令类似cmake .. -G Visual Studio 16 2019 -A x64 \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIXC:/pangolin/install \ -DBUILD_EXAMPLESOFFPangolin在Windows下最常见的问题是找不到GLEW。如果你的环境里没有GLEW可以在CMake配置前先装好或者把BUILD_PANGOLIN_VIDEO关掉先编译出来验证完基础功能再补视频模块。BUILD_EXAMPLESOFF可以减少编译量只保留库本体这个开关不影响ORB-SLAM调用。3. 编译ORB-SLAM2主体VS工程生成、第三方库链接和源码的Windows化改动3.1 vcpkg还是手动编译依赖管理路径怎么选在Windows上管理C依赖现在很多人第一反应是用vcpkg。比如vcpkg install opencv[world]:x64-windows eigen3 pangolin一条命令能装好几个库听起来省事但实际踩下来有个问题vcpkg默认给的是它仓库里最新或较新的版本版本号不可控很可能拿到OpenCV4.x和Eigen3.4而这正好是ORB-SLAM2最不待见的组合。另外ORB-SLAM2源码自带的DBoW2和g2o是独立于vcpkg的你仍然需要单独编译它们。vcpkg只帮你省了OpenCV、Eigen、Pangolin这三个通用库的编译省下来的时间又一部分花在和版本较劲上。我的选择是通用依赖手动编译固定版本vcpkg用作补充比如临时需要某个小工具库时再装。这样翻车概率最低。如果你实在想用vcpkg也不是不行装完以后把VCPKG_INSTALLED_DIR指到对应目录CMake也能找到。但请务必确认三个库的版本是匹配的否则第三方的g2o在链接OpenCV的C接口时会炸出各种模板实例化错误。3.2 用CMake GUI生成ORB_SLAM2.sln并设置依赖路径ORB-SLAM2的根目录自带CMakeLists.txt可以直接用CMake GUI生成VS工程。比起纯命令行GUI对新手更友好因为它会把找不到的依赖项直接标红。打开CMake GUI后源目录填ORB_SLAM2根目录构建目录填ORB_SLAM2/build点Configure选Visual Studio 16 2019和x64。第一次Configure大概率会报错原因通常是找不到Pangolin或OpenCV。这时需要手动指定三个变量OpenCV_DIRC:/opencv/install Pangolin_DIRC:/pangolin/install/lib/cmake/Pangolin EIGEN3_INCLUDE_DIRC:/eigen3这三个变量名在不同版本的CMake里略有差异如果EIGEN3_INCLUDE_DIR没生效就在CMAKE_PREFIX_PATH里把Eigen和Pangolin的安装根目录都加进去。Configure成功后点Generate生成ORB_SLAM2.sln然后用VS打开它。打开工程后第一件事是把解决方案配置从Debug切到Release。前面三方库都是Release编译的主工程也必须是Release否则链接会报一堆msvcrtd.lib与libcmt.lib冲突的错误。第二件事是逐个项目检查属性里的C语言标准把/std:c14加上ORB-SLAM2的老代码在C17下偶尔会出现std::unexpected之类的编译error。3.3 必改的源码usleep、_CRT_SECURE_NO_WARNINGS 与 Debug/Release 对齐ORB-SLAM2是Linux起家的项目源码里有几处Windows下无法直接编译的调用。最常见的改动是usleep函数。它存在于unistd.hWindows没有这个头文件。我一般在涉及的关键.cpp文件顶部加一段兼容代码#ifdef _WIN32 #include windows.h #define usleep(x) Sleep((x) / 1000) #else #include unistd.h #endif这段的作用很直接在Windows下用Sleep替换usleep并把微秒换算成毫秒。改动点主要集中在src/System.cc、Examples/Monocular/mono_tum.cc、Examples/RGB-D/rgbd_tum.cc这几个文件。Sleep的参数是毫秒usleep的参数是微秒除以1000不能省否则线程休眠时间差了三个数量级运行节奏会明显不对。第二处必改是fopen等函数在VS下的安全警告。OpenCV和ORB-SLAM2的代码里用了不少标准C文件函数VS默认会把它当成error。与其逐个改函数名不如在VS的项目属性里加_CRT_SECURE_NO_WARNINGS预处理器定义或者在每个源文件顶部加#define _CRT_SECURE_NO_WARNINGS。这个属于纯编译器策略问题不改语义只消警告。第三处容易翻车的地方是Debug/Release混用。很多人前面依赖库编了Release主工程编译时却顺手在VS里选了Debug结果链接阶段出现大量LNK2005重复符号错误。解决方式很简单三处统一——三方库编ReleaseCMake生成工程时指定ReleaseVS里主工程也选Release。检查顺序按这个来基本能规避九成链接错误。4. 跑通第一个TUM序列从数据集准备到轨迹误差评估4.1 数据集选型与配置文件为什么建议先从fr1_desk开始TUM数据集是ORB-SLAM论文中使用最广泛的评测集之一它的特点是自带真值轨迹和多种场景。选数据集有个原则刚开始跑通阶段不要一上来就用大场景或长时间序列选一个小范围、光照稳定、纹理中等偏上的室内序列最合适。fr1_desk就是这种典型桌面场景相机运动幅度适中纹理充足既不会因为快速运动导致特征丢失也不会因为纯平面场景让PnP退化。我见过不少新手直接用fr3_long_office_household那个序列时间更长、场景更大跑到后半段位姿漂移明显第一反应往往是自己编译错了其实不是。先用fr1_desk把流程跑顺再换其他序列验证才是更稳的路径。数据集的配置文件直接用ORB-SLAM2自带的TUM1.yaml即可。这个YAML里写了相机的内参fx/fy/cx/cy、畸变系数、以及相机频率。TUM数据集对应的相机型号各不相同严格来说每个序列有自己的标定参数但fr1系列大多共用一组近似参数跑实验足够。等你要做严格精度评测时再按数据集官网给的内参覆盖YAML。4.2 单目与RGB-D的最小启动命令参数含义和路径习惯编译成功后运行程序分两种模式。单目模式对应mono_tumRGB-D模式对应rgbd_tum。单目最小启动命令是Examples\Monocular\Release\mono_tum.exe Vocabulary\ORBvoc.txt Examples\Monocular\TUM1.yaml D:\datasets\fr1_desk三个参数的含义分别是词袋文件路径、相机配置文件路径、数据集序列根目录路径。词袋文件用Vocabulary\ORBvoc.txt程序启动时会逐行读入并构建DBoW2的词典这个过程大概要几秒到十几秒属于正常现象。如果你觉得每次启动都要等也可以提前用项目里未提供的小工具把文本词袋转成二进制的ORBvoc.bin加载能快不少但这不是必须的。RGB-D模式多一个参数也就是关联文件Examples\RGB-D\Release\rgbd_tum.exe Vocabulary\ORBvoc.txt Examples\RGB-D\TUM1.yaml D:\datasets\fr1_desk D:\datasets\fr1_desk\associations.txt关联文件是RGB-D实验的必需品它把彩色图和深度图按时间戳一一对应。TUM官网提供了associate.py脚本也可以自己在启动前用几行Python生成。注意TUM官方的彩色图和深度图时间戳不完全一致直接用按文件名排序会出问题必须先做时间戳匹配否则后面跟踪会大量丢帧。我习惯在Windows Terminal里跑这些命令路径用反斜杠不会遇到Git Bash里那种盘符挂载转换问题。还有一个老生常谈的坑数据集路径和工程路径都不要带中文也不要有空格。带空格的路径在启动时会被命令行拆开程序读到的序列路径是残缺的表现出来就是窗口一闪而过或者加载图像为零张。4.3 结果怎么看KeyFrameTrajectory.txt与evo评估ATE程序跑完后在ORB-SLAM2的根目录下会生成KeyFrameTrajectory.txt和CameraTrajectory.txt两个文件。前者记录的是每一帧关键帧的位姿后者是所有帧的估计轨迹。文件格式都是TUM格式每一行是时间戳、平移x/y/z、四元数q_x/q_y/q_z/q_w。评估精度最常用的工具是evo它专门处理这类SLAM轨迹文件。跑完实验后用下面命令评估绝对轨迹误差evo_ape tum KeyFrameTrajectory.txt groundtruth.txt -a -v其中groundtruth.txt是TUM数据集自带真值文件需要放到与估计轨迹同级的路径下。-a表示用SE(3) Umeyama算法对齐估计轨迹和真值轨迹消除坐标系偏移的影响-v把结果以图表形式弹出来。命令行末尾加上--plot可以保存png格式的误差曲线图。怎么看结果是否正常对fr1_desk来说ATE的RMSE在2到5厘米范围属于正常。如果你跑出来的误差达到几十厘米甚至抛出明显漂移先别急着认为是代码编译有问题更多是单目初始化时真实尺度没对齐造成的这是单目SLAM的固有现象多跑几帧让它完成初始化误差会回落。开启-a对齐后尺度误差会被部分吸收所以直接看RMSE绝对值前先确认对齐方式。5. 踩坑与排查Windows下ORB-SLAM编译和运行的五个高发问题5.1 LNK2019/LNK2005链接错误库版本混用的连锁反应现象用VS编译ORB_SLAM2.sln时链接阶段报大量LNK2019无法解析的外部符号尤其是OpenCV相关符号另一种是LNK2005重复定义提示某个函数已经定义。原因八成是三方的库和你主工程版本不对齐。常见组合是OpenCV编译时用了BUILD_opencv_worldON但主工程CMake指过去的路径里混杂了OpenCV 3.4和OpenCV 4.x两套目录CMake先找到了一套生成规则链接时又链到另一套文件目录下符号表自然对不上。另一种是高发场景OpenCV是Release主工程选Debug链接进去的lib带d后缀函数签名必须不一致。解决把OpenCV_DIR、Pangolin_DIR等变量重新指到唯一的安装路径清掉build目录重新Configure。然后进入VS在解决方案管理器右键每个项目配置管理器里确认“活动解决方案配置”是Releasex64平台。检查工程属性里的“附加依赖项”如果看到opencv的lib列表确保和OpenCV_DIR下实际存在的目录一致。5.2 启动即崩溃找不到opencv_world DLL的三种姿势现象编译成功双击mono_tum.exe弹出对话框提示“找不到opencv_world341.dll”或者程序直接闪退没有任何日志。原因Windows下可执行文件运行时按路径顺序查找DLLOpenCV的安装路径如果没进系统PATH程序就找不到。另一种情况是UAC导致环境变量没生效或者是当前shell没重启PATH列表里没有新加的目录。解决第一优先把C:\opencv\install\x64\vc15\bin这类DLL目录加到系统PATH然后重启终端重新运行。第二是把需要的DLL直接拷贝到exe同级目录一劳永逸但升级时容易混乱。第三是检查你是不是把系统里装了两个OpenCV老的3.4.x和新的4.x混在一起这种情况建议只保留一个版本或者把其中一个目录整个移走。我在Windows上一般选择第二优先级的直接拷贝方式做实验不折腾环境变量。5.3 Pangolin窗口白屏或黑屏OpenGL上下文与远程桌面的干扰现象程序正常启动终端打印初始化的日志但Pangolin弹出来的窗口里什么都画不出来白色或全黑偶尔还能看到一小块控件但地图点和轨迹都不显示。原因Pangolin依赖OpenGL上下文Windows下的显卡驱动如果没有正确初始化或者你通过远程桌面/虚拟机运行OpenGL只提供软件渲染或干脆禁用Pangolin会创建窗口成功但没有任何绘制内容。解决先确认是不是远程桌面环境如果是换台本地主机跑。如果本地也不行到显卡控制面板里把ORB_SLAM2相关exe设为使用独立显卡而不是集成显卡。另一个保险做法是更新OpenGL驱动后清空build目录重新编译Pangolin因为这个库在编译时会按当时的OpenGL头文件版本生成部分代码。还有一个容易忽略的问题Pangolin窗口创建后如果你拖动窗口或切到后台绘制线程被挂起切回时地图点全部消失也是正常现象不算bug。5.4 建图中途闪退Eigen对齐和VS工程属性的隐蔽设置现象程序启动正常跑几秒或几十秒后突然崩溃错误信息里经常出现“EIGEN_MAKE_ALIGNED_OPERATOR_NEW”或static assertion failed有的还会提示class std::vector相关。原因Eigen的高版本在SSE向量化时要求对齐内存而STL容器不保证分配器的对齐属性当你把含固定尺寸向量类型的对象放进std::vector或std::map时越界访问内存直接崩。这个问题在Linux的GCC下表现不强烈Windows的MSVC下特别明显。解决在自定义的包含Eigen::Isometry3d、Eigen::Matrix4d的类型里加上EIGEN_MAKE_ALIGNED_OPERATOR_NEW宏。如果代码里用了vectorKeyFrame*这种指针容器不受影响真正有风险的是vectorEigen::Vector3d和vectorSophus::SE3这类值类型容器。此外给VS里每个相关项目加上/bigobj编译选项它能避免大型目标文件在链接时出现“too many sections”之类的溢出错误这个错误在ORB-SLAM里也很常见。5.5 按了启动键却读不到图像路径空格、中文目录和反斜杠现象运行mono_tum.exe后终端显示加载完词袋然后提示找不到图像或者显示图像数为0接着就退出。原因路径里带了中文目录名或者数据集路径有空格命令行解析时把这些字符截断了。还有一种是我踩过的玄学在Git Bash里运行Windows路径时D:\datasets\fr1_desk会被解释成/d/datasets/fr1_desk程序按照Windows路径找数据自然零结果。解决数据集路径和工程路径统一放到英文、无空格目录下比如D:\slam\datasets\fr1_desk。运行程序时不要从Git Bash或MSYS环境启动用Windows Terminal或CMD直接调exe。如果你确实想用脚本启动把路径写成正斜杠D:/slam/datasets/fr1_deskWindows API本身认识正斜杠这样能减少一层转义问题。这个坑说大不大但每一届新手都会踩一遍属于路径玄学里的顽固分子。6. 进阶把USB摄像头接进ORB-SLAM把离线实验变实时Demo6.1 以最小改动实现实时单目入口跑通离线数据集后把ORB-SLAM接上实时摄像头是验证系统真实性的最好一步。改动量其实很小核心思路是复用mono_tum的框架把图像来源从数据集换成VideoCapture。大致结构如下cv::VideoCapture cap(0); cap.set(cv::CAP_PROP_FRAME_WIDTH, 640); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480); ORB_SLAM2::System SLAM(Vocabulary/ORBvoc.txt, Examples/Monocular/TUM1.yaml, ORB_SLAM2::System::MONOCULAR, true); while (cap.isOpened()) { cv::Mat frame; cap frame; if (frame.empty()) continue; Sophus::SE3f Tcw SLAM.TrackMonocular(frame, timestamp); timestamp 0.03; }TrackMonocular返回当前帧的位姿如果初始化还没完成返回的矩阵里会带一个无效标志。单目实时模式最需要注意的是初始化程序启动后要缓慢平移摄像头让它看到有明显视差的场景盯着不动是永远初始化不出来的。分辨率设在640x480左右是因为实时特征提取在更高分辨率下的耗时会让帧率掉到10帧以下。6.2 实时跑的验证标准和调参习惯我一般会开两个窗口一个看Pangolin的实时地图点一个看终端打印的帧耗时。帧耗时在30毫秒上下算健康如果超过60毫秒就把相机画面里的纹理丰富区域对准一下墙角、桌面边缘这些特征明显的区域。地图点数量在几百到几千都正常关键是回环窗口有没有出现闭环边。实时跑通是实验的转折点也是你第一次能直观感受到单目SLAM的尺度漂移有多直接。最后说一句个人习惯我现在在Windows上跑SLAM实验会把版本组合和补丁改动额外存一份说明脚本每次换机器就能少折腾一个多小时也算是对自己踩过的坑留个后悔药。希望帮到你。本文还有配套的精品资源点击获取