Edited at

OpenCV 3.1 SfMモジュール (Visual Studio 2013)

More than 3 years have passed since last update.

OpenCV3.1にはSfM(Structure from Motion)モジュールが新たに追加されたが、CMakeしてもCeres solverを見つけてくれない。

そもそも、


The module is only available for Linux/GNU systems.


とあった。

ウソだ… Windowsでやってみた


システム環境


  • OpenCV 3.1

  • Visual Studio 2013

  • Windows 8.1

  • CMake 3.2


GLog



  1. GLog 0.3.3をダウンロードする。

  2. 解凍したら、google-glog.slnを開き、ビルドする。

  3. DebugとReleaseにそれぞれlibglog.dll, libglog.libが生成される。


logging.ccのエラー

#include <algorithm>

を追記し、

Ln1386, 1387の

const int copy = min<int>(data_->num_chars_to_log_,

sizeof(fatal_message)-1);

を以下のように変更すると通った。

const int copy = std::min<int>(data_->num_chars_to_log_,

sizeof(fatal_message)-1);


GFlags

1. GFlagsをダウンロードする。

2. CMakeを起動し、

ソース先: C:\gflags-master

ビルド先: C:\gflags-master\build

と指定し、configure, そしてgenerateする。

3. build下に生成されたgflags.slnを開き、ビルドする。

4. gflags.libが生成される。


Ceres Solver



  1. Ceres Solverをダウンロードする。

  2. 先ほどコンパイルしたGLogのソースをceres-windows-masterにコピペする。

  3. また、latest stable releaseからダウンロードしたceres-solverをceres-windows-masterにコピペする。

  4. さらに、Eigenをceres-windows-masterにコピペする。
    EigenはPCL1.7.2に付属しているものを使用している。

  5. ceres-2012.slnを開き、ビルドする。

  6. Win32\DebugとWin32\Releaseにそれぞれceres.dll, ceres.libが生成される。


libmv

libmvはSfMライブラリであるが、OpenCV3.1では、SfMモジュールの中にlight版(libmv_light)が作成されている。その中に、Ceres Solverを用いたSimple Pipelineが追加されている。



  1. libmvをダウンロードする。(Eigen3に対応)
    これはCMakeできず、これはEigen2に対応。

  2. 解凍したlibmv-master\srcのlibmvとthird_partyをSfMモジュールのlibmv_light(opencv_contrib-master\modules\sfm\src\libmv_light\libmv)に合わせて変更していく。


libmv-master\src\libmvを変更


base

libmv_light\libmv\baseの


  • vector.h

  • vector_utils.h

をlibmv-master\src\libmv\baseに上書き。


correspondence

libmv_light\libmv\correspondenceの


  • bipartite_graph.h

  • feature.h

  • feature_matching.cc

  • feature_matching.h

  • matches.cc

  • matches.h

  • nRobustViewMatching.cc

  • nRobustViewMatching.h

  • nViewMatchingInterface.h

をlibmv-master\src\libmv\correspondenceに上書き。

CMakeLists.txtを以下のように変更する。

# define the source files

SET(CORRESPONDENCE_SRC matches.cc
feature_matching.cc
nRobustViewMatching.cc)

# define the header files (make the headers appear in IDEs.)
FILE(GLOB CORRESPONDENCE_HDRS *.h)

ADD_LIBRARY(correspondence ${CORRESPONDENCE_SRC} ${CORRESPONDENCE_HDRS})

# make the name of debug libraries end in _d.
SET_TARGET_PROPERTIES(correspondence PROPERTIES DEBUG_POSTFIX "_d")

TARGET_LINK_LIBRARIES(correspondence multiview)

# installation rules for the library
LIBMV_INSTALL_LIB(correspondence)

# LIBMV_TEST(klt "correspondence;image;numeric")
# LIBMV_TEST(bipartite_graph "")
# LIBMV_TEST(kdtree "")
# LIBMV_TEST(feature_set "correspondence;image;numeric")
# LIBMV_TEST(matches "correspondence;image;numeric")
# LIBMV_TEST(Array_Matcher "correspondence;numeric;flann")
# LIBMV_TEST(tracker "correspondence;reconstruction;numeric;flann")


multiview

libmv_light\libmv\multiviewの


  • conditioning.cc

  • conditioning.h

  • euclidean_resection.cc

  • euclidean_resection.h

  • fundamental.cc

  • fundamental.h

  • fundamental_kernel.cc

  • fundamental_kernel.h

  • homography.cc

  • homography.h

  • homography_error.h

  • homography_parameterization.h

  • nviewtriangulation.h

  • panography.cc

  • panography.h

  • panography_kernel.cc

  • panography_kernel.h

  • projection.cc

  • projection.h

  • random_sample.h

  • resection.h

  • resection_kernel.h

  • robust_estimation.cc

  • robust_estimation.h

  • robust_fundamental.cc

  • robust_fundamental.h

  • robust_resection.cc

  • robust_resection.h

  • triangulation.cc

  • triangulation.h

  • two_view_kernel.h

  • twoviewtriangulation.cc

  • twoviewtriangulation.h

をlibmv-master\src\libmv\multiviewに上書き。

CMakeLists.txtを以下のように変更する。

# define the source files

SET(MULTIVIEW_SRC conditioning.cc
euclidean_resection.cc
fundamental.cc
fundamental_kernel.cc
homography.cc
panography.cc
panography_kernel.cc
projection.cc
robust_estimation.cc
robust_fundamental.cc
robust_resection.cc
triangulation.cc
twoviewtriangulation.cc)

# define the header files (make the headers appear in IDEs.)
FILE(GLOB MULTIVIEW_HDRS *.h)

ADD_LIBRARY(multiview ${MULTIVIEW_SRC} ${MULTIVIEW_HDRS})

TARGET_LINK_LIBRARIES(multiview numeric V3D colamd ldl)

# make the name of debug libraries end in _d.
SET_TARGET_PROPERTIES(multiview PROPERTIES DEBUG_POSTFIX "_d")

# installation rules for the library
LIBMV_INSTALL_LIB(multiview)

#IF (BUILD_TESTS)
#ADD_LIBRARY(multiview_test_data
# test_data_sets.cc)
# make the name of debug libraries end in _d.
#SET_TARGET_PROPERTIES(multiview_test_data PROPERTIES DEBUG_POSTFIX "_d")
#ENDIF (BUILD_TESTS)

#MACRO (MULTIVIEW_TEST NAME)
# LIBMV_TEST(${NAME} "multiview_test_data;multiview;numeric")
#ENDMACRO (MULTIVIEW_TEST)

#MULTIVIEW_TEST(projection)
#MULTIVIEW_TEST(triangulation)
#MULTIVIEW_TEST(fundamental)
#MULTIVIEW_TEST(fundamental_kernel)
#MULTIVIEW_TEST(fundamental_parameterization)
#MULTIVIEW_TEST(homography)
#MULTIVIEW_TEST(homography_error)
#MULTIVIEW_TEST(homography_kernel)
#MULTIVIEW_TEST(homography_parameterization)
#MULTIVIEW_TEST(panography)
#MULTIVIEW_TEST(focal_from_fundamental)
#MULTIVIEW_TEST(nviewtriangulation)
#MULTIVIEW_TEST(resection)
#MULTIVIEW_TEST(resection_kernel)
#MULTIVIEW_TEST(robust_homography)
#MULTIVIEW_TEST(robust_fundamental)
#MULTIVIEW_TEST(robust_estimation)
#MULTIVIEW_TEST(sixpointnview)
#MULTIVIEW_TEST(bundle)
#MULTIVIEW_TEST(autocalibration)
#MULTIVIEW_TEST(five_point)
#MULTIVIEW_TEST(five_point_kernel)
#MULTIVIEW_TEST(essential_kernel)
#MULTIVIEW_TEST(affine)
#MULTIVIEW_TEST(affine_kernel)
#MULTIVIEW_TEST(affine_parameterization)
#MULTIVIEW_TEST(robust_affine)
#MULTIVIEW_TEST(euclidean_resection)
#MULTIVIEW_TEST(euclidean_resection_kernel)
#MULTIVIEW_TEST(robust_euclidean_resection)
#MULTIVIEW_TEST(twoviewtriangulation)
#MULTIVIEW_TEST(robust_resection)
#MULTIVIEW_TEST(similarity)
#MULTIVIEW_TEST(similarity_kernel)
#MULTIVIEW_TEST(similarity_parameterization)
#MULTIVIEW_TEST(robust_similarity)
#MULTIVIEW_TEST(euclidean)
#MULTIVIEW_TEST(euclidean_kernel)
#MULTIVIEW_TEST(euclidean_parameterization)
#MULTIVIEW_TEST(robust_euclidean)
#MULTIVIEW_TEST(rotation_parameterization)

# TODO(keir): Make tests that depend on generated.cc to use generated sources.
#ADD_GENERATED_SOURCE(generated.cc generator.py)


numeric

libmv_light\libmv\numericの


  • function_derivative.h

  • levenberg_marquardt.h

  • numeric.cc

  • numeric.h

  • poly.cc

  • poly.h

をlibmv-master\src\libmv\numericに上書き。


simple_pipeline

libmv-master\src\libmv\にはsimple_pipelineが存在しないので、libmv_light\libmv\simple_pipelineをコピペ。

CMakeLists.txtを以下のように変更する。

SET(SIMPLE_PIPELINE_SRC

bundle.cc
camera_intrinsics.cc
distortion_models.cc
initialize_reconstruction.cc
intersect.cc
keyframe_selection.cc
pipeline.cc
reconstruction.cc
reconstruction_scale.cc
resect.cc
tracks.cc
)

# Define the header files so that they appear in IDEs.
FILE(GLOB SIMPLE_PIPELINE_HDRS *.h)

ADD_LIBRARY(simple_pipeline STATIC ${SIMPLE_PIPELINE_SRC} ${SIMPLE_PIPELINE_HDRS})

TARGET_LINK_LIBRARIES(simple_pipeline multiview)

LIBMV_INSTALL_LIB(simple_pipeline)


libmv-master\src\third_partyの変更


eigen

ceres-windows-master\Eigenの


  • Eigen

  • unsupported

をlibmv-master\src\third_party\eigenに上書き。


glog

ceres-windows-master\glog\src\glogの


  • log_severity.h

  • logging.h.in

  • raw_logging.h.in

  • stl_logging.h.in

  • vlog_is_on.h.in

をlibmv-master\src\third_party\glog\src\glogに上書き。


libmvのコンパイル


  1. CMakeを開き、
    ソース先: C:\libmv-master\src
    ビルド先: C:\libmv-master\src\build
    としてconfigure, そしてgenerateする。

  2. build下に生成されたLIBMV.slnを起動し、correspondence, gflags, multiview, numeric, simple_pipelineのみビルドする。


  • correspondenceのプロパティから追加のインクルードディレクトリに追記する。

C:\ceres-windows-master\glog\src\windows;

$(OPENCV_DIR)\build\include;


  • multiviewのプロパティから追加のインクルードディレクトリに追記する。

C:\ceres-windows-master\glog\src\windows;


  • simple_pipelineのプロパティから追加のインクルードディレクトリに追記する。

C:\ceres-windows-master\glog\src\windows;

C:\ceres-windows-master\win\include;
C:\ceres-windows-master\ceres-solver\include;

ビルドに成功すれば、

correspondence_d.lib

correspondence.lib
gflags_d.lib (debugでビルドするときgflags.libなので名前を変更)
gflags.lib
multiview_d.lib
multiview.lib
numeric_d.lib
numeric.lib
simple_pipeline_d.lib (debugでビルドするときsimple_pipeline.libなので名前を変更)
simple_pipeline.lib

が生成される。


プログラム作成

これで準備が整ったので、実際のSfMモジュールのサンプルプログラムを動かしてみる。


Camera Motion Estimation


ヘッダーファイル

C:\opencv_contrib-master\modules\sfm\srcの


  • libmv_capi.h

を用いる。

libmv_capi.hに以下を追記する。

#define snprintf _snprintf

#define CERES_FOUND 1

#include <opencv2/opencv.hpp>
#include <opencv2/sfm.hpp>
#include <opencv_lib.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>


ソースファイル

C:\opencv_contrib-master\modules\sfm\samplesの


  • trajectory_reconstruccion.cpp

をmain.cppとする。

また、C:\opencv_contrib-master\modules\sfm\srcの


  • conditioning.cpp

  • fundamental.cpp

  • numeric.cpp

  • projection.cpp

  • reconstruct.cpp

  • robust.cpp

  • simple_pipeline.cpp

  • triangulation.cpp

を用いる。

main.cppに以下を追記する。

#include <opencv_lib.hpp>

main.cpp, reconstruct.cpp, simple_pipeline.cppに以下を追記する。

#define CERES_FOUND 1


追加のインクルードディレクトリ(Release)

C:\ceres-windows-master\Eigen;

C:\ceres-windows-master\glog\src\windows;
C:\ceres-windows-master\glog\src;
C:\ceres-windows-master\win\include;
C:\ceres-windows-master\ceres-solver\include;
C:\libmv-master\src;
C:\libmv-master\src\third_party;
$(OPENCV_DIR)\build\include;


追加のライブラリディレクトリ(Release)

C:\ceres-windows-master\glog\Release;

C:\ceres-windows-master\Win32\Release;
C:\libmv-master\src\build\lib;
$(OPENCV_DIR)\build\lib;


追加の依存ライブラリ(Release)

ceres.lib

libglog.lib
gflags.lib
correspondence.lib
multiview.lib
numeric.lib
simple_pipeline.lib


実行結果

プロジェクトの下に、ceres.dll, libglog.dll, opencv_contrib-master\modules\sfm\samples\data\desktop_tracks.txtをコピペする。

プロジェクトのプロパティ->デバッグ->コマンド引数に

desktop_tracks.txt 1914 640 360

を入力する。

Releaseで実行した結果を以下に示す。

sfm1.png

sfm2.png

sfm3.png

s: カメラ座標とワールド座標の視点切り替え

q: 終了

Debugではビルドできたが、実行したらエラーが出た。

err.png

次は、Scene Reconstructionをやる。


関連記事