目录
一、安装Anaconda
二、相关依赖库安装
1、boost安装
2、Eigen 3安装
3、opencv安装
4、Pangolin安装
三、配置Mask_RCNN环境
四、DynaSLAM编译
五、DynaSLAM运行
一、安装Anaconda
打开以下链接:
Index of /
下载和自己系统匹配的安装包。这里下载的是Anaconda3-2024.02-1-Linux-x86_64.sh。
在下载安装包的目录下打开终端,执行以下命令进行安装。
bash Anaconda3-2024.02-1-Linux-x86_64.sh
出现以下画面,按提示进行回车:
一直按回车,或按q直接跳过,直到出现“Do you accept the license terms”, 输入“yes” 。
默认位置已经足够,按ENTER确认安装位置。
出现是否要运行conda init,输入yes。
出现以下画面,Anaconda安装成功:
安装好后,source一下环境或者重新打开一个终端。
source ~/.bashrc
会多一个(base)的前缀。
附:如果希望 conda 的基础环境在启动终端时不被激活,将 auto_activate_base
参数设置为 false:
conda config --set auto_activate_base false
后面想要再进入conda的base环境,只需要使用conda指令激活:
conda activate base
二、相关依赖库安装
1、boost安装
通过以下链接下载boost1.71:
https://archives.boost.io/release/1.71.0/source/boost_1_71_0.tar.gz
将下载的源码解压缩至home下,在boost目录下打开终端,依次执行以下命令,等待安装完成即可:
sudo ./bootstrap.sh
sudo ./b2 install
2、Eigen 3安装
在home下打开终端,终端执行以下命令下载Eigen3源码:
git clone https://github.com/eigenteam/eigen-git-mirror
然后依次执行以下命令进行安装:
cd eigen-git-mirror
mkdir build && cd build
cmake ..
sudo make install
3、opencv安装
版本一定要对应,不然编译过程中会报各种错误。
通过以下链接下载opencv3.4.5:
https://github.com/opencv/opencv/archive/refs/tags/3.4.5.tar.gz
终端执行以下命令,安装所需的依赖项:
sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff5-dev libopenexr-dev libtbb-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libgtk-3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev pkg-config
在opencv目录下打开终端,执行以下命令编译安装:
mkdir build && cd build
cmake ..
sudo make -j4
sudo make install
终端执行以下命令,修改/etc/ld.so.conf文件:
sudo gedit /etc/ld.so.conf
在打开的文件中加上一行 include /usr/local/lib
,/usr/local是opencv的默认安装路径,这样告诉系统以后去lib目录下找opencv的库文件。
include /usr/local/lib
执行以下,命令使得conf生效:
sudo ldconfig
终端执行以下命令,修改bash.bashrc文件:
sudo gedit /etc/bash.bashrc
在文件末尾加上以下内容:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
然后source使得bash生效:
source /etc/bash.bashrc
输入以下命令查看opencv版本信息:
pkg-config opencv --modversion
显示版本,表示安装成功!
4、Pangolin安装
Pangolin一定要v0.5版本的,其他版本会报错。
由于我这里之前安装过Pangolin,因此需要卸载之前的版本。
(1)删除库和头文件
cd Pangolin/build
make clean
sudo make uninstall
(2)删除源代码
cd ../..
sudo rm -r Pangolin
(3)删除残留文件夹
sudo updatedb
locate pangolin
sudo rm -r /usr/local/include/pangolin
通过以下链接下载Pangolinv0.5源码:
https://github.com/stevenlovegrove/Pangolin/archive/refs/tags/v0.5.tar.gz
将其解压缩到主目录home下,打开Pangolin文件夹,打开终端执行以下命令:
mkdir build && cd build
cmake ..
sudo make -j4
sudo make install
安装时会出现报错,因此需要对文件进行修改:
在/Pangolin/CMakeModules/FindFFMPEG.cmake中63,64行
sizeof(AVFormatContext::max_analyze_duration2);}" HAVE_FFMPEG_MAX_ANALYZE_DURATION2
换成
sizeof(AVFormatContext::max_analyze_duration);}" HAVE_FFMPEG_MAX_ANALYZE_DURATION
/Pangolin/src/video/drivers/ffmpeg.cpp中第37行 namespace pangolin上面加上
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
第78,79行
TEST_PIX_FMT_RETURN(XVMC_MPEG2_MC);
TEST_PIX_FMT_RETURN(XVMC_MPEG2_IDCT);
改为
#ifdef FF_API_XVMCTEST_PIX_FMT_RETURN(XVMC_MPEG2_MC);TEST_PIX_FMT_RETURN(XVMC_MPEG2_IDCT);
#endif
第101-105行
TEST_PIX_FMT_RETURN(VDPAU_H264);TEST_PIX_FMT_RETURN(VDPAU_MPEG1);TEST_PIX_FMT_RETURN(VDPAU_MPEG2);TEST_PIX_FMT_RETURN(VDPAU_WMV3);TEST_PIX_FMT_RETURN(VDPAU_VC1);
改为
#ifdef FF_API_VDPAUTEST_PIX_FMT_RETURN(VDPAU_H264);TEST_PIX_FMT_RETURN(VDPAU_MPEG1);TEST_PIX_FMT_RETURN(VDPAU_MPEG2);TEST_PIX_FMT_RETURN(VDPAU_WMV3);TEST_PIX_FMT_RETURN(VDPAU_VC1);
#endif
第127行
TEST_PIX_FMT_RETURN(VDPAU_MPEG4);
改为
#ifdef FF_API_VDPAUTEST_PIX_FMT_RETURN(VDPAU_MPEG4);
#endif
在Pangolin/include/pangolin/video/drivers/ffmpeg.h开头加上
#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
更改完后,重新安装即可。
三、配置Mask_RCNN环境
在Anaconda虚拟环境下配置,终端依次执行以下命令:
# 创建一个虚拟环境
conda create -n MaskRCNN python=2.7
conda activate MaskRCNN
# 这一步可能报错,多尝试几次
pip install tensorflow==1.14.0
pip install keras==2.0.9
pip install scikit-image
pip install pycocotools
在安装pycocotools时报错:
通过以下命令安装pycocotools:
conda install -c conda-forge pycocotools
下载DynaSLAM并测试环境,终端执行以下命令下载DynaSLAM源码:
git clone https://github.com/BertaBescos/DynaSLAM.git
通过以下链接,下载mask_rcnn_coco.h5
文件:
https://github.com/matterport/Mask_RCNN/releases/download/v1.0/mask_rcnn_coco.h5
然后把mask_rcnn_coco.h5
文件放在DynaSLAM/src/python/文件夹下。
在DynaSLAM目录下打开终端,然后执行以下命令(需在刚刚创建的MaskRCNN环境下):
python src/python/Check.py
出现如下:Mask R-CNN is correctly working
则说明Mask_RCNN环境配置成功了。
四、DynaSLAM编译
编译之前需要对部分代码进行修改。
(1)DynaSLAM/CMakeLists.txt
中
C++11改为C++14
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 ")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
......................
#find_package(OpenCV 2.4.11 QUIET)
#if(NOT OpenCV_FOUND)
# message("OpenCV > 2.4.11 not found.")
# find_package(OpenCV 3.0 QUIET)
# if(NOT OpenCV_FOUND)
# message(FATAL_ERROR "OpenCV > 3.0 not found.")
# endif()
#endif()find_package(OpenCV 3.4 QUIET)
if(NOT OpenCV_FOUND)find_package(OpenCV 2.4 QUIET)if(NOT OpenCV_FOUND)message(FATAL_ERROR "OpenCV > 2.4.x not found.")endif()
endif()
......................
set(Python_ADDITIONAL_VERSIONS "2.7")
#This is to avoid detecting python 3
find_package(PythonLibs 2.7 EXACT REQUIRED)
if (NOT PythonLibs_FOUND)message(FATAL_ERROR "PYTHON LIBS not found.")
else()message("PYTHON LIBS were found!")message("PYTHON LIBS DIRECTORY: " ${PYTHON_LIBRARY} ${PYTHON_INCLUDE_DIRS})
endif()
......................
#find_package(Eigen3 3.1.0 REQUIRED)
find_package(Eigen3 3 REQUIRED)
......................
# add_executable(mono_carla
# Examples/Monocular/mono_carla.cc)
# target_link_libraries(mono_carla ${PROJECT_NAME})
(2)DynaSLAM/Thirdparty/DBoW/CMakeLists.txt
中
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 ")
......................
# find_package(OpenCV 3.0 QUIET)
find_package(OpenCV 3.4 QUIET)
(3)DynaSLAM/Thirdparty/g2o/CMakeLists.txt
中
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native")
#SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -march=native")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 ")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 ")
......................
#FIND_PACKAGE(Eigen3 3.1.0 REQUIRED)
FIND_PACKAGE(Eigen3 3 REQUIRED)
(4)DynaSLAM/include/Conversion.h
// cv::Mat toMat(const PyObject* o);cv::Mat toMat(PyObject* o);
(5)DynaSLAM/src/Conversion.cc
/*** This file is part of DynaSLAM.* Copyright (C) 2018 Berta Bescos <bbescos at unizar dot es> (University of Zaragoza)* For more information see <https://github.com/bertabescos/DynaSLAM>.**/#include "Conversion.h"
#include <iostream>namespace DynaSLAM
{static void init(){import_array();}static int failmsg(const char *fmt, ...){char str[1000];va_list ap;va_start(ap, fmt);vsnprintf(str, sizeof(str), fmt, ap);va_end(ap);PyErr_SetString(PyExc_TypeError, str);return 0;}class PyAllowThreads{public:PyAllowThreads() : _state(PyEval_SaveThread()) {}~PyAllowThreads(){PyEval_RestoreThread(_state);}private:PyThreadState *_state;};class PyEnsureGIL{public:PyEnsureGIL() : _state(PyGILState_Ensure()) {}~PyEnsureGIL(){// std::cout << "releasing"<< std::endl;PyGILState_Release(_state);}private:PyGILState_STATE _state;};using namespace cv;static PyObject *failmsgp(const char *fmt, ...){char str[1000];va_list ap;va_start(ap, fmt);vsnprintf(str, sizeof(str), fmt, ap);va_end(ap);PyErr_SetString(PyExc_TypeError, str);return 0;}class NumpyAllocator : public MatAllocator{public:
#if (CV_MAJOR_VERSION < 3)NumpyAllocator(){}~NumpyAllocator() {}void allocate(int dims, const int *sizes, int type, int *&refcount,uchar *&datastart, uchar *&data, size_t *step){// PyEnsureGIL gil;int depth = CV_MAT_DEPTH(type);int cn = CV_MAT_CN(type);const int f = (int)(sizeof(size_t) / 8);int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE: depth == CV_16U ? NPY_USHORT: depth == CV_16S ? NPY_SHORT: depth == CV_32S ? NPY_INT: depth == CV_32F ? NPY_FLOAT: depth == CV_64F ? NPY_DOUBLE: f * NPY_ULONGLONG + (f ^ 1) * NPY_UINT;int i;npy_intp _sizes[CV_MAX_DIM + 1];for (i = 0; i < dims; i++){_sizes[i] = sizes[i];}if (cn > 1){_sizes[dims++] = cn;}PyObject *o = PyArray_SimpleNew(dims, _sizes, typenum);if (!o){CV_Error_(CV_StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));}refcount = refcountFromPyObject(o);npy_intp *_strides = PyArray_STRIDES(o);for (i = 0; i < dims - (cn > 1); i++)step[i] = (size_t)_strides[i];datastart = data = (uchar *)PyArray_DATA(o);}void deallocate(int *refcount, uchar *, uchar *){// PyEnsureGIL gil;if (!refcount)return;PyObject *o = pyObjectFromRefcount(refcount);Py_INCREF(o);Py_DECREF(o);}
#elseNumpyAllocator(){stdAllocator = Mat::getStdAllocator();}~NumpyAllocator(){}UMatData *allocate(PyObject *o, int dims, const int *sizes, int type,size_t *step) const{UMatData *u = new UMatData(this);u->data = u->origdata = (uchar *)PyArray_DATA((PyArrayObject *)o);npy_intp *_strides = PyArray_STRIDES((PyArrayObject *)o);for (int i = 0; i < dims - 1; i++)step[i] = (size_t)_strides[i];step[dims - 1] = CV_ELEM_SIZE(type);u->size = sizes[0] * step[0];u->userdata = o;return u;}UMatData *allocate(int dims0, const int *sizes, int type, void *data,size_t *step, int flags, UMatUsageFlags usageFlags) const{if (data != 0){CV_Error(Error::StsAssert, "The data should normally be NULL!");// probably this is safe to do in such extreme casereturn stdAllocator->allocate(dims0, sizes, type, data, step, flags,usageFlags);}PyEnsureGIL gil;int depth = CV_MAT_DEPTH(type);int cn = CV_MAT_CN(type);const int f = (int)(sizeof(size_t) / 8);int typenum =depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE: depth == CV_16U ? NPY_USHORT: depth == CV_16S ? NPY_SHORT: depth == CV_32S ? NPY_INT: depth == CV_32F ? NPY_FLOAT: depth == CV_64F ? NPY_DOUBLE: f * NPY_ULONGLONG + (f ^ 1) * NPY_UINT;int i, dims = dims0;cv::AutoBuffer<npy_intp> _sizes(dims + 1);for (i = 0; i < dims; i++)_sizes[i] = sizes[i];if (cn > 1)_sizes[dims++] = cn;PyObject *o = PyArray_SimpleNew(dims, _sizes, typenum);if (!o)CV_Error_(Error::StsError,("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));return allocate(o, dims0, sizes, type, step);}bool allocate(UMatData *u, int accessFlags,UMatUsageFlags usageFlags) const{return stdAllocator->allocate(u, accessFlags, usageFlags);}void deallocate(UMatData *u) const{if (u){PyEnsureGIL gil;PyObject *o = (PyObject *)u->userdata;Py_XDECREF(o);delete u;}}const MatAllocator *stdAllocator;
#endif};NumpyAllocator g_numpyAllocator;NDArrayConverter::NDArrayConverter() { init(); }void NDArrayConverter::init(){import_array();}cv::Mat NDArrayConverter::toMat(PyObject *o){cv::Mat m;if (!o || o == Py_None){if (!m.data)m.allocator = &g_numpyAllocator;}if (!PyArray_Check(o)){failmsg("toMat: Object is not a numpy array");}int typenum = PyArray_TYPE(o);int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S: typenum == NPY_USHORT ? CV_16U: typenum == NPY_SHORT ? CV_16S: typenum == NPY_INT || typenum == NPY_LONG ? CV_32S: typenum == NPY_FLOAT ? CV_32F: typenum == NPY_DOUBLE ? CV_64F: -1;if (type < 0){failmsg("toMat: Data type = %d is not supported", typenum);}int ndims = PyArray_NDIM(o);if (ndims >= CV_MAX_DIM){failmsg("toMat: Dimensionality (=%d) is too high", ndims);}int size[CV_MAX_DIM + 1];size_t step[CV_MAX_DIM + 1], elemsize = CV_ELEM_SIZE1(type);const npy_intp *_sizes = PyArray_DIMS(o);const npy_intp *_strides = PyArray_STRIDES(o);bool transposed = false;for (int i = 0; i < ndims; i++){size[i] = (int)_sizes[i];step[i] = (size_t)_strides[i];}if (ndims == 0 || step[ndims - 1] > elemsize){size[ndims] = 1;step[ndims] = elemsize;ndims++;}if (ndims >= 2 && step[0] < step[1]){std::swap(size[0], size[1]);std::swap(step[0], step[1]);transposed = true;}if (ndims == 3 && size[2] <= CV_CN_MAX && step[1] == elemsize * size[2]){ndims--;type |= CV_MAKETYPE(0, size[2]);}if (ndims > 2){failmsg("toMat: Object has more than 2 dimensions");}m = Mat(ndims, size, type, PyArray_DATA(o), step);if (m.data){
#if (CV_MAJOR_VERSION < 3)m.refcount = refcountFromPyObject(o);m.addref(); // protect the original numpy array from deallocation// (since Mat destructor will decrement the reference counter)
#elsem.u = g_numpyAllocator.allocate(o, ndims, size, type, step);m.addref();Py_INCREF(o);// m.u->refcount = *refcountFromPyObject(o);
#endif};m.allocator = &g_numpyAllocator;if (transposed){Mat tmp;tmp.allocator = &g_numpyAllocator;transpose(m, tmp);m = tmp;}return m;}PyObject *NDArrayConverter::toNDArray(const cv::Mat &m){if (!m.data)Py_RETURN_NONE;Mat temp;Mat *p = (Mat *)&m;
#if (CV_MAJOR_VERSION < 3)if (!p->refcount || p->allocator != &g_numpyAllocator){temp.allocator = &g_numpyAllocator;m.copyTo(temp);p = &temp;}p->addref();return pyObjectFromRefcount(p->refcount);
#elseif (!p->u || p->allocator != &g_numpyAllocator){temp.allocator = &g_numpyAllocator;m.copyTo(temp);p = &temp;}// p->addref();// return pyObjectFromRefcount(&p->u->refcount);PyObject *o = (PyObject *)p->u->userdata;Py_INCREF(o);return o;
#endif}
}
终端执行以下命令进行编译:
conda activate MaskRCNN
cd DynaSLAM
chmod +x build.sh
./build.sh
若报出以下错误:
终端执行以下命令安装:
sudo apt-get install python2.7-dev
若还有其他的错误,按照对应的包即可解决。
安装完后,重新编译即可。重新编译时把前一次编译生成的build文件删除。
五、DynaSLAM运行
运行时需要先激活创建的虚拟环境:
conda activate MaskRCNN
创建dataset文件夹,将数据集文件rgbd_dataset_freiburg3_walking_xyz放在dataset下,如果不知道如何生成associations.txt关联文件,以下这两篇均有提到:
使用evo工具/rgbd_benchmark_tools评估TUM RGB-D数据集_orb-slam3 评测工具evo-CSDN博客
YOLO_ORB_SLAM3编译运行_yolo-orb-slam3-CSDN博客
在DynaSLAM目录下打开终端,执行以下命令:
./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt ./Examples/RGB-D/TUM3.yaml ./dataset/rgbd_dataset_freiburg3_walking_xyz/ ./dataset/rgbd_dataset_freiburg3_walking_xyz/associations.txt ./dataset/mask ./dataset/output
如果运行时报以下错误:Light Tracking not working because Tracking is not initialized...
Geometry not working.
可以将DynaSLAM/Examples/RGB-D/TUM3.yaml文件里的ORBextractor.nFeatures参数值由1000改为3000。或再检查一下需要修改的文件内容有没有全部修改。
运行成功画面如下: