Ubuntu20.04安装运行DynaSLAM
目录
一、安装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_XVMC
TEST_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_VDPAU
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);
#endif
第127行
TEST_PIX_FMT_RETURN(VDPAU_MPEG4);
改为
#ifdef FF_API_VDPAU
TEST_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);
}
#else
NumpyAllocator()
{
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 case
return 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)
#else
m.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);
#else
if (!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。或再检查一下需要修改的文件内容有没有全部修改。
运行成功画面如下: