配置 GCNv2_SLAM 所需的环境并实现纯 cpu 运行项目的全过程记录。
前排提醒:本文所述安装方式只在没有显卡的虚拟机上通过了测试,有显卡的主机涉及到 CUDA 等显卡依赖项版本问题,本文可能不适用 !
1. 环境说明 GCNv2_SLAM 是比较出名的基于 RGB-D 传感器的 SLAM 系统之一,对应的论文和 github 如下:
不过,对新手不友好的一点是,项目 github 的 readme 里面并没有详细的描述如何安装依赖项和运行这个项目(毕竟论文开源代码的目标人群都是会 SLAM 的),在慕雪搜索相关资料的时候还遇到了大量水文,给本来就不太了解 opencv 和 pytorch 的我造成了更大的困扰。
不过,最终我还是搜索到了几篇写的很不错的导引文章,里面详细说明了如何在纯 CPU 环境中运行这个项目,包括安装依赖项的全过程。
本文是对上述博客的汇总和记录,同时我还将 GCNv2_SLAM 的运行环境制作成了 dockerfile,可以在支持 docker 的 linux 桌面环境中运行。该镜像只在 parallels 的 ubuntu-22.04-arm64 虚拟机中测试过,不保证对其他环境也适用。
你可以在我的 github 中找到修改过后的项目和 dockerfile 文件:github.com/musnows/GCNv2_SLAM/tree/cpu ;构建 docker 镜像和使用 docker 容器纯 cpu 运行 GCNv2 项目的引导可见:musnows/GCNv2_SLAM/docker/README 。
前期准备:
ubuntu-18.04-desktop 虚拟机或支持 docker 的 ubuntu-desktop 虚拟机; 一个能正常 clone 到 github 项目的网络环境(不然会很烦); 本文示例环境:ubuntu 22.04 arm 虚拟机下启动的 ubuntu18.04 docker 容器(套娃)。
话不多说,开整!
2. 安装依赖项 项目运行主要要手动安装 4 个依赖项,以及数不清的 apt 包。
2.1. 基础 apt 包安装 运行之前先更新一下环境
1 2 sudo apt-get update -y sudo apt-get upgrade -y
首先是要用的到的工具包(这些都用得上)
1 2 3 4 5 6 7 8 sudo apt-get install -y \ apt-utils \ curl wget unzip zip \ cmake make automake \ openssh-server \ net-tools \ vim git gcc g++
随后是 python 工具组
1 2 3 4 5 6 7 sudo apt-get install -y \ python-dev \ python-pip \ python3-dev \ python3-pip \ python-all-dev \ python3-all-dev
还需要安装 x11 相关的依赖包
1 2 3 4 5 6 7 8 sudo apt-get install -y \ libx11-xcb1 \ libfreetype6 \ libdbus-1-3 \ libfontconfig1 \ libxkbcommon0 \ libxkbcommon-x11-0
2.2. Pangolin 6.0 安装 pangolin 之前先安装如下依赖包
1 2 3 4 5 6 7 8 9 sudo apt-get install -y \ libgl1-mesa-dev \ libglew-dev \ libboost-dev \ libboost-thread-dev \ libboost-filesystem-dev \ libpython2.7-dev \ libglu1-mesa-dev freeglut3-dev
随后使用如下命令来编译安装 Pangolin,Github 地址:Pangolin-0.6 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 wget -O Pangolin-0.6.tar.gz https://github.com/stevenlovegrove/Pangolin/archive/refs/tags/v0.6.tar.gz tar -zxvf Pangolin-0.6.tar.gz pushd Pangolin-0.6 rm -rf build mkdir build && cd build cmake -DCPP11_NO_BOOST=1 .. make -j$(nproc ) make install ldconfig popd
随后使用如下命令检查是否安装成功
1 2 3 4 5 cd Pangolin-0.6/examples/HelloPangolinmkdir build && cd buildcmake .. make
一切正常的话,应该能编译成功。
1 2 3 4 5 root@ubuntu-linux-22-04-02-desktop:/work/docker/Pangolin-0.6/examples/HelloPangolin/build Scanning dependencies of target HelloPangolin [ 50%] Building CXX object CMakeFiles/HelloPangolin.dir /main.o [100%] Linking CXX executable HelloPangolin [100%] Built target HelloPangolin
随后执行./HelloPangolin
运行程序(需要在 GUI 环境中执行),如果出现了一个三色正方体的弹窗就是 ok 了
2.3. OpenCV 3.4.5 先安装依赖项
1 2 3 4 5 6 7 8 9 10 11 sudo apt --fix-broken install sudo apt-get update sudo apt-get upgrade sudo apt-get install -y \ build-essential libgtk2.0-dev libgtk-3-dev \ libavcodec-dev libavformat-dev \ libjpeg.dev libtiff5.dev libswscale-dev \ libcanberra-gtk-module \ libavresample-dev libgphoto2-dev
opencv 的依赖项 libjasper 包在 arm64 和 amd64 上有区别,如果是 amd64 环境,使用如下命令安装。命令已在 ubuntu18.04 虚拟机中测试通过,就是 security.ubuntu.com
可能会因为网络问题无法联通,多试几次就 OK 了。
1 2 3 4 5 6 7 sudo apt-get install -y software-properties-common sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" sudo apt-get -y update sudo apt-get install -y libjasper1 libjasper-dev
amd64 平台添加新软件源后,update 命令执行结果如下
1 2 3 4 5 6 7 $ sudo apt-get -y update Hit:1 http://us.archive.ubuntu.com/ubuntu bionic InRelease Hit:2 http://security.ubuntu.com/ubuntu bionic-security InRelease Hit:3 http://us.archive.ubuntu.com/ubuntu bionic-updates InRelease Hit:4 http://security.ubuntu.com/ubuntu xenial-security InRelease Hit:5 http://us.archive.ubuntu.com/ubuntu bionic-backports InRelease Reading package lists... Done
如果是 arm64 平台,使用上面的软件源会出现 404 错误,在本站另外一篇博客 中有记录。
1 2 3 4 5 6 Err:6 http://security.ubuntu.com/ubuntu xenial-security/main arm64 Packages 404 Not Found [IP: 185.125.190.83 80] Fetched 106 kB in 2s (44.6 kB/s) Reading package lists... Done E: Failed to fetch http://security.ubuntu.com/ubuntu/dists/xenial-security/main/binary-arm64/Packages 404 Not Found [IP: 185.125.190.83 80] E: Some index files failed to download. They have been ignored, or old ones used instead.
在 arm64 上需要借助老版本的清华源来安装,将如下命令写入脚本文件使用 sudo 执行。
1 2 3 4 5 6 7 8 9 10 11 12 #!/usr/bin/env bash set -eecho -e "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe\n\ deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe\n\ deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe\n\ deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-backports main multiverse restricted universe\n\ deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main multiverse restricted universe\n\ deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-security main multiverse restricted universe\n\ deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-updates main multiverse restricted universe" >> /etc/apt/sources.list && \apt-get -y update apt-get install -y libjasper1 libjasper-dev
arm64 成功安装 libjasper 的命令行输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 root@ubuntu-linux-22-04-02-desktop:/# apt-get install -y libjasper1 libjasper-dev Reading package lists... Done Building dependency tree Reading state information... Done Suggested packages: libjasper-runtime The following NEW packages will be installed: libjasper-dev libjasper1 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 613 kB of archives. After this operation, 1327 kB of additional disk space will be used. Get:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports xenial-security/main arm64 libjasper1 arm64 1.900.1-debian1-2.4ubuntu1.3 [111 kB] Get:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports xenial-security/main arm64 libjasper-dev arm64 1.900.1-debian1-2.4ubuntu1.3 [502 kB] Fetched 613 kB in 1s (758 kB/s) debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 2.) debconf: falling back to frontend: Readline Selecting previously unselected package libjasper1:arm64. (Reading database ... 67223 files and directories currently installed.) Preparing to unpack .../libjasper1_1.900.1-debian1-2.4ubuntu1.3_arm64.deb ... root@ubuntu-linux-22-04-02-desktop:/#
安装好了依赖项后,使用如下命令编译 OpenCV,Github 地址:opencv 的 3.4.5 版本 。
PS: 如下命令同样适用于安装 OpenCV 3.2.0 版本,只需要更换链接中的版本号即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 wget -O opencv-3.4.5.tar.gz https://github.com/opencv/opencv/archive/refs/tags/3.4.5.tar.gz tar -zxvf opencv-3.4.5.tar.gz pushd opencv-3.4.5 rm -rf build mkdir build && cd build cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. make -j$(nproc ) make install ldconfig popd
使用如下命令检测 opencv 是否安装成功
1 2 3 4 5 6 3.4.5 -I/usr/local/include/opencv -I/usr/local/include -L/usr/local/lib -lopencv_dnn -lopencv_ml -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core
可以试试编译测试 demo 代码,注意需要在 GUI 环境中执行
1 2 3 4 5 6 cd opencv-3.4.5/samples/cpp/example_cmakemkdir build && cd build cmake .. make ./opencv_example
如果成功运行,会弹出一个 hello opencv 的弹窗。如果你的环境有摄像头,则会出现摄像头画面,如果没有摄像头,则为黑屏画面。
如果运行这个 demo 的时候遇到了 Failed to load module "canberra-gtk-module"
错误,是因为缺少了一个软件包,安装一下就可以了(上文安装包中已经列出)。
1 sudo apt-get install libcanberra-gtk-module
如果有摄像头的时候运行./opencv_example
的时,遇到了弹窗没有弹出程序就终止,请参考博客 里面的说明尝试确认是否为 waitKey()
函数导致。
2.4. Eigen 3.7 Eigen 包在 gitlab 里面下载:gitlab.com/libeigen/eigen/-/releases/3.3.7
1 2 3 4 5 6 7 8 9 wget -O eigen-3.3.7.tar.gz https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz tar -zxvf eigen-3.3.7.tar.gz cd eigen-3.3.7mkdir build && cd buildcmake .. make make install
注意需要执行 cp 命令拷贝一下头文件到另外一个目录中
1 2 3 4 sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include
这里给出一个 cpp 的 demo 代码来测试是否安装成功(直接 g++ 编译就可以了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <Eigen/Dense> using namespace Eigen;using namespace Eigen::internal;using namespace Eigen::Architecture;using namespace std;int main () { cout<<"*******************1D-object****************" <<endl; Vector4d v1; v1<< 1 ,2 ,3 ,4 ; cout<<"v1=\n" <<v1<<endl; VectorXd v2 (3 ) ; v2<<1 ,2 ,3 ; cout<<"v2=\n" <<v2<<endl; Array4i v3; v3<<1 ,2 ,3 ,4 ; cout<<"v3=\n" <<v3<<endl; ArrayXf v4 (3 ) ; v4<<1 ,2 ,3 ; cout<<"v4=\n" <<v4<<endl; }
运行结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 root@ubuntu-linux-22-04-02-desktop:/work/docker/pkg/eigen-3.3.7/build root@ubuntu-linux-22-04-02-desktop:/work/docker/pkg/eigen-3.3.7/build *******************1D-object**************** v1= 1 2 3 4 v2= 1 2 3 v3= 1 2 3 4 v4= 1 2 3
2.5. Pytorch 1.0.1 (libtorch) 原博客中安装的是 1.4.0,但是在我测试的 arm 环境中 1.4.0 有非常多的错误,这里直接采用 GCNv2 Github 中给出的 1.0.1 版本进行安装。
安装之前需要保证环境中有 python3(测试环境为 3.6.9)并安装 pyyaml 包
1 2 sudo apt-get install python3-dev python3-pip pip3 install pyyaml
随后克隆 pytorch 并编译 libtorch 动态库
1 2 3 git clone --recursive -b v1.0.1 https://github.com/pytorch/pytorch cd pytorch && mkdir build && cd buildpython3 ../tools/build_libtorch.py
这里就有难题啦!整个 pytorch 的库加上 sub-modules 一共有 3gb 之大,要想从 github 上安稳克隆下来可不简单。这里给大家分享一个百度云盘的链接,是所有子模组都被成功 clone 之后的压缩包。
1 2 通过网盘分享的文件:pytorch.full.1.0.1.tar.gz 链接: https://pan.baidu.com/s/1XHeYcHH5CMKmacFodFzqeA 提取码: 4h2g
下载了这个压缩包,使用 tar -zxvf
解压后,使用如下命令检查一下子模组是否完整,如果完整的话这个命令不会有任何输出。不完整它会继续下载子模组
1 git submodule update --init --recursive
在执行 python3 ../tools/build_libtorch.py
之前还需要进行两处代码的修改,这里直接给出 sed 命令,在 pytorch 库的根目录执行。
1 2 sed -i "s/yaml.load(\(.*\))/yaml.load(\1, Loader=yaml.FullLoader)/g" aten/src/ATen/cwrap_parser.py sed -i "s/yaml.load(\(.*\))/yaml.load(\1, Loader=yaml.FullLoader)/g" tools/cwrap/cwrap.py
两个代码文件中都只有一处要修改的地方,分别是 pytorch/tools/cwrap/cwrap.py
文件里面的 91 行和 pytorch/aten/src/ATen/cwrap_parser.py
的 18 行。
这里的修改是因为 pyyaml 库的变动(环境中安装的 pyyaml 版本为 6.0.1),需要传入第二个参数 Loader。原有的代码是没有传入的,编译的时候会出现如下错误,日志中的重点就是 TypeError: load() missing 1 required positional argument: 'Loader'
缺少参数的报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Traceback (most recent call last): File "/work/pytorch/cmake/../aten/src/ATen/gen.py", line 465, in <module> generate_outputs() File "/work/pytorch/cmake/../aten/src/ATen/gen.py", line 390, in generate_outputs for file in cwrap_files File "/work/pytorch/cmake/../aten/src/ATen/gen.py", line 391, in <listcomp> for d in cwrap_parser.parse(file)] File "/work/pytorch/aten/src/ATen/cwrap_parser.py", line 18, in parse declaration = yaml.load('\n'.join(declaration_lines)) TypeError: load() missing 1 required positional argument: 'Loader' caffe2/CMakeFiles/ATEN_CPU_FILES_GEN_TARGET.dir/build.make:132: recipe for target 'aten/src/ATen/CPUByteType.cpp' failed make[2]: *** [aten/src/ATen/CPUByteType.cpp] Error 1 CMakeFiles/Makefile2:3522: recipe for target 'caffe2/CMakeFiles/ATEN_CPU_FILES_GEN_TARGET.dir/all' failed make[1]: *** [caffe2/CMakeFiles/ATEN_CPU_FILES_GEN_TARGET.dir/all] Error 2 make[1]: *** Waiting for unfinished jobs.... [ 15%] Building CXX object third_party/protobuf/cmake/CMakeFiles/libprotobuf.dir/__/src/google/protobuf/wrappers.pb.cc.o [ 15%] Linking CXX static library ../../../lib/libprotobuf.a [ 15%] Built target libprotobuf Makefile:140: recipe for target 'all' failed make: *** [all] Error 2 Traceback (most recent call last): File "../tools/build_libtorch.py", line 30, in <module> subprocess.check_call(command, universal_newlines=True, env=my_env) File "/usr/lib/python3.6/subprocess.py", line 311, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['/work/pytorch/tools/build_pytorch_libs.sh', '--use-nnpack', '--use-qnnpack', 'caffe2']' returned non-zero exit status 2.
说实话,个人认为 pyyaml 库的这个变动非常不合理,版本更迭后,一个强制需要传入的参数应该给出缺省值才对。如果它给出了缺省值,那么这里的代码即便没有传入也不会报错了。
修改了这两处代码后,执行 python3 ../tools/build_libtorch.py
,不出意外的话编译就成功啦。
原博主使用的 pytorch 1.4.0 需要解决的问题比我这里更多,如果你想通过 pytorch 1.4.0 来编译 libtorch,请参考本文最开头贴出的博客。
3. 编译 GCNv2_SLAM 接下来我们就可以编译正主啦!首先克隆代码
1 git clone https://github.com/jiexiong2016/GCNv2_SLAM.git
3.1. 修改 build.sh 编译项目 修改项目根目录下的 build.sh,将 TORCH_PATH
修改为 pytorch 中的 torch/lib/tmp_install/share/cmake/Torch
目录。
1 cmake .. -DCMAKE_BUILD_TYPE=Release -DTORCH_PATH=/work/gcnv2slam/pytorch/torch/lib/tmp_install/share/cmake/Torch
修改了之后,应该就可以执行./build.sh
来编译项目了。
比较奇怪的是我的环境中并没有 cuda 也依旧能在不修改任何代码的情况下编译成功。
最开始的时候,我遇到了一个难题,参考的博客中大多数都用的 pytorch 1.4.0,里面都提到了修改 TORCH_PATH
为 pytorch/torch/share/cmake/Torch
目录,但是在我的 pytorch 1.0.1 里面压根没有这个目录。
本来都要放弃了,最终在 GCNv2 项目的 github 里面找到了说明,主要的修改点是 jiexiong2016/GCNv2_SLAM/commit/21cc44894 这一笔提交,readme 里面描述如下
The built libtorch library is located at pytorch/torch/lib/tmp_install/
in default.
Update: Have added support for master branch of pytorch or version larger than 1.0.1. For newer version, set TORCH_PATH
to pytorch/torch/share/cmake/Torch
说白了就是在 1.0.1 版本中的 TORCH_PATH
是在 pytorch/torch/lib/tmp_install/
里面的,更新的 pytorch 版本是在 pytorch/torch/share
目录,而 1.0.1 版本中不存在 pytorch/torch/share
目录。
3.2. 修改代码来实现纯 CPU 运行 第一处修改点在 GCNv2_SLAM/src/GCNextractor.cc
文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const char *net_fn = getenv ("GCN_PATH" );net_fn = (net_fn == nullptr ) ? "gcn2.pt" : net_fn; module = torch::jit::load (net_fn);torch::DeviceType device_type; device_type = torch::kCPU; torch::Device device (device_type) ;const char *net_fn = getenv ("GCN_PATH" );net_fn = (net_fn == nullptr ) ? "gcn2.pt" : net_fn; module = torch::jit::load (net_fn,device);device_type = torch::kCUDA; device_type = torch::kCPU;
修改后的截图如下
3.2.2. 修改 GCN2 下 pt 文件 其实 pt 文件是不影响编译的,可以在编译完成后再修改
修改 GCNv2_SLAM/GCN2
下 gcn2_320x240.pt、gcn2_640x480.pt 和 gcn2_tiny_320x240.pt 中的内容。需要先解压文件
解压出来之后会有 GCNv2_SLAM/GCN2/gcn/code/gcn.py
文件,将里面的 cuda:0
修改成 cpu
,批量替换就可以了,每个文件里面都是 8 处。
替换了之后,重新压缩 pt 文件,先删了原本的,重新压缩
1 2 3 rm -rf gcn2_320x240.ptzip -r gcn2_320x240.pt gcn rm -rf gcn
这只是一个例子,其他几个 gcn2 压缩包都要用相同的方式修改!
1 2 3 4 5 6 7 unzip gcn2_640x480.pt rm -rf gcn2_640x480.ptzip -r gcn2_640x480.pt gcn2_480x640 rm -rf gcn2_480x640
1 2 3 4 5 6 7 unzip gcn2_tiny_320x240.pt rm -rf gcn2_tiny_320x240.ptzip -r gcn2_tiny_320x240.pt gcn2_tiny rm -rf gcn2_tiny
3.2.3. 重新编译 修改之后重新编译项目,先删除原有的编译缓存
1 2 3 4 rm -rf Thirdparty/g2o/build/rm -rf Thirdparty/DBoW2/build/rm -rf Vocabulary/*.binrm -rf ./build
没有问题,编译成功了。
1 2 3 4 5 6 7 8 9 10 11 12 Configuring and building ORB_SLAM2 ... mkdir: cannot create directory 'build': File exists Build type: Release -- Using flag -std=c++11. TORCH_PATH set to: /work/gcnv2slam/pytorch/torch/lib/tmp_install/share/cmake/Torch -- Torch version is: 1.0.0 -- Configuring done -- Generating done -- Build files have been written to: /work/gcnv2slam/GCNv2_SLAM/build [ 91%] Built target ORB_SLAM2 [100%] Built target rgbd_gcn root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM#
4. 使用 TUM 训练集运行项目 4.1. 下载数据集 下载地址:cvg.cit.tum.de/data/datasets/rgbd-dataset/download
下载 fr1/desk
数据集,这是一个桌子的 RGBD 数据
在 GCNv2_SLAM 工程下新建 datasets/TUM
, 将数据集下载到其中
1 2 3 4 5 6 7 mkdir -p datasets/TUM cd datasets/TUMwget -O rgbd_dataset_freiburg1_desk.tgz https://cvg.cit.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_desk.tgz tar -xvf rgbd_dataset_freiburg1_desk.tgz
然后还需要下载一个 associate.py
脚本来处理一下数据集才能正常运行
下载地址:svncvpr.in.tum.de ,同时在我的 Github 仓库 也做了留档。
1 wget -O associate.py https://svncvpr.in.tum.de/cvpr-ros-pkg/trunk/rgbd_benchmark/rgbd_benchmark_tools/src/rgbd_benchmark_tools/associate.py
这个脚本只能用 python2 运行,需要下载 numpy 库(环境中 python2 是 2.7.17)
1 2 3 4 5 apt-get install -y python-pip pip install numpy python associate.py rgbd_dataset_freiburg1_desk/rgb.txt rgbd_dataset_freiburg1_desk/depth.txt > rgbd_dataset_freiburg1_desk/associate.txt
注意下载 numpy 库的时候不要用镜像源,否则无法安装。直接下就行了。
1 2 3 4 5 6 7 8 9 10 root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM/datasets/TUM# pip install numpy Collecting numpy Downloading https://files.pythonhosted.org/packages/b7/6f/24647f014eef9b67a24adfcbcd4f4928349b4a0f8393b3d7fe648d4d2de3/numpy-1.16.6.zip (5.1MB) 100% |################################| 5.2MB 470kB/s Building wheels for collected packages: numpy Running setup.py bdist_wheel for numpy ... done Stored in directory: /root/.cache/pip/wheels/cb/c2/c1/d99e8bf789c8dd07623af6be95e6a89984c85a05e31b8513c3 Successfully built numpy Installing collected packages: numpy Successfully installed numpy-1.16.6
执行 python 命令后可以看看合并成功了没有,如下应该就是没问题了。
1 2 3 4 5 root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM/datasets/TUM# python associate.py rgbd_dataset_freiburg1_desk/rgb.txt rgbd_dataset_freiburg1_desk/depth.txt > rgbd_dataset_freiburg1_desk/associate.txt root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM/datasets/TUM# tail rgbd_dataset_freiburg1_desk/associate.txt 1305031472.895713 rgb/1305031472.895713.png 1305031472.892944 depth/1305031472.892944.png 1305031472.927685 rgb/1305031472.927685.png 1305031472.924814 depth/1305031472.924814.png 1305031472.963756 rgb/1305031472.963756.png 1305031472.961213 depth/1305031472.961213.png
在同一个网站下载的其他数据集也需要用相同的方式进行处理
4.2. 运行 GCN2 随后进入项目的 GCN2 目录执行命令,我把命令中的路径都改成了相对路径
1 2 cd GCN2GCN_PATH=gcn2_320x240.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3_small.yaml ../datasets/TUM/rgbd_dataset_freiburg1_desk ../datasets/TUM/rgbd_dataset_freiburg1_desk/associate.txt
如果运行 tiny 数据集,命令如下
1 2 cd GCN2GCN_PATH=gcn2_tiny_320x240.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3_small.yaml ../datasets/TUM/rgbd_dataset_freiburg1_desk ../datasets/TUM/rgbd_dataset_freiburg1_desk/associate.txt
在 mac 上虚拟机安装的 arn 版本 ubuntu22.04 中用 docker 安装的 ubuntu18.04 成功运行本项目,虽然很卡,但是运行起来了!
最终结束后的输出如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM# cd GCN2/ root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM/GCN2# GCN_PATH=gcn2_320x240.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3_small.yaml ../datasets/TUM/rgbd_dataset_freiburg1_desk ../datasets/TUM/rgbd_dataset_freiburg1_desk/associate.txt ORB-SLAM2 Copyright (C) 2014-2016 Raul Mur-Artal, University of Zaragoza. This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions. See LICENSE.txt. Input sensor was set to: RGB-D Loading ORB Vocabulary. This could take a while... Vocabulary loaded! Camera Parameters: - fx: 267.7 - fy: 269.6 - cx: 160.05 - cy: 123.8 - k1: 0 - k2: 0 - p1: 0 - p2: 0 - fps: 30 - color order: RGB (ignored if grayscale) ORB Extractor Parameters: - Number of Features: 1000 - Scale Levels: 8 - Scale Factor: 1.2 - Initial Fast Threshold: 20 - Minimum Fast Threshold: 7 Depth Threshold (Close/Far Points): 5.97684 ------- Start processing sequence ... Images in the sequence: 573 New map created with 251 points Finished! ------- median tracking time: 1.7969 mean tracking time: 1.82306 Saving camera trajectory to CameraTrajectory.txt ... trajectory saved! Saving keyframe trajectory to KeyFrameTrajectory.txt ... trajectory saved! root@ubuntu-linux-22-04-02-desktop:/work/gcnv2slam/GCNv2_SLAM/GCN2#
同时我在 vmware16 安装的 ubuntu18.04 虚拟机中也运行了本项目,速度更慢。宿主机配置为牙膏厂的 i5-10400+16GB 内存,虚拟机分配了 8 核 8GB。
4.3. 简单分析一下结果 在 mac m3 16G 上 parallels 安装的 arm64 版本 ubuntu22.04 虚拟机(4 核 8G)中用 docker 运行的 ubuntu18.04 容器,容器内运行 gcn2_320x240.pt
的速度如下,约合 0.55hz
1 2 median tracking time: 1.7969 mean tracking time: 1.82306
在 vmware16 安装的 amd64 版本 ubuntu18.04 的虚拟机(8 核 8G)中,运行 gcn2_320x240.pt
的速度如下,约合 0.21hz。没想到比 arm 的速度还慢!
1 2 median tracking time: 4.70296 mean tracking time: 4.62603
作为对比,GCNv2 论文中提到了两个平台的运行结果,翻译如下
“GCNv2 和我们改进了 SLAM 方法的 GCN-SLAM,在配备 Intel i7-7700HQ 和移动版 NVIDIA 1070 的笔记本电脑上运行约 80 Hz。为了实现更高的帧率,以满足 Jetson TX2 上实时推理的需求,我们引入了 GCNv2 的一个较小版本,称为 GCNv2-tiny,在此版本中,我们从 conv2 开始将特征图的数量减少了一半。GCNv2-tiny 运行在 40 Hz,使用 GCNv2-tiny 的 GCN-SLAM 在 TX2 上运行为 20 Hz,非常适合部署在无人机上。”
只能说纯 CPU 运行的效果也太差了!应该是因为 GCNv2_SLAM 项目有用到神经网络,所以没有显卡的话速度会非常慢。
5. The end 折腾了好几天,才成功把 GCNv2_SLAM 需要的环境给配置好,可惜 GCNv2 用到了深度神经网络,在没有 GPU 的环境下纯 CPU 运行的效果太差了,不知道有没有办法优化一下。
另外,我似乎没搜到 GCNv2_SLAM 在较新一点的带 N 卡的电脑(比如 30 系以后的 N 卡)中运行的教程博客 ,如果想用 GPU 来运行一下本项目,估计又是一个大麻烦事……
更新:慕雪已在 AutoDL 云平台的 2080ti 显卡容器化环境中成功运行了 GCNv2_SLAM,效果远好于本地 CPU 运行,详见【SLAM】于 AutoDL 云上 GPU 运行 GCNv2_SLAM 的记录 。