あけましておめでとうございます!今年もよろしくお願いします.
2018年の抱負から始めるべきだったのですが,昨年やり残してたアイテムの備忘録も兼ねて,新年一発目の投稿はSFMで行きます.
で,以前の投稿
では,Mastering OpenCVのサンプルコードを使ってSFMを実施しようとしたのですが,これだとアルゴリズムの実装がストレートすぎて,自前のカメラで撮影した写真の対応は難しそうです...何回やっても計算がいい感じに収束しませんでした.ただ,シンプルな作りになっているので,アルゴリズムの基本的な流れの理解にはとても役立つと思います.
で,自前のカメラで実用に耐えられるSFMのコードを探しました.いくつか候補はあったのですが,コードがメンテされているとのことで,下記のサイトを参考にして OpenMVG を題材に今後の作業を進めていくことにしました.
画像から3次元形状を復元!OpenMVGでSfMを試してみた - 株式会社CFlatの明後日スタイルのブログ
0. 目論見
今年のつくばチャレンジでは,SFM (Structure From Motion) とMVS (Multi View Stereo) の技術を自律走行に生かせないかなあと思っています.具体的には,
1. つくばチャレンジのコースを一眼レフカメラでいっぱい撮影して三次元マップをオフライン生成.
2. オフライン生成したマップ情報を元に,ロボットのカメラ(低解像度)で撮影した画像を合わせこみ.オンラインで自己位置推定.
という感じで,攻めたいと思っています.が,いまやっていることより難易度が上がるので,頭がついて行けばいいのですが,,,
1. コードのダウンロード
落としてきたコードは下記のものです.どちらのコードも整理されていますが,結構大きい&難しいことをやっているので,中身を理解するまでには時間が掛かりそうですが,,
OpenMVG
OpenMVS
Eigen-3.2.10
http://bitbucket.org/eigen/eigen/get/3.2.10.zip
※Eigenのバージョンは3.2.xでないとダメです.3.3.xだと,OpenMVSのメッシュ化のところでこけます.
VCGLib
Ceres
2. コードのビルド
コードのビルドは下記の要領でできました.
(フォルダはホームフォルダから始める前提で書いてます.)
2-0 必要モジュールのインストール
(ちなみに,自分はROS Kineticを入れているので,ROSを入れてない人は他にもいくらかインストールしないと行けないかもしれません.)
cd sudo apt-get install libpng-dev libjpeg-dev sudo apt-get install libcgal-dev libcgal-qt5-dev sudo apt-get install meshlab sudo apt-get -y install freeglut3-dev libglew-dev libglfw3-dev
2-1. OpenMVG のビルド
OpenMVGは割とストレートにビルド完了まで行きました.
cd mkdir ~/workspace/reps/openmvg ~/workspace/reps/openmvg/build ~/workspace/reps/openmvg/install git clone https://github.com/openMVG/openMVG ~/workspace/reps/openmvg/dist cd ~/workspace/reps/openmvg/dist git submodule update -i cd ~/workspace/reps/openmvg/build cmake -DCMAKE_INSTALL_PREFIX=~/workspace/reps/openmvg/install ../dist/src/ make install -j8
3. OpenMVS のビルド
3-1 Eigen のビルド
cd hg clone https://bitbucket.org/eigen/eigen#3.2.10 workspace/reps/eigen-3.2.10/dist mkdir workspace/reps/eigen-3.2.10/build workspace/reps/eigen-3.2.10/install cd workspace/reps/eigen-3.2.10/build cmake -DCMAKE_INSTALL_PREFIX=~/workspace/reps/eigen-3.2.10/install/ ../dist/ make install
ここからはちょっと正しいかどうか怪しいのですが,Eigenの3.2.x系にEigen3Config.cmakeファイルがなかったので,Eigenの3.3.4をmake install した時に生成されるshare/eigen3のフォルダをコピーしてeigen-3.2.10/install/shareに持ってきました.つまり,,,
cd cp -r ~/workspace/reps/eigen-3.3.4/install/share/ ~/workspace/reps/eigen-3.2.10/install/
で,このままだとcmakeに認識されるバージョン情報が違ってしまうので,下記の変更を実施しました.
Eigen3Config.cmake
Before
set (EIGEN3_FOUND 1) set (EIGEN3_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/UseEigen3.cmake") set (EIGEN3_DEFINITIONS "") set (EIGEN3_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/eigen3") set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3") set (EIGEN3_ROOT_DIR "${PACKAGE_PREFIX_DIR}") set (EIGEN3_VERSION_STRING "3.3.4") set (EIGEN3_VERSION_MAJOR "3") set (EIGEN3_VERSION_MINOR "3") set (EIGEN3_VERSION_PATCH "4")
After
set (EIGEN3_FOUND 1) set (EIGEN3_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/UseEigen3.cmake") set (EIGEN3_DEFINITIONS "") set (EIGEN3_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/eigen3") set (EIGEN3_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/eigen3") set (EIGEN3_ROOT_DIR "${PACKAGE_PREFIX_DIR}") set (EIGEN3_VERSION_STRING "3.2.10") set (EIGEN3_VERSION "3.2.10") set (EIGEN3_VERSION_MAJOR "3") set (EIGEN3_VERSION_MINOR "2") set (EIGEN3_VERSION_PATCH "10") set (EIGEN_FOUND ${EIGEN3_FOUND}) set (EIGEN_USE_FILE ${EIGEN3_USE_FILE}) set (EIGEN_DEFINITIONS ${EIGEN3_DEFINITIONS}) set (EIGEN_INCLUDE_DIR ${EIGEN3_INCLUDE_DIR}) set (EIGEN_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIRS}) set (EIGEN_ROOT_DIR ${EIGEN3_ROOT_DIR}) set (EIGEN_VERSION_STRING ${EIGEN3_VERSION_STRING}) set (EIGEN_VERSION ${EIGEN3_VERSION}) set (EIGEN_VERSION_MAJOR ${EIGEN3_VERSION_MAJOR}) set (EIGEN_VERSION_MINOR ${EIGEN3_VERSION_MINOR}) set (EIGEN_VERSION_PATCH ${EIGEN3_VERSION_PATCH})
Eigen3ConfigVersion.cmake
Before
set(PACKAGE_VERSION "3.3.4") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() if("3.3.4" MATCHES "^([0-9]+)\\.") set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") else() set(CVF_VERSION_MAJOR "3.3.4") endif()
After
set(PACKAGE_VERSION "3.2.10") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() if("3.2.10" MATCHES "^([0-9]+)\\.") set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") else() set(CVF_VERSION_MAJOR "3.2.10") endif()
3-2 VCG のビルド
こいつはCMake&ビルド不要です.
cd git clone https://github.com/cnr-isti-vclab/vcglib.git ~/workspace/reps/vcg
3-3 Ceres Solver のビルド
cd git clone https://github.com/ceres-solver/ceres-solver.git ~/workspace/reps/ceres/dist mkdir ~/workspace/reps/ceres/build ~/workspace/reps/ceres/install cd ~/workspace/reps/ceres/build
で,せっかくEigenをインストールしたので,Ceresが参照するEigenのバージョンも下記のように変更してあげます.
変更する箇所は,ceres/dist/CMakeLists.txt以下の下記の部分です.
Before
find_package(Eigen REQUIRED)
After
set(Eigen3_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../eigen-3.2.10/install/share/eigen3/cmake") find_package(Eigen3 REQUIRED CONFIG PATHS ${Eigen3_DIR} NO_DEFAULT_PATH)
そしてビルドします.
cmake -DCMAKE_INSTALL_PREFIX=~/workspace/reps/ceres/install/ -DMINIGLOG=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=ON ../dist/ make install -j8
3-4 OpenMVSのビルド
ここまでくれば,ようやくOpenMVSのビルドです.
cd git clone https://github.com/cdcseacave/openMVS ~/workspace/reps/openmvs/dist mkdir ~/workspace/reps/openmvs/build ~/workspace/reps/openmvs/install
で,同じくCMakeLists.txtを変更してやる必要があります.
一つ目のCMakeLists.txtは~/workspace/reps/openmvs/dist/CMakeLists.txtです.変更内容はCeresの時と同じで,自分のローカルでビルドしたEigenとOpenCVを使うように設定します.
openmvs/dist/CMakeLists.txt
Before
FIND_PACKAGE(Eigen ${SYSTEM_PACKAGE_REQUIRED}) if(EIGEN_FOUND) INCLUDE_DIRECTORIES(${EIGEN_INCLUDE_DIRS}) ADD_DEFINITIONS(${EIGEN_DEFINITIONS} -D_USE_EIGEN) SET(_USE_EIGEN TRUE) endif() FIND_PACKAGE(OpenCV ${SYSTEM_PACKAGE_REQUIRED})
After
SET(Eigen3_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../eigen-3.2.10/install/share/eigen3/cmake") FIND_PACKAGE(Eigen3 ${SYSTEM_PACKAGE_REQUIRED} CONFIG PATHS Eigen3_DIR NO_DEFAULT_PATH) if(EIGEN3_FOUND) INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) ADD_DEFINITIONS(${EIGEN_DEFINITIONS} -D_USE_EIGEN) SET(_USE_EIGEN TRUE) endif() SET(OpenCV_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../opencv-3.1.0/install/share/OpenCV") FIND_PACKAGE(OpenCV ${SYSTEM_PACKAGE_REQUIRED} CONFIG PATHS ${OpenCV_DIR} NO_DEFAULT_PATH)
二つ目ののCMakeLists.txtは~/workspace/reps/openmvs/dist/libs/MVS/CMakeLists.txtです.gitからダウンロードした VCG と Ceres のパス設定をします.
dist/libs/MVS/CMakeLists.txt
VCG,Ceresのパス設定.
Before
FIND_PACKAGE(VCG ${SYSTEM_PACKAGE_REQUIRED}) if(VCG_FOUND) include_directories(${VCG_INCLUDE_DIRS}) add_definitions(${VCG_DEFINITIONS}) endif() FIND_PACKAGE(CERES ${SYSTEM_PACKAGE_REQUIRED}) if(CERES_FOUND) include_directories(${CERES_INCLUDE_DIRS}) add_definitions(${CERES_DEFINITIONS})
After
SET(VCG_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../../vcg/") include_directories(${VCG_INCLUDE_DIRS}) add_definitions(${VCG_DEFINITIONS}) SET(CERES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../ceres/install/lib/cmake/Ceres") FIND_PACKAGE(Ceres ${SYSTEM_PACKAGE_REQUIRED} CONFIG PATHS ${CERES_DIR} NO_DEFAULT_PATH) if(CERES_FOUND) include_directories(${CERES_INCLUDE_DIRS}) add_definitions(${CERES_DEFINITIONS})
あと,Ceres-Solverのリンクディレクトリ周りも少し修正が必要でした.
Before
TARGET_LINK_LIBRARIES(MVS Common Math IO ${CERES_LIBS} ${CGAL_LIBS} ${CUDA_CUDA_LIBRARY})
After
LINK_DIRECTORIES("${CERES_DIR}/../../") TARGET_LINK_LIBRARIES(MVS Common Math IO ceres ${CGAL_LIBS} ${CUDA_CUDA_LIBRARY})
で,ビルドが通ります.
cd cd ~/workspace/reps/openmvs/build cmake -DCMAKE_INSTALL_PREFIX=~/workspace/reps/openmvs/install ../dist/ make install -j8
ふーーーー.記事にまとめようとすると,時間かかりますね...次は実際に自分の一眼レフでとった写真を復元します.