PCを新調してできることが増えたので色々遊び始める。
さっそくOpenCV 3.1をopencv_contribのモジュールも含めてビルドしてみようと思う。目当ては特にSfMモジュール。
Windows環境でx64ビルドするための手順をメモしておく。
オイラの環境は
- Windows 10 Pro
- Visual Studio Community 2015
OpenCVのビルド
こちらの記事を参考に、OpenCVをソースコードからWindows用にビルドしてみる。↓
http://qiita.com/SatoshiRobatoFujimoto/items/21d74912a7752b9e6ca4
http://qiita.com/fukushima1981/items/961918db7835160cdde5
2017年1月25日 追記:Qittaの記事を参考に再挑戦しました。↓
材料のダウンロード
まず、OpenCV3.1本体とopencv_contribのソースコードを以下からダウンロードする。
そして、依存ライブラリのEigen, VTKのソースコードもダウンロードする。
SfMモジュールのサンプルコードではvizモジュールを使うようなので、vizモジュールを有効にするために依存ライブラリにVTKも入れておくのです。
最近のVisual Studio環境ならIntel TBBを入れなくても速度的に十分らしいのでTBBのビルドはやめておく。また、CUDAはVisual Studio 2015に対応していないようなのでCUDAのビルドも諦める。
Eigenは現時点での最新バージョンの3.2.8をダウンロード。Eigenはビルドの必要なし。
VTK6.3.0の設定・ビルド
VTKは最新バージョンの7.0.0ではなく、1つ前のバージョンのVTK6.3.0を使う。現状、7.0.0ではOpenCVのビルドが上手くいかない。
CMakeのGUIツールを使ってお手軽に設定してしまう。基本的にはデフォルト設定のままで良いけど、インストール先は指定のディレクトリにしたかったのでCMAKE_INSTALL_PREFIXだけは変更しておいた。Configure, Generateと順に押して、VTKビルド用のVisual Studioソリューションを生成する。
ソリューションを開いてALL_BUILD, INSTALLプロジェクトをビルドすれば、先ほどCMAKE_INSTALL_PREFIXで指定したディレクトリにVTK一式が出力される。
CMakeでOpenCVのビルド設定
先ほどダウンロードしたOpenCV3.1本体のソースコードをCMakeで開き、設定していく。
OPENCV_EXTRA_MODULE_PATHに先ほどダウンロードしたopencv_contrib内の”module”ディレクトリまでのパスを入力。
WITH_VTKにチェックを入れ、VTK_DIRに先ほどビルドしたVTKのインストールディレクトリ下”/lib/cmake/vtk-6.3″までのパスを入力。Configureを押すと、opencv_contribのモジュールと、vizモジュールのチェックボックスが出てくるので、チェックを入れてConfigureを押す。VTKの時と同じように、CMAKE_INSTALL_PREFIXを設定しておけば任意のディレクトリにインストールできる。オイラは”C:\dev\opencv-3.1.0\install”としておいた。
設定が済み、エラーが消えたらGenerateを押す。
ビルド・インストール
生成されたVisual Studio 2015ソリューションを開き、ALL_BUILDとINSTALLプロジェクトをビルド。Windowsの環境変数に以下を設定すればOpenCVのインストール完了。
変数 | 値 |
---|---|
Path | %OPENCV_DIR%\bin; |
OPENCV_DIR | C:\dev\opencv-3.1.0\install |
OPENCV_VER | 310 |
なのだが、この段階ではまだSfMモジュールはビルドに含まれていない。Windows環境では、もうひと手間かけないとSfMモジュールのビルドができないらしい。
SfMモジュールのビルド
ということで、SfMモジュールのビルドはここを参考にする。↓
http://qiita.com/SatoshiRobatoFujimoto/items/c87b14cd20cda3c97306
この記事とオイラの環境は少し違うで、いくつか追加で修正が必要だった。
材料のダウンロード
SfMモジュールのビルドには、以下のライブラリが必要となる。
それぞれそのままビルドできるかというとそうでもなく、いくつかコードの修正等が必要となる。
GLogの修正・ビルド
普通にCMakeでVisual Studioソリューションを生成し、ビルドしようとするとlogging.ccでエラーになる。
参考記事にならって
#include <algorithm>
を追記し、
1386, 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);
オイラの環境ではそれでもまだエラーは消えなくて、1444行目あたりの
_asm int 3
を
__debugbreak;
へ書き換え、
さらにport.ccの
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
va_start(ap, format);
const int r = vsnprintf(str, size, format, ap);
va_end(ap);
return r;
}
を
#if _MSC_VER < 1900
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
va_start(ap, format);
const int r = vsnprintf(str, size, format, ap);
va_end(ap);
return r;
}
#endif
へ書き換えてやっとビルドできた。Visual Studio2015ではsnprintfが標準で定義されているようなので別途定義する必要がないらしい。_MSC_VERの条件で有効・無効を切り替えて対応した。
GFlagsのビルド
GFlagsは特に苦労することなく普通にCMakeでVisual Studioソリューションを生成してビルドできた。
Ceres Solverのビルド
Ceres SolverをWindowsビルドできるようカスタマイズされたceres-windowsをベースに使う。
ダウンロードしたceres-windowsを展開したディレクトリ内の”glog”ディレクトリへ先ほどビルドできるよう書き換えたGLogのソースコードをコピーする。
オリジナルのCeres Solverのlatest stable releaseをダウンロードしてきて、同じくceres-windows下の”ceres-solver”ディレクトリへ配置する。
同様にEigenもceres-windows下の”Eigen”ディレクトリへ配置する。
Visual Studio2015でceres-2012.slnを開き、x64設定してビルドすると、x64\Debugとx64\Releaseにそれぞれceres.dll, ceres.libが生成される。
libmv_lightに合わせてlibmvを修正・ビルド
ここが1番面倒な作業。
opencv_contribのSfMモジュールの中に、SfMライブラリ libmvを軽量化したlibmv_lightが含まれており、その中のSimple PipelineはCeres Solverに依存している。そのため、まずはCeres SolverをWindows用にビルドする必要があったのだ。
ここでは参考記事にならってlibmvをlibmv_lightに合わせて修正し、ビルドすることにする。ダウンロードしたlibmvを展開したlibmv-masterディレクトリをベースに進めていく。
libmv-master/src/libmvを変更
base
opencv_contrib SfMモジュール内のsrc/libmv_light/libmv/baseの
- vector.h
- vector_utils.h
をlibmv-master/src/libmv/baseに上書き。
correspondence
opencv_contrib SfMモジュール内のsrc/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
opencv_contrib SfMモジュール内のsrc/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
opencv_contrib SfMモジュール内のsrc/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が存在しないので、opencv_contrib SfMモジュール内のsrc/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)
simple_pipelineディレクトリを追加したのでlibmv-master/src/libmvにあるCMakeLists.txtも以下のように修正。
ADD_SUBDIRECTORY(base)
ADD_SUBDIRECTORY(camera)
ADD_SUBDIRECTORY(detector)
ADD_SUBDIRECTORY(descriptor)
ADD_SUBDIRECTORY(image)
ADD_SUBDIRECTORY(numeric)
ADD_SUBDIRECTORY(correspondence)
ADD_SUBDIRECTORY(optimize)
ADD_SUBDIRECTORY(multiview)
ADD_SUBDIRECTORY(reconstruction)
ADD_SUBDIRECTORY(scene_graph)
ADD_SUBDIRECTORY(simple_pipeline)
ADD_SUBDIRECTORY(tools)
#Installation macro for all headers
LIBMV_INSTALL_ALL_HEADERS()
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でソースのパスにlibmv-master\srcディレクトリを、ビルドパスには任意のディレクトリのパスを指定してConfigure,Generateを押す。
生成されたLIBMV.slnを起動し、correspondence, gflags, multiview, numeric, simple_pipelineプロジェクトのみをビルドする。
correspondenceプロジェクトのプロパティから追加のインクルードディレクトリに以下を追記する。
任意のディレクトリ\ceres-windows-master\glog\src\windows;
$(OPENCV_DIR)\build\include;
multiviewプロジェクトのプロパティから追加のインクルードディレクトリに以下を追記する。
任意のディレクトリ\ceres-windows-master\glog\src\windows;
simple_pipelineプロジェクトのプロパティから追加のインクルードディレクトリに以下を追記する。
任意のディレクトリ\ceres-windows-master\glog\src\windows;
任意のディレクトリ\ceres-windows-master\win\include;
任意のディレクトリ\ceres-windows-master\ceres-solver\include;
そのままビルドしようとしてもlogging.hでエラー出るので、logging.hの
#include "third_party/glog/src/glog/logging.h"
を
#include "third_party/glog/src/windows/glog/logging.h"
へ書き換える。
これで参考記事と同じようにビルドできるようになり、SfMモジュールを使うためのlibファイルが生成される。
と、ここまででSfMモジュールをビルドする準備が完了。(まだ準備か…)
だいぶ疲れたので、実際にサンプルを実行してみるのはまた別の記事に。。。
あ、Visual Studio 2015でやるならここを参考にすればよかったかも↓
http://cvl-robot.hateblo.jp/entry/2016/02/04/194144
2016年12月16日 追記:OpenCVの本来のビルドシステムの中でビルドする正攻法の方が良いですね。↓
http://qiita.com/ChaoticActivity/items/3888e886925ef0f84926
http://qiita.com/ChaoticActivity/items/178d23508b92a09e59ea
コメント