【ORB-SLAM3】Uso de la cámara de un teléfono Android para ejecutar ORB3

1. Introducción

Estaba aprendiendo ORBSLAM2/3 recientemente y encontré una publicación sobre cómo ejecutar ORB2 en un teléfono Android. Seguí la publicación y ejecuté correctamente ORB3 en un teléfono Android. Esta publicación registrará los detalles.

Puesto de referencia: ORB-SLAM2 en ejecución - ROS + cámara de teléfono Android

El entorno de este artículo:

  • Ubuntu 20.04
  • ROSNoetic
  • Teléfono Android (Redmi note9 pro)

2.ros instalación noética

Cuando usa una computadora más nueva, la instalación de la versión anterior de ubuntu causará varios problemas de discrepancia del controlador de hardware, por lo que instalé la versión 20.04 directamente en ubuntu, y la versión ros correspondiente es noética.

Referencia de instalación:

Sitio web oficial (https://wiki.ros.org/noetic/Installation/Ubuntu)

error:

sudo rosdep init no se puede conectar

resolver:

# 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. Instalación de ORB-SLAM3

Originalmente, quería ejecutar ORB2 primero. ORB2 es compatible con opencv2/3, pero ROS-Noetic instala opencv4 de forma predeterminada y cv_bridge vincula opencv4 de forma predeterminada, lo que genera el problema de que la versión de opencv no coincide al compilar ORB2 directamente. Lo intento para instalar Opencv3 y desinstalar el cv_bridge de ros, compilar un cv_bridge enlazando opencv3 desde el codigo fuente, el resultado es encontrar opencv4 despues de compilar, y la solucion no se resolvio en un dia, asi que tengo que instalar ORB3, ORB3 soporta opencv3/4, el proceso de instalación es relativamente fluido. Los pasos de instalación a continuación:

(1) Dependencias de instalación

Requiere la versión Pangolinv0.5, versión opencv3/4, Eigen3, g2o, ROS

(2) Descargar y compilar

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

P1:

CMake Error at CMakeLists.txt:91 (ADD_LIBRARY): Cannot find source
file:
g2o/stuff/timeutil.cpp

A1:

Si copia directamente el código fuente de ORB3 en XTDrone, se informará de este error porque faltan /Thirdparty/g2o/g2o/stuff/archivos timeutil.h、timeutil.cpp. Debe descargar los archivos correspondientes del sitio web oficial.

P2:

ORB SLAM2 找不到 libDBoW2.so / libg2o.so

A2:

ORB_SLAM3/Thirdparty/DBoW2La carpeta que falta del código fuente de ORB3 en XTDrone , pero no puedo encontrar la carpeta correspondiente liben el sitio web oficial actual de ORB . Hay un tutorial sobre cómo compilar los archivos de biblioteca que faltan por sí mismo. Sin embargo, lo resolví buscando y escribiendo los archivos de la biblioteca que faltaban directamente en la computadora instalada por otros.lib

(3) Compilar en 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) Ejecutar ORB3

ORB3 admite la ejecución monocular, binocular, de profundidad y combinada con IMU. Dado que la cámara del teléfono móvil es monocular, hablemos de ORB3 ejecutando comandos monoculares:

rosrun ORB_SLAM3 Mono PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE

PATH_TO_VOCABULARYEs la ruta del modelo de bolsa de palabras preentrenado fuera de línea, que ORB_SLAM3/Vocabularyes un txtarchivo debajo del archivo de origen;

PATH_TO_SETTINGS_FILEEs un archivo de configuración de la cámara, que registra los parámetros internos de la cámara de la cámara monocular. Necesitamos recalibrar los parámetros internos de la cámara más tarde. ORB proporciona un archivo de configuración de referencia, y la ruta está enORB_SLAM3/Examples/Monocular/TUM1.yaml

4. Comunicación basada en ROS entre la cámara del teléfono Android y la PC

Nuestro ORB3 se ejecuta en el ROS de la PC, y el sensor de la cámara está en el teléfono móvil, por lo que debemos establecer la comunicación entre la imagen de la cámara del teléfono móvil y el ROS del lado de la PC, y publicar la imagen de la cámara del teléfono móvil como ROS tema. Esto se basa en uno en GitHub. Proyecto: hitcm/Android_Camera-IMU , el autor realizó la transferencia de la información de la cámara y la información de IMU del teléfono móvil a la PC (consulte la publicación de blog del autor ROS para recopilar imágenes de Android y Datos IMU en tiempo real ). En este artículo, solo necesitamos usar la información de la cámara.

(1) instalación

# 电脑PC端
git clone https://github.com/hitcm/Android_Camera-IMU.git
sudo apt-get install ros-noetic-imu-tools  # 修改对应自己的 ROS 版本
# 安卓手机端
# 将git下载的源文件中的apk安装包发给手机并安装

(2) correr

# 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. Calibración de la cámara del teléfono móvil

Para que ORB-SLAM3 funcione con precisión, la cámara del teléfono móvil debe calibrarse. El método de calibración es: tome fotografías de la placa de calibración de tablero de ajedrez en todas las direcciones y luego realice la calibración basada en OpenCV. Tenga en cuenta que las imágenes recopiladas aquí deben ser coherentes con las leídas por el programa ORB-SLAM3, por lo que no puede usar directamente la aplicación de cámara integrada del teléfono para tomar fotos, porque el teléfono las corregirá automáticamente a través del algoritmo y la comunicación anterior transmite imágenes en bruto. Por lo tanto, la primera tarea que debemos completar es: recopilar y guardar la imagen de la cámara.

1. Recopile imágenes de calibración de la cámara

(1) Tablero de calibración de impresión

Imprima la imagen de la placa de calibración a continuación

imagen

(2) Escriba el código para recopilar imágenes.

Actualmente, no hay forma de guardarlo directamente, por lo que elegimos escribir un nodo ROS para recibir la imagen desde el teléfono móvil y luego mostrarla y guardarla a través de OpenCV.

Para mayor comodidad, elegimos ORB_SLAM3/Examples/ROS/ORB_SLAM3/srcros_mono.ccmodificar directamente sobre la base del código de ORB-SLAM3 y ros_mono.ccescribir un código en el mismo directorio ros_camera_capture.cc, el contenido es:

/**
* 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) compilar el código

Agregue el siguiente contenido en ORB_SLAM3/Examples/ROS/ORB_SLAM3el directorio CMakeLists.txt(simplemente agregue arriba # Nodo para cámara monocular):

# Node for capture images for camera calibration
rosbuild_add_executable(CameraCapture
src/ros_camera_capture.cc
)

target_link_libraries(CameraCapture
${LIBS}
)

Después de eso, vuelva a compilar el proyecto ORB_SLAM3

cd PATH/ORB_SLAM3
./build_ros.sh

(4) Ejecute el código para recopilar imágenes.

# 终端1
roscore

# 手机
运行应用软件并连接

# 终端2
cd pathToAndroid_Camera-IMU  # 就是cd到刚才git下载的源文件
roslaunch android_cam-imu.launch
# 可以关掉rviz

# 终端3
rosrun ORB_SLAM3 CameraCapture
# 会显示手机摄像头图片,按下 q 键保存图像

Preste atención a disparar la placa de calibración desde múltiples ángulos al disparar. Dado que la imagen es borrosa, debe estar más cerca al disparar

imagen-20230522110717175

2. Calibrar la cámara

Para el programa de calibración de la cámara, usamos el programa de ejemplo opencv. Copie la carpeta en el directorio de instalación de OpenCV samples/cpp/tutorial_code/calib3d/camera_calibrationa la ruta personalizada, cree una nueva subcarpeta en ella imgy coloque todas las imágenes guardadas anteriormente imgen la carpeta. La estructura del archivo es:

camera_calibration_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
├── en_VID5.xml
├ ── out_camera_data.yml
└── VID5.xml

(1) Modificar VID5.xml

La ruta de la imagen de calibración se almacena en VID5.xml, así que agregue la ruta de todas las imágenes de calibración en VID.xml, por ejemplo:

<?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>

Tenga en cuenta que la ruta de la imagen interior debe ser una ruta relativa, no una ruta absoluta, de lo contrario, se informará un error.

(2) Modificar en_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) compilar el proyecto

Cree un nuevo CMakeLists.txt en el directorio de trabajo camera_calibration_opencv:

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})

Después de compilar:

cd camera_calibration_opencv
mkdir build
cd build
cmake ..
make

(4) Ejecute el programa para la calibración

cd camera_calibration_opencv/build
./Camera_Calibration ../in_VID5.xml

Como dije antes al modificar la suma, VID5.xmluse in_VID5.xmluna ruta relativa en lugar de una ruta absoluta, de lo contrario ocurrirá un error:
Input does not exist: VID5.xmlInvalid input detected

Entonces necesita saber cuál es la ruta actual cuando usa una ruta relativa.La ruta actual es Camera_Calibrationla ruta donde su terminal ejecuta el archivo ejecutable, por ejemplo:

# 运行方法一:
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

Después de una operación exitosa, las imágenes de calibración se mostrarán en secuencia y el error de reproyección se mostrará en el terminal. Cuanto menor sea el error, mejor. Aquí es 0.3. Si es demasiado grande, tome una foto nuevamente.

Re-projection error reported by calibrateCamera: 0.299492
Calibration succeeded. avg re projection error = 0.299491

(5) Complete el archivo de configuración SETTINGS_FILE de ORB-SLAM3

Cuando ejecute con éxito el programa de calibración, el archivo de resultados de la referencia interna de la cámara se generará en el mismo directoriocamera_calibration_opencv/build/out_camera_data.xml

Abra y encuentre los parámetros internos de la cámara dentro:

  • <camera_matrix type_id="opencv-matrix">es la matriz de referencia interna de la cámara, el orden es fx, 0, cx; 0, fy, cy; 0, 0, 1.
  • <distortion_coefficients type_id="opencv-matrix">es el parámetro de distorsión, su orden es k1, k2, p1, p2, k3.

Luego ORB_SLAM3/Examples/Monocularcópielo debajo de la ruta TUM1.yaml, asígnele un nombre AndroidPhone.yamly complete los parámetros internos de la cámara:

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. Ejecute 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的绝对路径

Visualización del efecto de ejecución:

imagen

Nota: ORB-SLAM3 Mono aún es relativamente difícil de inicializar (sus condiciones de inicialización son relativamente duras). Al principio, seleccione un área con texturas ricas en características, no gire únicamente y mueva la cámara hacia arriba, abajo, izquierda y derecha. , que es propicio para la inicialización.

Supongo que te gusta

Origin blog.csdn.net/caiqidong321/article/details/130811051
Recomendado
Clasificación