1 はじめに
最近 ORBSLAM2/3 を学習していて、Android スマートフォンでの ORB2 の実行に関する投稿を見つけました。その投稿に従って、Android スマートフォンで ORB3 を実行することに成功しました。この投稿では、その詳細を記録します。
参考投稿: ORB-SLAM2 の実行 - ROS + Android スマートフォンのカメラ
この記事の環境:
- Ubuntu 20.04
- ROSノエティック
- Android スマートフォン (Redmi note9 pro)
2.ros noeticインストール
新しいコンピューターを使用する場合、古いバージョンの ubuntu をインストールすると、さまざまなハードウェア ドライバーの不一致の問題が発生するため、20.04 バージョンを ubuntu に直接インストールしました。対応する ros バージョンは noetic です。
インストールのリファレンス:
公式ウェブサイト (https://wiki.ros.org/noetic/installation/Ubuntu)
間違い:
sudo rosdep initが接続できない
解決:
# 1.pip安装rosdepc
sudo pip install rosdepc
# 如果显示没有pip可以试试pip3
sudo pip3 install rosdepc
# 如果pip3还没有
sudo apt-get install python3-pip
sudo pip install rosdepc
# 2.用rosdepc替换原来的rosdep安装
sudo rosdepc init
rosdepc update
3. ORB-SLAM3のインストール
当初はORB2を先に実行したかったのですが、ORB2はopencv2/3をサポートしているのですが、ROS-Noeticはデフォルトでopencv4をインストールし、cv_bridgeはデフォルトでopencv4をバインドするため、ORB2を直接コンパイルするとopencvのバージョンが一致しないという問題が発生しました。 Opencv3 をインストールするため、ros の cv_bridge をアンインストールし、ソース コードから opencv3 をリンクする cv_bridge をコンパイルすると、コンパイル後に opencv4 が見つかりますが、解決策は 1 日経っても解決されないため、ORB3 をインストールする必要があります。ORB3 はサポートしていますopencv3/4 の場合、インストールプロセスは比較的スムーズです。インストール手順は以下のとおりです。
(1) インストールの依存関係
Pangolinv0.5 バージョン、opencv3/4 バージョン、Eigen3、g2o、ROS が必要
(2) ダウンロードとコンパイル
git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git ORB_SLAM3
cd ORB_SLAM3
# 修改ORB_SLAM3/CMakeLists.txt
# 把opencv版本改为自己的版本,如 find_package(OpenCV 4 QUIET)
chmod +x build.sh
./build.sh
Q1:
CMake Error at CMakeLists.txt:91 (ADD_LIBRARY): Cannot find source
file:
g2o/stuff/timeutil.cpp
A1:
ORB3 ソース コードを XTDrone に直接コピーすると、/Thirdparty/g2o/g2o/stuff/
ファイルが見つからないため、このエラーが報告されますtimeutil.h、timeutil.cpp
。公式Webサイトから対応するファイルをダウンロードする必要があります。
Q2:
ORB SLAM2 找不到 libDBoW2.so / libg2o.so
A2:
XTDrone で ORB3 のソース コードのフォルダーORB_SLAM3/Thirdparty/DBoW2
が不足していますが、lib
現在の ORB 公式 Web サイトには該当するlib
フォルダーが見つかりません。不足しているライブラリ ファイルを自分でコンパイルする方法に関するチュートリアルがあります。ただし、他の人がインストールしたコンピューター上で不足しているライブラリ ファイルを直接見つけて入力することで問題を解決しました。
(3) ROSにコンパイルする
# 路径需要自己修改
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/catkin_ws/src/ORB_SLAM3/Examples/ROS
# 修改ORB_SLAM3/Examples/ROS/ORB_SLAM3/CMakeLists.txt
# 把opencv版本改为自己的版本,注意要和前面修改的CMakeLists.txt中的opencv版本一致
# 如 find_package(OpenCV 4 QUIET)
# -----------------
chmod +x build_ros.sh
./build_ros.sh
(4) ORB3を実行する
ORB3 は、単眼、双眼、深度の実行をサポートし、IMU との組み合わせをサポートしています。携帯電話のカメラは単眼なので、ORB3 の単眼コマンドの実行について説明します。
rosrun ORB_SLAM3 Mono PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE
PATH_TO_VOCABULARY
これは、オフラインで事前トレーニングされたバッグオブワード モデルのパスであり、ソース ファイルの下にあるファイルORB_SLAM3/Vocabulary
です。txt
PATH_TO_SETTINGS_FILE
これは、単眼カメラのカメラ内部パラメータを記録するカメラ設定ファイルです。後でカメラ内部パラメータを再調整する必要があります。ORB は参照設定ファイルを提供しており、パスは次のとおりです。ORB_SLAM3/Examples/Monocular/TUM1.yaml
4. Android スマートフォンのカメラと PC 間の ROS ベースの通信
ORB3 は PC の ROS 上で動作し、カメラセンサーは携帯電話上にあるため、携帯電話のカメラ画像と PC 側の ROS の間の通信を確立し、携帯電話のカメラ画像を ROS として公開する必要があります。これは GitHub のプロジェクトに基づいています。プロジェクト: hitcm/Android_Camera-IMUで、作者は携帯電話のカメラ情報と IMU 情報を PC に転送することを実現しました (作者のブログ記事「Android イメージを収集するための ROS」を参照)リアルタイムの IMU データ)。この記事では、カメラ情報のみを使用する必要があります。
(1) インストール
# 电脑PC端
git clone https://github.com/hitcm/Android_Camera-IMU.git
sudo apt-get install ros-noetic-imu-tools # 修改对应自己的 ROS 版本
# 安卓手机端
# 将git下载的源文件中的apk安装包发给手机并安装
(2) 走る
# 1.PC和手机处于同一个网段,例如PC和手机连同一个wifi,然后查看PC端ip
ifconfig # 记录一下PC端的ip地址
# 2.运行roscore
roscore
# 3.手机上运行安装好的软件,在 IP Port 中修改 IP 地址为 PC的 IP地址,port不需要修改,之后点击 Connect,连接成功则进入相机界面。
# 例如 http://192.168.31.192:11311/
# 4.运行roslaunch文件,复制出一个跑orb3需要的摄像头话题
cd pathToAndroid_Camera-IMU # 就是cd到刚才git下载的源文件
roslaunch android_cam-imu.launch
# 没报错的话,会弹出一个rviz,直接关掉就可以了
# 5.查看图片话题
rqt_image_view # 如果成功看到有图形,那么就成功了
5. 携帯電話のカメラのキャリブレーション
ORB-SLAM3 を正確に実行するには、携帯電話のカメラを校正する必要があります。キャリブレーション方法は、チェッカーボード キャリブレーション ボードの全方向の写真を撮影し、OpenCV に基づいてキャリブレーションを実行します。ここで収集された写真は、ORB-SLAM3 プログラムによって読み取られた写真と一致している必要があることに注意してください。そのため、電話機の内蔵カメラ アプリを直接使用して写真を撮ることはできません。電話機はアルゴリズムを通じて自動的に修正するためです。上記の通信では生の画像が送信されます。したがって、完了する必要がある最初のタスクは、カメラ画像を収集して保存することです。
1. カメラのキャリブレーション画像を収集する
(1) プリントキャリブレーションボード
下のキャリブレーションボードの画像を印刷してください
(2) 画像収集用のコードを書く
現時点では直接保存する方法がないため、携帯電話から画像を受信するための ROS ノードを作成し、OpenCV を介して表示および保存することにします。
便宜上、ORB_SLAM3/Examples/ROS/ORB_SLAM3/srcros_mono.cc
ORB-SLAM3 のコードに基づいて直接変更することを選択し、ros_mono.cc
同じディレクトリにコードを記述しますros_camera_capture.cc
。内容は次のとおりです。
/**
* ros_camera_capture.cc
* This file is to capture images from Android phone, for camera calibration
* This file is used with Android_Camera-IMU
*/
#include<iostream>
#include<algorithm>
#include<fstream>
#include<chrono>
#include<ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include<opencv2/core/core.hpp>
#include"../../../include/System.h"
using namespace std;
string save_dir = "~/"; // 修改为自己保存图片的路径,注意路径末尾带上/
int imgId = 0;
void GrabImage(const sensor_msgs::ImageConstPtr& msg);
int main(int argc, char **argv)
{
std::cout << "To save the current frame, please press 'Q' or 'q' " << std::endl;
std::cout << "The images will be saved to " << save_dir << std::endl;
ros::init(argc, argv, "PClistener");
ros::start();
ros::NodeHandle nodeHandler;
ros::Subscriber sub = nodeHandler.subscribe("/camera/image_raw", 1, GrabImage);
ros::spin();
ros::shutdown();
return 0;
}
void GrabImage(const sensor_msgs::ImageConstPtr& msg)
{
string imgname;
cv_bridge::CvImageConstPtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvShare(msg);
cv::Mat img = cv_ptr->image;
cv::imshow("img_name", img);
char key = cv::waitKey(1);
// press "q" to save the image
if(key == 'q' || key == 'Q'){
imgId++;
imgname = "img_" + to_string(imgId) + ".jpg";
cv::imwrite(save_dir + imgname, img);
std::cout << "has saved image "<< imgId << " to " << save_dir << std::endl;
}
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
}
(3) コードをコンパイルする
ORB_SLAM3/Examples/ROS/ORB_SLAM3
次のコンテンツをディレクトリに追加しますCMakeLists.txt
(単眼カメラの場合は、上記の # ノードを追加するだけです)。
# Node for capture images for camera calibration
rosbuild_add_executable(CameraCapture
src/ros_camera_capture.cc
)
target_link_libraries(CameraCapture
${LIBS}
)
その後、ORB_SLAM3 プロジェクトを再コンパイルします。
cd PATH/ORB_SLAM3
./build_ros.sh
(4) コードを実行して画像を収集します
# 终端1
roscore
# 手机
运行应用软件并连接
# 终端2
cd pathToAndroid_Camera-IMU # 就是cd到刚才git下载的源文件
roslaunch android_cam-imu.launch
# 可以关掉rviz
# 终端3
rosrun ORB_SLAM3 CameraCapture
# 会显示手机摄像头图片,按下 q 键保存图像
撮影時はキャリブレーションボードを複数の角度から撮影するよう注意してください。画像がぼやけているので、近づいて撮影する必要があります。
2. カメラを調整する
カメラ キャリブレーション プログラムには、opencv サンプル プログラムを使用します。OpenCV インストール ディレクトリのフォルダーをsamples/cpp/tutorial_code/calib3d/camera_calibration
カスタム パスにコピーし、その中に新しいサブフォルダーを作成しimg
、以前に保存したすべての画像をimg
そのフォルダーに置きます。ファイル構造は次のとおりです。
カメラキャリブレーション_opencv
§──camera_calibration.cpp
§── CMakeLists.txt
§── img
│ §── img_10.jpg
│ §── img_11.jpg
│ §── img_1.jpg
│ §── img_2.jpg
│ §── img_3. jpg
│ §── img_4.jpg
│ ├── img_5.jpg
│ §── img_6.jpg
│ §── img_7.jpg
│ §── img_8.jpg
│ └── img_9.jpg
§── in_VID5.xmlってい
ます。 ── out_camera_data.yml
└── VID5.xml
(1) VID5.xmlを修正する
キャリブレーション イメージのパスは VID5.xml に保存されているため、すべてのキャリブレーション イメージのパスを VID.xml に追加します。次に例を示します。
<?xml version="1.0"?>
<opencv_storage>
<images>
../img/img_1.jpg
../img/img_2.jpg
../img/img_3.jpg
../img/img_4.jpg
../img/img_5.jpg
../img/img_6.jpg
../img/img_7.jpg
../img/img_8.jpg
../img/img_9.jpg
../img/img_10.jpg
../img/img_11.jpg
</images>
</opencv_storage>
内部の画像のパスは絶対パスではなく相対パスである必要があることに注意してください。そうでない場合はエラーが報告されます。
(2) in_VID5.xmlを修正する
# 棋盘格的宽和高,注意,这里的宽度和高度是指内部交叉点的个数,而不是方形格的个数。如上图棋盘的数据就是9和6
<BoardSize_Width> 9</BoardSize_Width>
<BoardSize_Height>6</BoardSize_Height>
# 修改为每格的边长 (mm),拿尺子量。
<Square_Size>19</Square_Size>
# 修改 VID5.xml 的路径,这里路径是相对路径
<Input>"../VID5.xml"</Input>
# 此处原来是0,需要改为1,表示引入切向畸变参数(因为 ORB-SLAM2 中也引入了切向畸变参数),否则只有径向畸变参数
<Calibrate_FixPrincipalPointAtTheCenter> 1 </Calibrate_FixPrincipalPointAtTheCenter>
(3) プロジェクトをコンパイルする
作業ディレクトリ Camera_calibration_opencv に新しい CMakeLists.txt を作成します。
project(Camera_Calibration)
set(CMAKE_CXX_STANDARD 11)
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()
include_directories(${OpenCV_INCLUDE_DIR})
add_executable(Camera_Calibration camera_calibration.cpp)
target_link_libraries(Camera_Calibration ${OpenCV_LIBS})
コンパイル後:
cd camera_calibration_opencv
mkdir build
cd build
cmake ..
make
(4) 校正用プログラムを実行します。
cd camera_calibration_opencv/build
./Camera_Calibration ../in_VID5.xml
前に述べたように、合計を変更するときは、絶対パスではなく相対パスをVID5.xml
使用してくださいin_VID5.xml
。そうしないと、エラーが発生します。
Input does not exist: VID5.xmlInvalid input detected
次に、相対パスを使用する場合の現在のパスが何であるかを知る必要があります。現在のパスは、Camera_Calibration
ターミナルが実行可能ファイルを実行するパスです。たとえば、次のようになります。
# 运行方法一:
cd camera_calibration_opencv/build
camera_calibration_opencv/build$./Camera_Calibration ../in_VID5.xml
# 终端当前路径就是$号前面的路径,也就是camera_calibration_opencv/build,所以in_VID5.xml的相对路径就是../in_VID5.xml
# 运行方法二:
cd camera_calibration_opencv
camera_calibration_opencv$./build/Camera_Calibration in_VID5.xml
# 终端当前路径就是camera_calibration_opencv,所以in_VID5.xml的相对路径就是in_VID5.xml
正常に実行されると、キャリブレーション画像が順番に表示され、ターミナルに再投影誤差が出力されます。誤差は小さいほど良いです。ここでは 0.3 です。大きすぎる場合は、もう一度写真を撮ります。
Re-projection error reported by calibrateCamera: 0.299492
Calibration succeeded. avg re projection error = 0.299491
(5) ORB-SLAM3の設定ファイルSETTINGS_FILEを記入します。
キャリブレーションプログラムが正常に実行されると、カメラ内部参照結果ファイルが同じディレクトリに生成されます。camera_calibration_opencv/build/out_camera_data.xml
開いて、内部カメラ パラメータを見つけます。
<camera_matrix type_id="opencv-matrix">
はカメラの内部参照行列で、順序は fx, 0, cx; 0, fy, cy; 0, 0, 1 です。<distortion_coefficients type_id="opencv-matrix">
は歪みパラメータで、その順序は k1、k2、p1、p2、k3 です。
次に、ORB_SLAM3/Examples/Monocular
それを path の下にコピーしTUM1.yaml
、 という名前を付けAndroidPhone.yaml
、カメラの内部パラメータを入力します。
Camera1.fx: 454.608394
Camera1.fy: 454.608394
Camera1.cx: 319.500000
Camera1.cy: 239.500000
Camera1.k1: 0.180868
Camera1.k2: -1.037955
Camera1.p1: 0.00
Camera1.p2: 0.00
Camera1.k3: 2.046420
6. ORB-SLAM3 を実行します。
# 1.
roscore
# 2.
手机运行应用程序并连接
# 3.
cd pathToAndroid_Camera-IMU
roslaunch android_cam-imu.launch # 可以关掉rviz
# 4.
rosrun ORB_SLAM3 Mono PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE
# PATH_TO_VOCABULARY就是ORB_SLAM3/Vocabulary/ORBvoc.txt的绝对路径
# PATH_TO_SETTINGS_FILE就是AndroidPhone.yaml的绝对路径
ランニング効果表示:
注: ORB-SLAM3 Mono の初期化はまだ比較的困難です (初期化条件は比較的厳しいです)。最初に、豊富な特徴テクスチャを持つ領域を選択し、純粋に回転せず、カメラを上下左右に移動します。 、これは初期化に役立ちます。