DynaSLAM を実行するための Ubuntu20.04 のインストールと構成
記事ディレクトリ
DynaSLAM は、ORB-SLAM2 をベースに Mask_RCNN とマルチビュー ジオメトリを組み合わせて動的機能を削除するため、Ubuntu 20.04 で ORB-SLAM2 と ORB-SLAM3 の動作環境を構成 + ROS で ORB-SLAM2 をリアルタイムで実行 + Gazebo シミュレーションで ORB を実行-SLAM2 + 各種関連 ライブラリインストールの基本環境で DynaSLAM を設定して実行
1.アナコンダをインストールする
Anaconda 公式 Web サイトに入り、[ダウンロード] をクリックしてダウンロードします (Anaconda は、Web ページへのアクセスに使用されるシステムに応じて、対応するバージョンをダウンロードします。たとえば、ここでダウンロードしたのは Anaconda3-2023.03-Linux-x86_64.sh です)。
アナコンダをインストールする
bash Anaconda3-2023.03-Linux-x86_64.sh
(1) インストール同意書を確認し、表示されるまで Enter キーを押しDo you accept the license terms? [yes|no]
、Enter を押してyes
インストールを続行します;
(2) yes と入力した後、インストール場所を確認するプロンプトが表示されます。ここをクリックしてEnter
デフォルトにします;
(3) Anaconda を初期化します。プロンプトに従う必要があるだけです。yes と入力してください。
ターミナルを再起動して conda 基本環境に入り、プロンプトに従います。ターミナルの起動時に conda 基本環境をアクティブにしない場合は、auto_activate_base
パラメーター
conda config --set auto_activate_base false
後で conda ベース環境に入りたい場合は、conda コマンドを使用してアクティブ化するだけです。
conda activate base
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
2. インストールの依存関係
(1) boost ライブラリのインストール
sudo apt-get install libboost-all-dev
(2) Pangolin、OpenCV2 または 3 および Eigen3 インストール リファレンス: Ubuntu 20.04 構成 ORB-SLAM2 および ORB-SLAM3 動作環境 + ORB-SLAM を実行する ROS リアルタイム + ORB-SLAM2 を実行する Gazebo シミュレーション + さまざまな関連ライブラリのインストール、この記事そこに Eigen3.4.0 と OpenCV3.4.5 をインストールし、それを元にインストールします。
3.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
次のステップに進むことができます
4.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
- マスター ブランチに mono_carla.cc ファイルがない場合は、コメント アウトする必要があります。
# add_executable(mono_carla
# Examples/Monocular/mono_carla.cc)
# target_link_libraries(mono_carla ${PROJECT_NAME})
- エラー 致命的なエラー: ndarrayobject.h: No such file or director, numpy は仮想環境と Python3 にインストールされていますが、Ubuntu に付属している python2 はインストールされていませんが、pip は python3 にインストールされるため使用できません。
sudo apt-get install python-numpy
- Error: error: static assertion failed: std::map must have the same value_type as its allocator. It's an old problem. ORB をインストールした記事に書きましたが、 ORB-SLAM2のソースコードディレクトリ
// 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)
後の 2 つのパラメーターを指定しない場合は、ORB-SLAM2 を実行するのと同じです.MaskRCNN の関数を使用するだけで、path_to_masks にマスクを保存したくない場合は、no_save と記述し、それ以外の場合は、Mask を保存するフォルダーのアドレスを指定します.
CPU (私の第 12 世代 i5) はまったく動作せず、スタックしていますが、動的データの配置効果は実際にははるかに優れています。