轉載請注明出處,謝謝
原創作者:Mingrui
原創鏈接:https://www.cnblogs.com/MingruiYu/p/12425855.html
本文要點:
- dso 配置安裝
- dso 離線數據集運行示例
- dso_ros 配置安裝
- 解決報錯
DSO missing from command line
- 解決運行時報錯
Couldn't find executable named dso_live
- 解決報錯
- 手機攝像頭標定
- 參數以相應格式填入 DSO 的相機標定文件
- 以 Android 手機攝像頭為輸入,實時運行 DSO
- 關於運行提示
could not parse argument "mode=1"!!
- 關於運行提示
寫在前面
之前認真研讀了 ORB-SLAM2 論文和代碼(ORB-SLAM2 系列博文),也實現了以 Android 手機攝像頭為輸入,實時運行 ORB-SLAM2(ORB-SLAM2 運行 —— ROS + Android 手機攝像頭)。這幾天在了解直接法 SLAM,先閱讀了 LSO-SLAM 的論文,因為其是14年的,開源代碼還是基於 ROS indigo + Ubuntu 14.04,所以就不跑了。之后閱讀了 DSO 的論文,決定仿照之前 ORB-SLAM2 的學習過程,也以 Android 手機攝像頭為輸入,實時運行 DSO 試一試。
本文環境為:
- Ubuntu 18.04
- ROS Melodic
- Android 手機(MI 9 SE)
DSO 簡介
DSO: Direct Sparse Odometry 為 TUM Vision Group 介紹 DSO 的網站,其中包括論文鏈接。
ROS 配置安裝
參照 ROS 官方安裝教程 和我的博文 ORB-SLAM2 運行 —— ROS + Android 手機攝像頭。
DSO 配置安裝
參照 JakobEngel/dso (GitHub 文檔):
下載 DSO
為方便后續跑 dso_ros,先建立一個 catkin workspace:
mkdir -p YOUR_PATH/catkin_ws/src
cd YOUR_PATH/catkin_ws
catkin_make
cd src
git clone https://github.com/JakobEngel/dso.git
依賴安裝
基礎依賴
sudo apt-get install libsuitesparse-dev libeigen3-dev libboost-all-dev
OpenCV & Pangolin
之前跑 ORB-SLAM2 的時候已經安裝過了,還沒裝過的朋友可以參考我的博文 ORB-SLAM2 初體驗 —— 配置安裝。
ziplib
用於直接讀取 zip 壓縮文件中的圖像(例如在 TUM monoVO dataset 就是 zip 文件),為了方便。否則只能先手動解壓縮。既然人家建議,就裝了吧:
sudo apt-get install zlib1g-dev
cd dso/thirdparty
tar -zxvf libzip-1.1.1.tar.gz
cd libzip-1.1.1/
./configure
make
sudo make install
sudo cp lib/zipconf.h /usr/local/include/zipconf.h # (no idea why that is needed).
安裝 DSO
cd dso
mkdir build
cd build
cmake ..
make -j4
DSO 的安裝到這里就結束了,比較簡單的。
離線數據集運行示例
數據集下載:(https://vision.in.tum.de/mono-dataset),每個視頻序列文件夾以 sequence_XX 命名,其中包括了 image.zip(視頻序列), camera.txt(相機內參及畸變參數等), pcalib.txt, vignette.png (二者為 photometric calibration 的標定參數,詳見論文)文件。
(photometric calibration:光度標定,是 TUM Vision Group 提出的一種相機除了幾何標定之外的光度參數的標定方法,詳細內容可參考)
運行:
cd dso
./build/bin/dso_dataset \
files=XXXXX/sequence_XX/images.zip \
calib=XXXXX/sequence_XX/camera.txt \
gamma=XXXXX/sequence_XX/pcalib.txt \
vignette=XXXXX/sequence_XX/vignette.png \
preset=0 \
mode=0
其中的參數:
- 前4項就是視頻序列文件夾中的文件。
- preset 表示系統以何種方式運行(默認模式/快速模式,非實時/實時),preset=0 表示默認模式且可以非實時。
- mode 表示相機的標定情況,mode=0 表示相機完全標定(包括幾何標定和 photometric 標定)。
- 更詳細的內容還有其它的一大堆參數的具體含義詳見 (https://github.com/JakobEngel/dso#3-usage)。
運行效果展示:

dso_ros 安裝
以上的過程我都進行的非常順利,然而接下來就是踩坑之旅了。
JakobEngel/dso repo 本身是沒有 ROS 支持的,但是 TUM Vision Group 單獨在 GitHub 上建了一個 dso_ros 的 repo,其提供了 DSO 的 ROS 接口。
下載 dso_ros
cd YOUR_PATH/catkin_ws/src
git clone https://github.com/JakobEngel/dso_ros.git
修改 CMakeLists.txt
這里很重要了,否則在之后安裝或者運行的時候會報錯
1 CMakeLists.txt 倒數第二行:
target_link_libraries(dso_live ${DSO_LIBRARY} ${Pangolin_LIBRARIES} ${OpenCV_LIBS} -lboost_system)
尾部添加 -lboost_system
(上述代碼為添加后的)。
如果不進行這一步,會在編譯的時候報錯 DSO missing from command line
。
2 CMakeLists.txt 中的
set(EXECUTABLE_OUTPUT_PATH bin)
修改為
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
修改之前,編譯生成的可執行文件 dso_live 的位置為 dso_ros/build/bin,但這樣的話在運行的時候會報錯:
Couldn't find executable named dso_live below YOUR_PATH/catkin_ws/src/dso_ros
修改后,dso_live 的位置變為 dso_ros/bin,運行的時候就可以找到了。參考資料
安裝 dso_ros
cd YOUR_PATH/catkin_ws
source devel/setup.bash
cd src/dso_ros
export DSO_PATH=YOUR_PATH/dso
rosmake
Android 手機攝像頭與 PC 進行基於 ROS 的通信
參考我的博文 ORB-SLAM2 運行 —— ROS + Android 手機攝像頭 其中的“Android 手機攝像頭與 PC 進行基於 ROS 的通信”一節。
手機攝像頭標定
參考我的博文 ORB-SLAM2 運行 —— ROS + Android 手機攝像頭 其中的“手機攝像頭標定”一節。
注意: 在 ORB-SLAM2 中,系統所需的相機畸變參數為 k1, k2, p1, p2, k3。而在 DSO 中,系統所需的相機畸變參數為 k1, k2, p1, p2。所以需要在標定環節中修改 VID5.xml 時,將 <Fix_K3>0</Fix_K3>
的 0 該為 1,這樣就會保持 k3 = 0,使得得到的畸變參數滿足 DSO 系統的要求。
參數填入 DSO 的相機標定文件
在某處建立一個 myCamera.txt 文件,用於按照 DSO 要求的格式存放相機的參數。
myCamera.txt 文件格式可參考 DSO/Geometric Calibration File,其中有很多不同情況的例子。具體到本實現中,該標定文件的內容格式可為
fx fy cx cy k1 k2 p1 p2
640 480
crop
640 480
(因為上文中手機端傳回來的視頻流的分辨率為640*480)
(這一部分我也沒太懂,官方文檔中的那些情況都具體怎么用,為什么在 TUM monoVO dataset 中 camera.txt 第一行的 fx 和 第三行的 fx 值不一樣,crop/full 都具體指什么,in_width/out_width 對實際效果有什么影響。歡迎大佬指教 QAQ)
以 Android 手機攝像頭為輸入,實時運行 DSO
Terminal 1:
roscore
手機進入 app 運行
Terminal 2: 在 Android_Camera-IMU 目錄
roslaunch android_cam-imu.launch
(可以關掉 Rviz)
Terminal 3:
rosrun dso_ros dso_live image:=/camera/image_raw calib=YOUR_PATH/myCamera.txt
注意: 因為我們沒有對相機進行 photometric calibration,所以我們只能提供幾何標定的標定文件。其它的省略就可以了。
關於 mode=1
一個很神奇的地方,按照 dso 文檔的說法,沒有 photometric calibration 的話,需要在運行指令中添加 mode=1。一開始我也這樣做的,但是提示:could not parse argument "mode=1"!!
。然后我發現,在 dso_ros/src/main.cpp 中,parseArgument() 中並沒有 mode 和 preset 參數,也就是根本沒有定義這些參數(迷惑)。參考資料
再仔細一看,在 dso/src/main_dso_pangolin.cpp(offline DSO)中,mode=1 的作用是修改了 setting_photometricCalibration = 0。setting_photometricCalibration 的含義為
- 0 = nothing.
- 1 = apply inv. response.
- 2 = apply inv. response & remove V.
在 DSO 系統中,setting_photometricCalibration 默認為2,即有 photometric calibration,可以通過在運行指令中添加 mode=1 修改。而在 dso_ros/src/main.cpp 中,直接指定了 setting_photometricCalibration=2,沒有提供修改選項。這可能是因為如官方說法,dso_ros 只是一個最簡版本的 ROS 接口(simple, minimal example),所以很多支持都不完善吧。
這個自己添加選項很容易,這里我圖省事,就直接將 dso_ros/src/main.cpp 中的 setting_photometricCalibration=2 改為了 =0。之后重新編譯 dso_ros。
運行效果展示:

發現:
- 初始化比 ORB-SLAM2 Mono 容易多了
- 軌跡很飄,建圖還行
簡化啟動
上述啟動步驟需要啟動3個終端,挺麻煩的,所以可以選擇寫一個腳本來自動啟動這3個終端。參考資料
新建 DSO_with_AndroidPhone.sh,在其中填入:
gnome-terminal --title="roscore" -x bash -c "roscore"
sleep 2s;
gnome-terminal --title="AndroidPhone" -x bash -c "cd YOUR_PATH/Android_Camera-IMU; roslaunch android_cam-imu.launch"
sleep 2s;
gnome-terminal --title="DSO" -x bash -c "rosrun dso_ros dso_live image:=/camera/image_raw calib=YOUR_PATH/myCamera.txt"
之后賦予權限(僅需一次):
chmod +x DSO_with_AndroidPhone.sh
運行:
./DSO_with_AndroidPhone.sh
即可一次性打開3個終端,並運行相關命令。之后手機再打開 app 就可以了。
注意: 此時終端運行結束后會自動退出,如果不想自動退出,可 在terminal點右鍵,選擇Profiles->Profile Preferences然后找到Title and Command,里面有一項When command exits,后面選擇為Hold the terminal open。參考資料