简介:面向SLAM研究与机器人开发者的Windows平台ORB-SLAM3适配实战包,围绕ORB-SLAM3在Windows下的编译、配置与二次开发提供完整工程方案。压缩包共2000个文件、约318.29MB,其中840个cpp源文件、699个h头文件构成算法主体,348个txt文件多为配置说明与使用文档,23个yaml文件对应相机参数与系统配置,另有c/cc/sh/py等文件用于辅助构建与扩展。包内包含环境搭建、源代码配置、功能演示及接口调用等模块,针对内存管理、线程同步等跨平台问题做了专门优化,并利用Windows多线程与GPU加速提升运行效率。已有688人学习下载,适合具备一定C++基础、希望快速在Windows平台落地ORB-SLAM3的开发者参考借鉴。 差不多两年前我第一次在Windows上尝试编译ORB-SLAM3,折腾了将近一周,中间一度想放弃换回双系统。后来把一个一个坑填平、把整套流程跑通之后,回头去看,Windows适配这件事其实没有想象中那么玄,只是官方仓库默认只给Linux写了构建脚本,导致大多数人都被挡在了第一步。
这篇文章就把我自己在Windows平台上从零编译、配置、运行ORB-SLAM3的完整过程整理出来。包括依赖库的版本选择、CMake工程怎么改、有哪些编译期的高频报错、以及跑通EuRoC和TUM数据集后怎么用evo做精度评估。适合手里只有Windows机器、又需要跑视觉SLAM算法的学生、算法工程师和做产品验证的朋友。
1. 为什么我非要在Windows上折腾ORB-SLAM3
先说结论:如果你手头有Ubuntu环境,直接照官方README装,半小时就能跑起来。但现实情况里,"只能用Windows"的场景比想象中多——公司办公机锁了系统不让装双系统、实验室公用机器装不了Linux、又或者你的目标就是要把SLAM算法集成到一个Windows桌面的上位机软件里去。
ORB-SLAM3是目前视觉SLAM领域里综合能力很能打的一套开源方案。它把单目、双目、RGB-D三种视觉模式,和单目+IMU、双目+IMU两种惯性紧耦合模式全部收到了一套框架里,还支持多地图系统(Multi-Map)和混合地图复用。跟ORB-SLAM2相比,官方论文里给的数据是精度平均提升2到5倍,尤其在相机快速运动、短时遮挡、重复纹理这些场景下,鲁棒性强了很多。
但坏消息是,ORB-SLAM3的官方仓库没有Windows版本,build.sh是纯Linux的脚本,源码里也确实有一些依赖POSIX接口的代码。这就导致"Windows上跑ORB-SLAM3"成了一个大家都会遇到、但很少有人把完整路径写清楚的事情。
我当时的目标很明确:把ORB-SLAM3编译成Windows原生的exe,能用命令行跑EuRoC和TUM数据集,能输出KeyFrameTrajectory.txt这种轨迹文件,后面再用evo做评估。不做ROS版本,不做界面,先把算法验证这条链路打通。这个目标也是我建议你第一次适配时的参考范围——千万别一上来就想着接ROS、接相机实时跑,先把离线数据集跑通,再谈下一步。
2. 环境准备:版本匹配决定命运
2.1 工具链清单
Windows下编译ORB-SLAM3,最稳定的组合我实测下来是这样一套:
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| Visual Studio | 2019 或 2022 | 必须安装C++桌面开发工作负载 |
| CMake | 3.16及以上 | 建议用最新稳定版 |
| Git | 任意较新版本 | 拉取源码和第三方库 |
| OpenCV | 4.x(建议4.5.5或4.8.x) | 不建议用3.x,ORB-SLAM3的CMake是按4.x写的 |
| Eigen | 3.3.x | 纯头文件库,无需编译 |
| Pangolin | 最新master分支 | 用于可视化,Windows下依赖较多 |
这套组合我后来在不同机器上装过至少三次,一次是VS2019 + OpenCV 4.5.5,一次是VS2022 + OpenCV 4.8.0,都能正常编译运行。版本上不要随便挑太老的,也不要追最新,OpenCV 4.8.1之前有几个版本的VideoIO在Windows上和Pangolin有冲突,4.5.5到4.8.0这个区间最稳。
2.2 编译顺序有讲究
依赖库之间有依赖关系,编译顺序建议是:
- Eigen:无需编译,把目录解压好,在CMake里指定
EIGEN3_INCLUDE_DIR即可。它是纯头文件模板库,省去很多麻烦。 - OpenCV:官方有Windows预编译包,直接去官网下载
opencv-4.x.x-windows.exe,解压后就是一个build目录,里面已经带好了OpenCVConfig.cmake。建议把opencv\build\x64\vc15\bin或vc16\bin加进系统PATH,否则运行exe时找不到DLL。 - Pangolin:这个是最容易出问题的点。Windows下需要自己用CMake编译,依赖OpenGL、GLEW、GLFW、libjpeg等。如果手动折腾这些依赖太痛苦,可以用
vcpkg install pangolin:x64-windows一条命令装,省心很多。
我在第一次适配时Pangolin是用vcpkg装的,后面第二次是手动编译的。两者的差异后面会在编译环节展开讲。
2.3 手动编译Pangolin的关键步骤
如果你选择手动编译Pangolin,有两点必须注意。第一,CMake生成项目时要选x64架构,千万不要默认Win32,否则后面所有库的位数都会不对齐;第二,Pangolin的Windows依赖里,libjpeg和libpng如果本地没有,CMake会自动跳过JPEG支持,这不影响核心功能,但会影响SetImage相关接口的调用,ORB-SLAM3主要用Pangolin做3D可视化和UI窗口,影响不太大。
我自己用的编译命令是这样:
git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=C:/libs/pangolin -DCMAKE_BUILD_TYPE=Release -A x64 cmake --build . --config Release --target install注意-A x64这个参数,它只对Visual Studio生成器生效,用于指定目标架构。如果你用vcpkg,就不需要关心这些,装完直接用即可。
3. 修改源码与构建:把Linux项目掰成Windows形状
3.1 源码获取和目录结构
git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git目录结构里比较重要的几个地方:
Thirdparty/:DBoW2、g2o、Sophus,ORB-SLAM3把关键依赖内置了,这三个子库也能独立编译,需要用CMake单独构建;Vocabulary/:ORB词袋文件ORBvoc.txt,约28MB,运行时需要载入;Examples/:各传感器模式的示例工程,单目、双目、RGB-D、单目+IMU、双目+IMU,每个都有独立的CMakeLists.txt;include/:核心头文件,System.h是最主要的入口。
Windows下编译和Linux最大的区别是:Linux的build.sh会依次进入Thirdparty三个目录和Examples目录,逐个执行cmake和make,但Windows没有这个脚本,你需要自己一个一个用CMake配置。
为了方便,我自己写了一个批处理脚本,按顺序编译Thirdparty里的DBoW2、g2o、Sophus,再编译主工程和Examples。你也可以直接用VS的CMake功能一次配置整个工程,但说实话不如分步来,问题更容易定位。
3.2 核心源码修改点
ORB-SLAM3源码在Windows下直接编译,会遇到几个明确的报错,提前改掉能省很多时间。
第一处:unistd.h缺失
include/System.h和部分源文件里包含了unistd.h,这是Linux才有的头文件。最简单的处理方式是加一个平台判断:
#ifdef _WIN32 #include <io.h> #else #include <unistd.h> #endif如果还有gettimeofday之类的函数报错,可以在System.h或者公共头文件里加一个Windows下的替代实现,或者直接用std::chrono替换掉时间戳获取逻辑。
第二处:drand48()、srand48()不存在
这两个函数在ORB-SLAM3的LoopClosing.cc或LocalMapping.cc里会被用到,属于Linux的C库函数。Thirdparty/DBoW2里自带了一个Random.h,ORB-SLAM3自己的include/Random.h其实已经做了跨平台处理,但某些版本还是会漏。我的处理方式是直接搜出所有drand48调用的位置,改成Random::Unif(0.0f, 1.0f)。
第三处:CMakeLists.txt里的Linux假设
主目录的CMakeLists.txt里有这段逻辑:
IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE Release) ENDIF()Linux下默认Release没问题,但Windows下如果你用VS生成器,不显式指定/MD或者运行时库,可能出现静态运行时和动态运行时不匹配的问题,导致第三方库链接时各种LNK2038。建议在CMakeLists里显式设置:
set(CMAKE_CXX_FLAGS_RELEASE "/MD /O2 /Ob2 /DNDEBUG")3.3 用VS打开CMake工程的两种方式
源码改完后,有两种构建路径。
方式一:命令行CMake生成VS工程
mkdir build && cd build cmake .. -DOpenCV_DIR=C:/libs/opencv/build -DCMAKE_PREFIX_PATH=C:/libs/pangolin -A x64 cmake --build . --config Release这种方式会生成一个.sln,之后可以直接用VS打开继续调试。
方式二:直接让VS打开根CMakeLists.txt
VS2019以上的CMake集成很好用,直接文件 -> 打开 -> CMake,选择根目录的CMakeLists.txt,然后VS会自动配置、生成、编译。这种方式对新手最友好,因为所有的CMake报错都会以红波浪线的形式直接标出来。
我推荐方式一,因为ORB-SLAM3的示例工程有多个可执行文件,命令行构建能清楚看到每个目标是否编译成功、链接是否通过。
3.4 高频编译错误对照表
| 报错特征 | 原因 | 处理方法 |
|---|---|---|
LNK2001 unresolved external symbol一大片 | 库位数不一致,或者Debug/Release混用 | 所有库统一x64,统一Release,重编一遍 |
C2220 warning treated as error | 编译选项把警告当错误 | CMake里加/W0或去掉-Werror标志 |
fatal error C1083: Cannot open include file: 'unistd.h' | 平台头文件缺失 | 按上文加条件编译 |
could not find OpenCV_DIR | CMake没找到OpenCV | 在CMake缓存里手动指定OpenCV_DIR路径 |
Cannot specify include directories for imported target | 第三方库的CMake配置在Windows下兼容性问题 | 升级CMake版本,或把对应include路径写进主工程 |
我踩得最深的坑是Debug/Release混用。OpenCV预编译包自带的lib有opencv_world450.lib和opencv_world450d.lib两种,前者是Release,后者是Debug。CMake默认会根据CMAKE_BUILD_TYPE去选,但如果你在CMake里指定的是Release、VS里用Debug跑,链接器就会去拼命找opencv_world450d.lib,找不到就报一堆外部符号错误。这类问题不会只报一个错,而是几十行一起刷出来,很容易让人误判是源码问题。
4. 实机运行:用EuRoC和TUM把三套模式跑通
4.1 数据集准备
编译成功只是第一步,真正验证适配是否成功,要看能不能稳定跑完数据集。
EuRoC数据集(单目、双目、IMU)
EuRoC是苏黎世联邦理工发布的无人机视觉惯性数据集,包含11个序列(MH_01到MH_05是机房,V1_01到V2_03是室内)。ASL格式的包里,mav0/cam0/data是左目图像,mav0/cam1/data是右目图像,mav0/imu0/data.csv是IMU数据,mav0/state_groundtruth_estimate0/data.csv是真值轨迹。ORB-SLAM3的yaml配置文件里默认路径就对应这个结构。
TUM数据集(RGB-D)
TUM是慕尼黑工大发布的RGB-D数据集,格式和EuRoC不同。解压后里面有rgb/和depth/两个目录,分别存放彩色图和深度图,还有一个groundtruth.txt,每一行是时间戳 + 位姿。运行时ORB-SLAM3的RGB-D示例会用associate.py脚本把彩色图和深度图按时间戳匹配,Windows下你需要自己把对应的关联文件生成好。
这两个数据集官网都提供下载,EuRoC的MH_01大概2.7GB,TUM的fr1_xyz大概1.1GB,选一个跑通就够了,不用全下。
4.2 命令行参数与启动命令
编译完的exe在Examples/下的对应目录里。以单目EuRoC为例:
Examples\Monocular\mono_euroc.exe Vocabulary\ORBvoc.txt Examples\Monocular\EuRoC.yaml D:\Datasets\MH_01三个参数分别是:词袋文件路径、yaml配置文件路径、数据集根目录路径。yaml文件里面有相机内参、畸变系数、IMU噪声参数等,每个数据集的yaml在ORB-SLAM3源码里已经配好,直接用。
RGB-D的TUM示例:
Examples\RGB-D\rgbd_tum.exe Vocabulary\ORBvoc.txt Examples\RGB-D\TUM1.yaml D:\Datasets\fr1_xyz D:\Datasets\fr1_xyz\associations.txt第四个参数是关联文件路径。你没有这个文件的话,可以用TUM官方提供的associate.py脚本生成,命令是:
python associate.py rgb.txt depth.txt > associations.txt跑起来之后,如果一切正常,会弹出一个Pangolin的3D可视化窗口,窗口中可以看到相机轨迹和地图点实时生成。终端里会周期性打印当前帧号、跟踪状态、关键帧数量、每帧处理耗时等信息。跑完后程序会在当前目录生成KeyFrameTrajectory.txt,这就是后续评估用的轨迹文件。
4.3 用evo量化评估轨迹精度
跑通数据集只是第一步,算法效果到底怎么样,需要用工具量化。
evo是最常用的SLAM轨迹评估工具,支持TUM和KITTI格式的轨迹比较,能计算绝对位姿误差(ATE)和相对位姿误差(RPE)。安装很简单:
pip install evo --upgrade --no-binary evo注意一定加--no-binary evo,否则在某些Windows环境上会因为预编译包缺失依赖而失败。
评估ATE的命令:
evo_ape tum groundtruth.txt KeyFrameTrajectory.txt -a -s-a表示自动对齐(先做位姿对齐再算误差),-s表示尺度对齐。单目SLAM因为没有尺度信息,-s是必加的;RGB-D和双目本身有尺度,可以不加。
RPE评估:
evo_rpe tum groundtruth.txt KeyFrameTrajectory.txt -a -s我之前用这台Windows机器(i7-12700 + 32GB内存 + 无独显)跑出来的参考数据大致是这样:
| 数据集 | 模式 | ATE RMSE | 每帧耗时 |
|---|---|---|---|
| EuRoC MH_01 | 单目 | 0.11m | 25~35ms |
| EuRoC MH_04 | 单目+IMU | 0.08m | 20~30ms |
| TUM fr1_xyz | RGB-D | 0.012m | 30~45ms |
这个精度水平和论文报告的基本一致,说明Windows下的适配没有引入额外的精度损失。
4.4 实时显示与轨迹可视化
如果不想只是对着终端刷数字,可以用evo的绘图功能看轨迹对比:
evo_traj tum KeyFrameTrajectory.txt --ref=groundtruth.txt -a -s --plot_mode=xyz会弹出3D轨迹对比图,蓝色是估计轨迹、红色是真值,能很直观地看出漂移集中的区间。这个功能在调试自己的数据集时特别好用,因为数值指标只是平均值,轨迹图能暴露出具体是哪个时间段、哪个场景出了偏差。
5. 这套方案能直接支撑的项目场景与后续优化
5.1 直接能做的三件事
跑通这一整套之后,你手上就有了一套Windows原生可用的SLAM能力。它可以直接支撑以下几类工作:
第一,算法验证和论文复现。这在教学和科研里是最常见的需求。以前想在Windows上复现ORB-SLAM3的结果,很多人只得装虚拟机或双系统,性能损失不说,还被各种环境问题折磨。现在直接在Windows上就能跑完整个实验链路,包括数据预处理、SLAM运行、evo评估、绘制定量对比表。
第二,Windows桌面上位机集成。ORB-SLAM3的System类封装得很好,对着自己的相机写一个采集线程,把图像帧喂给mpSLAM->TrackMonocular()或TrackRGBD(),就能拿到当前帧的位姿。你在Windows上编译出来的lib和dll可以直接被一个Qt或MFC的桌面程序引用,省去了跨进程通信那层麻烦。
第三,离线SLAM批处理。比如你有一批离线视频或图片序列要处理,可以在Windows上写个脚本批量调用exe,自动把每条序列的轨迹文件生成出来,再统一用evo做精度汇总,非常适合做算法回归测试。
5.2 性能调优的方向
我的实测里,单目模式在纯CPU上每帧25到35毫秒,也就是大约30到40帧的处理速度,能实时但余量不大。如果后续要跑更高分辨率或者更高帧率,有几个方向:
- 确保编译的是Release,Debug模式慢3到5倍是常态;
- 在CMake里开
-march=native类似的CPU指令集优化(MSVC对应是/arch:AVX2),OpenCV和Eigen的矩阵运算会有明显提升; - 换OpenCV的GPU模块(CUDA版本),特征提取和描述子计算能大幅加速,但需要注意Windows下CUDA版OpenCV的安装方式完全不同,整体复杂度会上升不少;
- 如果不需要可视化,可以在System构造函数里传
eViewer::NONE,省掉Pangolin的开销,能降一些延迟。
5.3 一个容易忽略的后续问题:中文路径与系统编码
这件事我必须单独提。Windows控制台默认编码是GBK,而ORB-SLAM3读取的yaml文件和数据集的路径如果包含中文,很容易出现读取失败、文件打不开之类的"灵异问题"。建议所有跟SLAM相关的路径一律用纯英文路径,不要有空格、不要有中文。如果你已经踩了这个坑,把数据集放到C:\slam_data这种目录下,很多莫名奇妙的报错会自动消失。
另外,程序运行过程中如果终端输出乱码,通常是编码问题而不是算法问题,可以在VS工程的main函数开头加:
#ifdef _WIN32 system("chcp 65001 > nul"); #endif把控制台切到UTF-8编码,日志输出正常了,排查问题时会舒服很多。
我在把整个流程跑通之后,又用这套Windows环境给一个做室内定位的团队搭了验证demo,他们不需要在产线上塞一台Linux工控机,直接用现成的Windows主机就能完成传感器验证和定位算法对比。这也是我一直觉得Windows适配这件事值得做透的原因——它把SLAM算法从"只能在Linux实验室里玩"带到了实际的Windows产品环境中,省掉的迁移成本是实打实的。
如果你也是刚开始碰ORB-SLAM3,建议第一次跑的时候不要贪多,先只跑单目EuRoC一条序列,把整条链路打通了再扩展双目和IMU。我第一次就是提交太多目标,结果报错一个接一个,反而花了更长时间定位问题。另外,建议把每一步环境配置、每个改过的文件都记录下来,这项目调完之后你会发现,你自己积攒的那份Windows适配笔记,比网上任何一份教程都管用。
本文还有配套的精品资源,点击获取