Ubuntu20.04安装配置运行DynaSLAM
DynaSLAM结合Mask_RCNN和多视图几何,在ORB-SLAM2的基础上去除动态特征,因此在[Ubuntu 20.04配置ORB-SLAM2和ORB-SLAM3运行环境+ROS实时运行ORB-SLAM2+Gazebo仿真运行ORB-SLAM2+各种相关库的安装](https://blog.csdn.net/zardforever123/article/details/125044004?s
Ubuntu20.04安装配置运行DynaSLAM
文章目录
DynaSLAM结合Mask_RCNN和多视图几何,在ORB-SLAM2的基础上去除动态特征,因此在Ubuntu 20.04配置ORB-SLAM2和ORB-SLAM3运行环境+ROS实时运行ORB-SLAM2+Gazebo仿真运行ORB-SLAM2+各种相关库的安装的基础环境下配置运行DynaSLAM
一、安装Anaconda
进入Anaconda官网,点击Download下载(Anaconda会根据访问网页所使用的系统下载对应的版本,比如我这里下载的是Anaconda3-2023.03-Linux-x86_64.sh)
安装Anaconda
bash Anaconda3-2023.03-Linux-x86_64.sh
(1)查看安装协议,一直按Enter直到出现 Do you accept the license terms? [yes|no]
,输入yes
即可继续安装;
(2)输入yes后会提示确认安装位置,这里点击Enter
,默认即可;
(3)初始化Anaconda,这一步只需要根据提示输入yes即可;
重启终端进入conda基础环境,按照提示,如果希望 conda 的基础环境在启动终端时不被激活,将 auto_activate_base
参数设置为 false:
conda config --set auto_activate_base false
后面想要再进入conda的base环境,只需要使用conda指令激活:
conda activate base
conda常用命令:
- 创建conda环境
conda create --name 环境名 包名(多个包名用空格分隔)
# 例如:conda create --name my_env python=3.7 numpy pandas scipy
- 激活(切换)conda环境
conda activate 环境名
# 例如:conda activate bas
- 显示已创建的conda环境
conda info --envs
# 或者:conda info -e,亦或者conda env list
- 删除指定的conda环境,
# 通过环境名删除
conda remove --name 要删除的环境名 --all
# 通过指定环境文件位置删除(这个方法可以删除不同位置的同名环境)
conda remove -p 要删除的环境所在位置 --all
# 例如:conda remove -p /home/zard/anaconda3/envs/MaskRCNN --all
二、安装依赖
(1)安装boost库
sudo apt-get install libboost-all-dev
(2)Pangolin, OpenCV2 or 3 以及 Eigen3的安装参考:Ubuntu 20.04配置ORB-SLAM2和ORB-SLAM3运行环境+ROS实时运行ORB-SLAM+Gazebo仿真运行ORB-SLAM2+各种相关库的安装,这篇文章里安装的是 Eigen3.4.0,OpenCV3.4.5,接下来就基于他们安装
三、配置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
# 这一步可能提示numpy,pillow版本过低,升级numpy和pillow
# sudo pip install numpy==x.x.x
# sudo pip install pillow==x.x.x
pip install scikit-image
pip install pycocotools
下载DynaSLAM并测试环境
git clone https://github.com/BertaBescos/DynaSLAM.git
cd DynaSLAM
python src/python/Check.py
如果输出:
Mask R-CNN is correctly working
就可以下一步了
四、安装DynaSLAM
下载mask_rcnn_coco.h5文件,将其复制到DynaSLAM/src/python/
下
Dynaslam源码中有些只适合opencv2.4,对于我们之前安装的opencv3.4.5需要修改dynaslam源码,并且为了避免出现段错误,也要修改部分内容,参考文章:关于运行DynaSLAM源码这档子事(OpenCV3.x版)
4.1 修改CMakeLists.txt
(1)DynaSLAM/CMakeLists.txt
中
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)
(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.2 修改源码
(1)include/Conversion.h
// cv::Mat toMat(const PyObject* o);
cv::Mat toMat(PyObject* o);
(2)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
}
}
4.3 编译DynaSLAM
conda activate MaskRCNN
cd DynaSLAM
chmod +x build.sh
./build.sh
- 如果是master分支没有mono_carla.cc这个文件,需要注释掉
# add_executable(mono_carla
# Examples/Monocular/mono_carla.cc)
# target_link_libraries(mono_carla ${PROJECT_NAME})
- 报错fatal error: ndarrayobject.h: No such file or director,虚拟环境和Python3中均安装了numpy,但是Ubuntu自带的python2没有安装,但不能用pip,因为会安装到python3中,因此
sudo apt-get install python-numpy
- 报错:error: static assertion failed: std::map must have the same value_type as its allocator,老问题了,我安装ORB的那篇文章里写了,把ORB-SLAM2源码目录中include/LoopClosing.h文件中的
// 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;
运行:
./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM3.yaml /XXX/tum_dataset/ /XXX/tum_dataset/associations.txt (path_to_masks) (path_to_output)
不给后面两个参数相当于运行ORB-SLAM2,如果只想用MaskRCNN的功能但不想存mask在path_to_masks那里就写为no_save,否则就给一个存Mask的文件夹地址
CPU(我的12代i5)上根本跑不动,卡死了,不过对于动态数据的定位效果,确实是好太多了:
更多推荐
所有评论(0)