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)


スポンサーリンク

関連記事

Alice Vision:オープンソースのPhotogrammetryフレームワーク
CGAN (Conditional GAN):条件付き敵対的生成ネットワーク
Unity ARKitプラグインサンプルのチュートリアルを読む
FreeMoCap Project:オープンソースのマーカーレスモーションキャプチャ
OpenCV
VCG Library:C++のポリゴン操作ライブラリ
AmazonEC2のインスタンスをt1.microからt2.microへ移行する
BlenderのPython環境にPyTorchをインストールする
Geogram:C++の3D幾何アルゴリズムライブラリ
OpenCVで動画の手ぶれ補正
ZScript
Live CV:インタラクティブにComputer Visionコーディングができるツール
画像生成AI Stable Diffusionで遊ぶ
書籍『ゼロから作るDeep Learning』で自分なりに学ぶ
iPhoneで3D写真が撮れるアプリ『seene』
オープンソースの物理ベースGIレンダラ『appleseed』
Amazon Web ServicesでWordPress
OpenCVの顔検出過程を可視化した動画
BlenderでPhotogrammetryできるアドオン
Raspberry Piでセンサーの常時稼働を検討する
Google Chromecast
Raspberry Pi 2のGPIOピン配置
WordPressのサーバ引っ越し方法を考える
iOSデバイスと接続して連携するガジェットの開発方法
Theia:オープンソースのStructure from Motionライブラリ
cvui:OpenCVのための軽量GUIライブラリ
Mayaのレンダリング アトリビュート
Verilog HDL
Mask R-CNN:ディープラーニングによる一般物体検出・Instance Segmentatio...
書籍『ROSプログラミング』
COLMAP:オープンソースのSfM・MVSツール
TensorSpace.js:ニューラルネットワークの構造を可視化するフレームワーク
PSPNet (Pyramid Scene Parsing Network):ディープラーニングによ...
PythonのHTML・XMLパーサー『BeautifulSoup』
GeoGebra:無料で使える数学アプリ
Google App Engine上のWordPressでAmazonJSを利用する
Iterator
Webスクレイピングの勉強会に行ってきた
Model View Controller
AMIMOTO(PVM版)で作成したインスタンスをAMIMOTO (HVM版)へ移行する
オープンソースのプリント基板設計ツール『KiCad』
SONY製のニューラルネットワークライブラリ『NNabla』

コメント