OpenCV 3.1とopencv_contribモジュールをVisual Studio 2015でビルドする

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

OpenCV3ではじめるWindowsアプリ開発 (I・O BOOKS)

関連記事

GAN (Generative Adversarial Ne...

Unityからkonashiをコントロールする

OpenCVのfindEssentialMat関数を使ったサ...

Raspberry Pi

Kinect for Windows V2のプレオーダー開始

Google App Engine上のWordPressでA...

ブログの復旧が難航してた話

このブログのデザインに飽きてきた

OpenCV 3.1のsfmモジュールを試す

Googleが画像解析旅行ガイドアプリのJetpac社を買収

Windows10でPyTorchをインストールしてVSCo...

SVM (Support Vector Machine)

Digital Emily Project:人間の顔をそっく...

Human Generator:Blenderの人体生成アド...

WordPressの表示を高速化する

Deep Learningとその他の機械学習手法の性能比較

OpenCVで平均顔を作るチュートリアル

pythonの機械学習ライブラリ『scikit-learn』

2D→3D復元技術で使われる用語まとめ

iPhone・iPod touchで動作する知育ロボット『R...

顔画像処理技術の過去の研究

Javaで作られたオープンソースの3DCGレンダラ『Sunf...

Math Inspector:科学計算向けビジュアルプログラ...

UnityプロジェクトをGitHubで管理する

UnityでShaderの入力パラメータとして行列を渡す

YOLO (You Only Look Once):ディープ...

クラスの基本

Open Shading Language (OSL)

フォトンの放射から格納までを可視化した動画

Cartographer:オープンソースのSLAMライブラリ

Google App Engineのデプロイ失敗

HerokuでMEAN stack

VCG Library:C++のポリゴン操作ライブラリ

科学技術計算向けスクリプト言語『Julia』

OpenCV

Math.NET Numerics:Unityで使える数値計...

Managing Software Requirements...

TorchStudio:PyTorchのための統合開発環境と...

Kubric:機械学習用アノテーション付き動画生成パイプライ...

COLMAP:オープンソースのSfM・MVSツール

PyDataTokyo主催のDeep Learning勉強会

PythonのHTML・XMLパーサー『BeautifulS...

コメント