OpenCV3.1にはSfM(Structure from Motion)モジュールが新たに追加されたが、CMakeしてもCeres solverを見つけてくれない。
そもそも、
とあった。
ウソだ… Windowsでやってみた
システム環境
- OpenCV 3.1
- Visual Studio 2013
- Windows 8.1
- CMake 3.2
GLog
- GLog 0.3.3をダウンロードする。
- 解凍したら、google-glog.slnを開き、ビルドする。
- 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
- Ceres Solverをダウンロードする。
- 先ほどコンパイルしたGLogのソースをceres-windows-masterにコピペする。
- また、latest stable releaseからダウンロードしたceres-solverをceres-windows-masterにコピペする。
- さらに、Eigenをceres-windows-masterにコピペする。
EigenはPCL1.7.2に付属しているものを使用している。 - ceres-2012.slnを開き、ビルドする。
- Win32\DebugとWin32\Releaseにそれぞれceres.dll, ceres.libが生成される。
libmv
libmvはSfMライブラリであるが、OpenCV3.1では、SfMモジュールの中にlight版(libmv_light)が作成されている。その中に、Ceres Solverを用いたSimple Pipelineが追加されている。
-
libmvをダウンロードする。(Eigen3に対応)
これはCMakeできず、これはEigen2に対応。 - 解凍した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のコンパイル
- CMakeを開き、
ソース先: C:\libmv-master\src
ビルド先: C:\libmv-master\src\build
としてconfigure, そしてgenerateする。 - 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
を入力する。
s: カメラ座標とワールド座標の視点切り替え
q: 終了
次は、Scene Reconstructionをやる。