Help us understand the problem. What is going on with this article?

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をやる。

関連記事

SatoshiGachiFujimoto
高専で制御を学び、大学でセンシングを学び、次は脳みそ。SLAMに関連したロボット/ドローンやMRの研究開発をしています。
https://www.gachimoto.com
knowledgecommunication-inc
クラウドインテグレーター、AI・VRの分野で様々なソリューションを展開
http://www.knowledgecommunication.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away