GCN-SLAM2复现

配置环境

环境要求

ubuntu 18.04

能够运行orb-slam2的库环境。

有git


环境准备

查看gcc和g++的版本:

g++ --version
gcc --version

因为c++17需要gcc-9和g+±9以及以上的版本,如果你不是则执行下列代码来换版本:

#安装gcc-9和g++-9
sudo apt-get update
sudo apt-get install gcc-9 g++-9
#更新默认版本:使用 update-alternatives 命令来更新系统默认的 GCC 和 G++ 版本
首先,添加新的 GCC 和 G++ 版本到 update-alternatives 系统中:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 70
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90
选择默认版本:通过 update-alternatives 命令来选择默认版本
sudo update-alternatives --config gcc
你会看到类似如下的输出:
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc-9    90        auto mode
  1            /usr/bin/gcc-7    70        manual mode
  2            /usr/bin/gcc-9    90        manual mode

Press <enter> to keep the current choice[*], or type selection number:
选2
--------------------------------------------------------------------------
然后,选择默认的 G++ 版本:
sudo update-alternatives --config g++
然后出现以下:
There are 2 choices for the alternative g++ (providing /usr/bin/g++).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/g++-9    90        auto mode
  1            /usr/bin/g++-7    70        manual mode
  2            /usr/bin/g++-9    90        manual mode

Press <enter> to keep the current choice[*], or type selection number:
选2
------------------------------------------------------------------------
然后验证一下:
gcc --version
g++ --version


安装libtorch

注:在Libtorch下载时,有两个版本: Pre-cxx11 ABI 和 cxx11- ABI, 需要下载cxx11- ABI,否则会和其他库冲突(pangolin, DBOW)

我们需要根据我们系统的glibc来安装libtorch的版本,由于我是在虚拟机里跑的,所以用CPU版本的。

先检查我们安装的glibc版本:

ldd --version

我的glibc 版本为 2.27 的系统,推荐安装 libtorch 1.6.0 或更早的版本(这里我下载的是1.6.0)

下载libtorch

将下载的解压到一个位置,后面这个位置需要写在CMakeLists.txt和build.sh文件里面


安装代码

mkdir gcnslam
cd  gcnslam
git clone https://github.com/jiexiong2016/GCNv2_SLAM.git

拔下来之后先要修改CMakeLists.txt和部分文件,具体修改如下:

文件GCNextractor.h 和GCNextractor.cpp修改如下:

可以直接替换掉文件的内容。

//99行
//原
std::shared_ptr<torch::jit::script::Module> module;
//改为
torch::jit::script::Module module;
//270行
//原
auto output = module->forward(inputs).toTuple();
//改为
auto output = module.forward(inputs).toTuple();
//218改为
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);
 
//使用全局搜索,将torch::kCUDA替换为torch::kCPU。有两个地方,具体情况可能不一样。我看别的人说只有一个

文件CMakeLists.txt修改如下:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(ORB_SLAM2)

SET(CMAKE_BUILD_TYPE Release)
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")

# Check C++17, C++11, or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)  # 添加对 C++17 的检查
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)

if(COMPILER_SUPPORTS_CXX17)  # 优先使用 C++17
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
   add_definitions(-DCOMPILEDWITHC17)
   message(STATUS "Using flag -std=c++17.")
elseif(COMPILER_SUPPORTS_CXX11)  # 然后使用 C++11
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
   add_definitions(-DCOMPILEDWITHC11)
   message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X)  # 最后使用 C++0x
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
   add_definitions(-DCOMPILEDWITHC0X)
   message(STATUS "Using flag -std=c++0x.")
else()
   message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 or C++17 support. Please use a different C++ compiler.")
endif()

LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
   find_package(OpenCV 2.4.3 QUIET)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
   endif()
endif()

find_package(Eigen3 3.1.0 REQUIRED)
find_package(Pangolin REQUIRED)
set(TORCH_PATH "PATH/libtorch/share/cmake/Torch")##这里填写的是前面解压的路径
if( TORCH_PATH ) 
   message("TORCH_PATH set to: ${TORCH_PATH}")
   set(Torch_DIR ${TORCH_PATH})
else()
   message(FATAL_ERROR "Need to specify Torch path, e.g., pytorch/torch/share/cmake/Torch ")
endif()

find_package(Torch REQUIRED)
message(STATUS "Torch version is: ${Torch_VERSION}")
if(Torch_VERSION GREATER 1.0.1)
   message(STATUS "Torch version is newer than v1.0.1, will use new api")
   add_definitions(-DTORCH_NEW_API)
endif()

include_directories(
  ${PROJECT_SOURCE_DIR}
  ${PROJECT_SOURCE_DIR}/include
  ${EIGEN3_INCLUDE_DIR}
  ${Pangolin_INCLUDE_DIRS}
)

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)

add_library(${PROJECT_NAME} SHARED
    src/System.cc
    src/Tracking.cc
    src/LocalMapping.cc
    src/LoopClosing.cc
    src/ORBextractor.cc
    src/GCNextractor.cc
    src/ORBmatcher.cc
    src/FrameDrawer.cc
    src/Converter.cc
    src/MapPoint.cc
    src/KeyFrame.cc
    src/Map.cc
    src/MapDrawer.cc
    src/Optimizer.cc
    src/PnPsolver.cc
    src/Frame.cc
    src/KeyFrameDatabase.cc
    src/Sim3Solver.cc
    src/Initializer.cc
    src/Viewer.cc
)

target_link_libraries(${PROJECT_NAME}
    ${OpenCV_LIBS}
    ${EIGEN3_LIBS}
    ${Pangolin_LIBRARIES}
    ${TORCH_LIBRARIES}
    ${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
    ${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/GCN2)
add_executable(rgbd_gcn GCN2/rgbd_gcn.cc)
target_link_libraries(rgbd_gcn ${PROJECT_NAME} ${TORCH_LIBRARIES})
set_property(TARGET rgbd_gcn PROPERTY CXX_STANDARD 17)  # 修改为 C++17 标准

关于gcn2_320x240.pt (其他pt文件同理)

双击打开gcn2_320x240.pt (其他pt文件同理)(无需解压)/gcn/code/'下找到 ‘gcn.py’

这是因为1.3以前默认true 1.3以后默认false,这里我能是1.6,所以也要改

_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0))

改为

_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0, True))

# 所有的cuda:0替换为cpu

关于文件LoopClosing.c

#:439:21:
KeyFrameAndPose CorrectedSim3, NonCorrectedSim3;进入这个函数的定义里面
将    
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
        Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;
改为:
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
       Eigen::aligned_allocator<std::pair<KeyFrame *const, g2o::Sim3> > > KeyFrameAndPose;

关于rgbd_gcn.cc文件

在文件前面加上:

#define COMPILEDWITHC11


下载数据集

下载地址:Computer Vision Group - Dataset Download

随便选一个,我下载的是fr3/long_office_household,将其解压缩到/home/chan/GCNv2_SLAM/datasets/TUM中(就是自己建个TUN文件夹,这个路径很重要,之后需要用到)

解压后里面包含一个depth.txt和一个rgb.txt两个用来保存filename的文件,代码是通过filename从文件夹里读取的图像。但是在GCN的run.sh启动文件里,启动参数传入的是association.txt,经过翻看了一下ORB的一些传入参数,发现这里传入的association.txt应该是上面rgb.txt与depth.txt合并的结果,所以用一个函数来完成
创建一个associate.py,其内容如下:

def split_line(f_rgbd):
    rgbd_split = f_rgbd.read().split()
    index_to_delete = []
    for i in range(len(rgbd_split)):
        if i%2:
            index_to_delete.append(i)
    count = 0
    for index in index_to_delete:
        index = index - count
        rgbd_split.pop(index)
        count += 1
    return rgbd_split
 
def near_time_stamp(rgb_time_stamp, depth_time_stamp):
    """
    假设len(rgb_time_stamp)  >  len(depth_time_stamp)
    只需在rgb_time_stamp中取出len(depth_time_stamp)个元素即可
    """
    near_rgb_stamp = []
    for index in depth_time_stamp:
        min_value = 1000000000
        min_jndex = ''
        depth_float = float(index)
        for jndex in rgb_time_stamp:
            rgb_float = float(jndex)
            if abs(depth_float - rgb_float) < min_value:
                min_value = abs(depth_float - rgb_float)
                min_jndex = jndex
        near_rgb_stamp.append(min_jndex)
    return near_rgb_stamp
 
 
if __name__ == '__main__':
 
    f_rgb = open("rgb.txt","r")
    f_depth = open("depth.txt","r")
    f_association = open('associations.txt','w',encoding='utf-8')
    data_depth = f_depth.readlines()
    f_depth.seek(0,0)
 
    # 切分出时间戳
    rgb_time_stamp = split_line(f_rgb)
    depth_time_stamp = split_line(f_depth)
 
    # 寻找最近时间戳
    rgb_time_stamp = near_time_stamp(rgb_time_stamp, depth_time_stamp)
    
    # 将rgb_time_stamp与depth_time_stamp对应行拼接起来
    for i in range(len(rgb_time_stamp)):
        str_association = rgb_time_stamp[i] + " " \
                            + "rgb/" + rgb_time_stamp[i] + ".png" + " " \
                            + data_depth[i]
        f_association.write(str_association)
 
    f_rgb.close()
    f_depth.close()
    f_association.close()

注:代码里按照filename读取文件的时候,没有考虑到这txt前三行的注释,所以也会有问题。故必须将传入的txt文件的前面三行的注释删掉,也就是rgb.txt与depth.txt按时间戳拼接后的.txt文件不要加前面的注释

预处理:python3 associate.py rgb.txt depth.txt > associations.txt

运行

cd /GCNv2_SLAM/GCN2
GCN_PATH=gcn2_320x240.pt ./rgbd_gcn ../Vocabulary/GCNvoc.bin TUM3_small.yaml /home/slam/GCNv2_SLAM/DataSet/rgbd_dataset_freiburg3_long_office_household /home/slam/GCNv2_SLAM/DataSet/rgbd_dataset_freiburg3_long_office_household/associations.txt

或者将run.sh数据集的路径改成你下载并解压的数据集路径就行

然后运行./run.sh就行

GCNv2-SLAM是一种基于图卷积网络(GCN)的视觉SLAM( simultaneous localization and mapping)方法。视觉SLAM是指在没有已知地图的情况下,通过从相机捕捉的图像数据中同时估计相机的路径和场景的结构。 GCNv2-SLAM通过将视觉SLAM问题建模为图形问题来解决,其中相机路径和场景结构被表示为图的节点,而视觉观测则表示为边。与传统的基于特征匹配的SLAM方法不同,GCNv2-SLAM从原始图像中学习到的特征表示被用来进行相机运动估计和地图重建。 GCNv2-SLAM的运行过程可以分为以下几个步骤:首先,提取输入图像的特征表示。这可以通过使用预训练的深度卷积神经网络(CNN)来实现。然后,使用特征表示来估计相机的运动。这个估计过程可以通过将特征表示作为输入,通过GCN进行推断来实现。 在相机运动估计之后,GCNv2-SLAM将观测到的特征匹配到先前帧的地图中,并使用三角测量技术重建三维地图。这个过程类似于传统的视觉SLAM方法,但是GCNv2-SLAM使用了从CNN中学习到的特征表示来提高地图的精度和稳定性。 最后,GCNv2-SLAM会对地图进行优化,以进一步提高估计的相机路径和地图结构的精度。这可以通过使用图优化算法,如Bundle Adjustment(BA)来实现。 总的来说,GCNv2-SLAM通过结合GCN和深度学习的技术,提供了一种高效准确的视觉SLAM解决方案。它可以用于各种应用,包括机器人导航、增强现实和虚拟现实等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值