サイトアイコン NegativeMindException

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

PCを新調してできることが増えたので色々遊び始める。
さっそくOpenCV 3.1をopencv_contribのモジュールも含めてビルドしてみようと思う。目当ては特にSfMモジュール。
Windows環境でx64ビルドするための手順をメモしておく。

オイラの環境は

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の

をlibmv-master/src/libmv/baseに上書き。

correspondence

opencv_contrib SfMモジュール内のsrc/libmv_light/libmv/correspondenceの

を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の

を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の

を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の

をlibmv-master/src/third_party/eigenに上書き。

glog

先ほど用意したceres-windows-master/glog/src/glogの

を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


スポンサーリンク

関連記事

  • Kinect for Windows v2の日本価格決定
  • Accord.NET Framework:C#で使える機械学習ライブラリ
  • OpenCVで平均顔を作るチュートリアル
  • スクラッチで既存のキャラクターを立体化したい
  • Kinect for Windows V2のプレオーダー開始
  • OpenAR:OpenCVベースのマーカーARライブラリ
  • html5のcanvasの可能性
  • UnityでOpenCVを使うには?
  • Pythonの自然言語処理ライブラリ『NLTK(Natural Language Toolkit)』
  • OpenMVS:Multi-View Stereoによる3次元復元ライブラリ
  • ドットインストールのWordPress入門レッスン
  • Structure from Motion (多視点画像からの3次元形状復元)
  • WordPressのサーバ引っ越し方法を考える
  • Point Cloud Utils:Pythonで3D点群・Meshを扱うライブラリ
  • FreeMoCap Project:オープンソースのマーカーレスモーションキャプチャ
  • UnityのGlobal Illumination
  • Super Resolution:OpenCVの超解像処理モジュール
  • MB-Lab:Blenderの人体モデリングアドオン
  • UnityプロジェクトをGitHubで管理する
  • PyMC:Pythonのベイズ統計ライブラリ
  • Autodesk Mementoでゴジラを3次元復元する
  • trimesh:PythonでポリゴンMeshを扱うライブラリ
  • 機械学習のオープンソースソフトウェアフォーラム『mloss(machine learning ope...
  • OpenCVでiPhone6sのカメラをキャリブレーションする
  • OpenCV 3.1から追加されたSfMモジュール
  • 写真に3Dオブジェクトを違和感無く合成する『3DPhotoMagic』
  • BlenderのPython環境にPyTorchをインストールする
  • Mayaのプラグイン開発
  • MythTV:Linuxでテレビの視聴・録画ができるオープンソースプロジェクト
  • Active Appearance Models(AAM)
  • AMIMOTO(PVM版)で作成したインスタンスをAMIMOTO (HVM版)へ移行する
  • KelpNet:C#で使える可読性重視のディープラーニングライブラリ
  • Pix2Pix:CGANによる画像変換
  • Webスクレイピングの勉強会に行ってきた
  • Kaolin:3Dディープラーニング用のPyTorchライブラリ
  • Photogrammetry (写真測量法)
  • 第1回 3D勉強会@関東『SLAMチュートリアル大会』
  • Unityの薄い本
  • Unity ARKitプラグインサンプルのドキュメントを読む
  • PCA (主成分分析)
  • Python拡張モジュールのWindows用インストーラー配布サイト
  • OpenCV
  • モバイルバージョンを終了