《视觉SLAM十四讲》slambook2配置和编译记录
最近有时间重拾《SLAM14讲》这本经典SLAM入门书。作者高老师提供了书中的整套习题和示例代码[https://github.com/gaoxiang12/slambook2]。
因为时间久远(当前2025年6月),书本推荐的系统是ubuntu14,我的系统是ubuntu22.04,可能不支持老版本的第三方库了,所以我基本采用新版的第三方库,配置和编译的时候遇到了一些问题。
现在从一个全新的系统开始配置:
1. 安装依赖库

主要是slambook2/3rdparty/ 提供的第三方库,还有这些库的依赖库。
全部从源码编译安装:
# 安装示例
git clone https://github.com/RainerKuemmerle/g2o.git
cd g2o && mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
Tips:
- 编译安装以前最好先切换到某个稳定版本,因为有的库安装时需要明确其依赖库的版本(例如Ceres 的配置文件 CeresConfig.cmake 在生成过程中需要知道你使用的 Abseil 库的版本号,后面会提到)。
具体方法如下:git tag // 查看tag git checkout tags/20240116 -b version-20240116 //-b <新建分支名字>
- Sophus库使用新版本会在编译到25%时死机,所以用的slambook2推荐sophus-13fb328。
- opencv安装,采用官方文档,直接安装最新版的opencv和opencv-contrib。
- 使用apt安装pcl/libepoxy 库。
2. 代码适配
1. g2o::make_unique 全部替换成std::make_unique。
2. 由于 OpenCV 4.x 版本中,常量名发生了变化,创建替换脚本update_opencv_constants.sh将部分旧的常量名替换为新的常量名:
#!/bin/bash
# 定义要搜索和替换的目录
SEARCH_DIR="/home/koap/workspace/slambook2"
# 替换旧的常量名
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_LOAD_IMAGE_COLOR/IMREAD_COLOR/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_LOAD_IMAGE_GRAYSCALE/IMREAD_GRAYSCALE/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_LOAD_IMAGE_UNCHANGED/IMREAD_UNCHANGED/g'
echo "Constants have been updated to OpenCV 4.x style."
# 替换所有 .cpp 文件中的旧常量
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_FM_8POINT/cv::FM_8POINT/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_FM_RANSAC/cv::FM_RANSAC/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_FM_LMEDS/cv::FM_LMEDS/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_BGR2GRAY/cv::COLOR_GRAY2BGR/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_GRAY2BGR/cv::COLOR_BGR2GRAY/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_BGR2RGB/cv::COLOR_BGR2RGB/g'
find $SEARCH_DIR -type f -name "*.cpp" | xargs sed -i 's/CV_FILLED/cv::FILLED/g'
echo "✅ OpenCV FM constants updated to OpenCV 4.x style."
3. 编译/安装/运行中的报错
1.
CMake Error at cmake_install.cmake:46 (message):
Cannot generate CeresConfig.cmake due to missing Abseil version. Using
resulting package configuration will likely result in integration errors.
Set absl_VERSION manually to disable this error message.
- 原因分析:ceres-solver安装时报错,Ceres 的配置文件 CeresConfig.cmake 在生成过程中需要知道使用的 Abseil 库的版本号。
- 解决办法:在确认好absl的版本后,在ceres的cmake时添加:
cmake .. -Dabsl_VERSION=20230802
2.
error: invalid use of incomplete type ‘PyFrameObject’
- 原因分析:这个错误发生在使用 pybind11 的代码中,尤其是在与 Python 3.13(Miniconda)结合时。这是一个典型的 Python 3.12+ 中引入的“受限头文件”机制 导致的问题。
- 解决方法:将环境中的python降级到3.11解决。
3.
error: ‘enable_if_t’ is not a member of ‘std’
高频次问题!
- 原因分析:这个错误表明代码中使用了 std::enable_if_t,但编译器(C++11)无法识别它。std::enable_if_t 是 C++14 引入的模板别名(alias template),用于 SFINAE(替换失败并非错误)机制。
- 解决方法:在CMakeLists.txt中指定使用高版本的C++编译器:(推荐17+)
set(CMAKE_CXX_FLAGS "-std=c++17")
4.
/usr/bin/ld: /usr/local/lib/libabsl_log_internal_log_sink_set.a(log_sink_set.cc.o):
relocation R_X86_64_TPOFF32 against '_ZZN4absl12lts_2024011612log_internal...`'
can not be used when making a shared object; recompile with -fPIC
- 原因分析:编译opencv时,依赖于 Abseil 库。系统中安装的 Abseil 是以静态库形式存在,但这些静态库没有使用 -fPIC 编译,因此不能被用来构建共享库(.so 文件),比如 OpenCV 的模块 opencv_sfm.so。
- 解决方法:重新构建 Abseil 动态库,并启用 -fPIC. 在cmake时添加:
cmake .. -DBUILD_SHARED_LIBS=ON \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_BUILD_TYPE=Release
5.
error while loading shared libraries: libpango_windowing.so.0: cannot open shared object file: No such file or directory
- 原因分析:已经安装了pangolin,在/usr/local/lib/下能找到libpango_windowing.so.0,在但是报libpango_windowing.so.0找不到。
- 解决方法:更新动态链接器缓存。
sudo ldconfig
6.
CMake 3.24 or higher is required. You are running version 3.22.1
- 原因分析:某些库需要高版本的CMake,但是apt里面版本比较旧。
- 解决方法:使用snap安装cmake,将路径添加到PATH第一位使其成为默认的cmake。
sudo snap install cmake --classic
export PATH=/snap/bin:$PATH
7.
/home/koap/miniconda3/include/spdlog/fmt/fmt.h:27:14: fatal error: spdlog/fmt/bundled/core.h: No such file or directory
27 | # include <spdlog/fmt/bundled/core.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
- 原因分析:我最初没有重新装spdlog,而是将miniconda中已有的libspdlog.so软链接了在/usr/lib中,该spdlog不是完整的,没有自带的fmt。
- 解决方法:
1) 从源码编译安装spdlog。
或者
2) 使用外部的fmt,在CMakeLists.txt中添加声明:
add_definitions(-DSPDLOG_FMT_EXTERNAL)
8.
/home/koap/miniconda3/lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /usr/local/lib/libopencv_core.so.411)
- 原因分析:程序在运行时尝试加载 /usr/local/lib/libopencv_core.so.411,这个库 需要更新版本的 libstdc++(GCC 的 C++ 标准库),但当前环境中优先使用了 Miniconda 自带的老版本 libstdc++(缺少 GLIBCXX_3.4.30)。
- 解决方法:强制使用系统自带的 libstdc++:
# 可以加到~/.bashrc
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
9.
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.11.0) ... error: (-15:Bad number of channels)
Invalid number of channels in input image:
'VScn::contains(scn)' where 'scn' is 1
- 原因分析:调用cv::imread(
, 0)去读取图像(是单通道图), 又调用cv::cvtColor时报错,因为但该函数期望的是一个 三通道或四通道图像(彩色图)。 - 解决方法:报错处的cv::imread(
, 0)改成cv::imread( )。
10.
CMake Error at CMakeLists.txt:11 (find_package):
Found package configuration file:
/usr/local/lib/cmake/Ceres/CeresConfig.cmake
but it set Ceres_FOUND to FALSE so package "Ceres" is considered to be NOT FOUND.
Reason given by package:
Found Eigen dependency, but the version of Eigen found () does not exactly match the version of Eigen Ceres was compiled with (3.4.0).
- 原因分析:安装的 Ceres Solver 是使用 Eigen 3.4.0 编译的,与当前系统中找到的 Eigen 版本不一致。但其实系统的eigen版本就是3.4.0 。应该是ceres识别不到apt安装的eigen的版本号?(所以从源码安装最好自己指定版本,减少这类的报错)
- 解决方法:从源码重新安装eigen和ceres,指定版本号。
wget https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
tar -xzf eigen-3.4.0.tar.gz
cd eigen-3.4.0
mkdir build && cd build
cmake ..
sudo make install
git clone https://github.com/ceres-solver/ceres-solver.git
cd ceres-solver
git checkout <tag-or-commit-id> # 推荐使用稳定版本如 2.1.0
mkdir build && cd build
cmake .. \
-DEIGEN_INCLUDE_DIR=/usr/local/include/eigen3 \ # 直接指定EIGEN路径
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTING=OFF
make -j$(nproc)
sudo make install
11.
undefined reference to 'g2o::csparse::CSparse::CSparse()'
undefined reference to 'g2o::csparse::CSparse::freeSymbolic()'
- 原因分析:缺少 g2o_solver_csparse 这个库。g2o::csparse::CSparse ,g2o::csparse::CSparse::freeSymbolic()和 g2o::LinearSolverCSparse 的实现就在 libg2o_solver_csparse.so 或 .a 里。
- 解决方法:在ch9的CMakeLists.txt添加g2o_solver_csparse:
# ...existing code...
SET(G2O_LIBS g2o_csparse_extension g2o_stuff g2o_core g2o_solver_csparse cxsparse g2o_solver_cholmod)
# ...existing code...
12. ch10, 运行./pose_graph_g2o_lie sphere.g2o 时
Sophus ensure failed in function 'void Sophus::SO3Base
::normalize() [with Derived = Sophus::SO3 ]', file '/usr/local/include/sophus/so3.hpp', line 273.
Quaternion ( 0.706662 4.32706e-17 0.707551 -4.3325e-17) should not be close to zero!
Aborted (core dumped)
- 原因分析:这个错误是 Sophus 库中的一个运行时断言(assert)触发,说明程序中某个 SO3 或 SE3 的四元数构造或旋转操作导致了一个接近零向量的非法单位四元数。
read函数漏写了return true;,导致C++返回未定义值,导致后续出错:四元数归一化失败导致的崩溃。 - 解决方法:确保 read 函数有 return true; 确认四元数顺序与 g2o 文件一致。
13. ch11, 安装DBow3
- 原因分析:由于版本太老,编译报错。
- 解决方法:
CMakeLists.txt:
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
检查并补全 BowVector.h 的头部:
#pragma once
#include <map>
#include <iterator>
#include <ostream>
#include <string>
#include <cstdint>
#include <cstddef>
14. ch12, PCL相关
/home/koap/workspace/slambook2/ch12/dense_RGBD/surfel_mapping.cpp: In function ‘SurfelCloudPtr reconstructSurface(const PointCloudPtr&, float, int)’:
/home/koap/workspace/slambook2/ch12/dense_RGBD/surfel_mapping.cpp:31:9: error: ‘class pcl::MovingLeastSquares<pcl::PointXYZRGB, pcl::PointXYZRGBNormal>’ has no member named ‘setPolynomialFit’; did you mean ‘setPolynomialOrder’?
31 | mls.setPolynomialFit(polynomial_order > 1);
| ^~~~~~~~~~~~~~~~
| setPolynomialOrder
-
原因分析:PCL 1.12 及以后版本中,setPolynomialFit 方法已被移除或重命名。现在只需设置 setPolynomialOrder。
-
解决方法:直接删除或注释掉 mls.setPolynomialFit(...) 这一行,只保留 mls.setPolynomialOrder(polynomial_order); 即可。
15. ch12, 运行./dense_mapping test_data/ 时报错
read total 202 files.
*** loop 1 ***
Segmentation fault (core dumped)
- 原因分析:update函数为定义为bool类型,但是没有返回值。
- 解决方法:可以改为void,或者添加返回值 return true;
运行以后,生成了一个全黑的图,解决方法:https://github.com/gaoxiang12/slambook2/issues/323
16. ch12, 运行./pointcloud_mapping 时报错
(base) koap@koap:~/workspace/slambook2/ch12/dense_RGBD$ ./pointcloud_mapping
正在将图像转换为点云...
转换图像中: 1
Segmentation fault (core dumped)
- 原因分析:
在CMakeLists.txt中,我把set(CMAKE_CXX_FLAGS "-std=c++17 -02")写成了set(CMAKE_CXX_FLAGS "-std=c++17 -march=native -O3")。
-march=native 导致了某些库(如 OpenCV、PCL、Eigen)或你自己代码中对内存访问/向量化操作的行为变化,从而导致崩溃。 - 解决方法:去掉 -march=native 后,程序能正常运行,因为编译器会生成更通用的代码,兼容性更好。 谨慎使用!

浙公网安备 33010602011771号