MinGWでOpenCVをビルドしてみた

公式で配布されているOpenCVOpenCLに対応していないconfigって噂を聞いたので、せっかくだからビルドしてみた。しにそうになったので記録として残す。
Qtがなくても一部機能制限されるだけで動くからQtのビルドにチャレンジするのはやめよう(戒め)

環境、バージョン

バージョンはこんな感じ。

今回はDLLとコンパイラの相性がひどくて大丈夫な組み合わせを探すのに時間がかかった。
こんな感じで。

  • Qt付属のMinGW ⇒ Qt OK、Python NG
  • PleiadesMinGW ⇒ Qt NG、Python OK
  • ビルド済みTBB、AnacondaのQt ⇒ MSVCマングルなのでそもそもリンクできず
  • Pythonからimport cv2 ⇒ OpenCVのhighguiがQtを使っているとなぜかダメ

結論として以下の組み合わせになった。

ビルド全体の流れ

公式サイト*1および、こちらの方*2のページを参考に進めた。

ざっくりとは以下のかんじ。

  • Pythonの環境を用意する (Anacondaをインストール、さらに2.x系の環境を作る)
  • OpenCLの環境を用意する (AMD APP SDKをインストール)
  • Qtをビルド(git clone、configure、make)
  • VTKをビルド(ソースダウンロード、cmake、make)
  • OpenCVをビルド(ソースダウンロード、cmake、make)

エラーへの対処方法

ビルド中に遭遇したエラー対処内容は以下の通り。

VTKのlibtiff

どうやらWindowsだと強制的にmsvcルートへ進むみたいでここ*3に書かれているようにThirdParty/tiff/vtktiff/CMakeLists.txtの「if(UNIX)」を「if(UNIX OR MINGW)」に修正するとビルドできる。

ちなみにVTKはQtやTBBを使うことができるらしい。今回は有効化していない。
たぶんTBBは自力でビルドするのは難しそう。しかもOpenCVがビルドしてくれるTBBは関数名を独自の命名規則に変更しているみたいなので流用はたぶん無理。

OpenCVのcmake

cmake時に「ENABLE_PRECOMPILED_HEADERS」を「OFF」に設定する。ここ*4参照。

DirectShowのソースでコンパイルエラー

\modules\videoio\src\cap_dshow.cppの先頭に「#define STRSAFE_NO_DEPRECAT」を追加する。こちらを*5参照。

Pythonモジュールのコンパイルでエラー

std::hypotが見つからずコンパイルエラーになる。詳細を絞り込んでいないがヘッダとかdefineの組み合わせで発生する模様。MinGWOpenCVをincludeしたPythonモジュールをコンパイルしようとすると出ちゃうっぽい。
出てしまった場合、\lib\gcc\x86_64-w64-mingw32\7.1.0\include\c++\cmathファイル中の「using ::hypot」をコメントアウトすればとりあえず通る。

Pythonモジュールその2

Pythonモジュールのリンクでエラーになる。こちら*6の「undefined reference to __imp_Py_InitModule4」箇所を参照。
Python2、Python3のpyconfig.hの「MS_WIN64」のdefineを「_MSC_VER」の外側へ移動させる。
自分の環境だと以下のファイル。2.x系、3.x系ともにincludeフォルダに該当ヘッダファイルが入っているっぽい。

  • D:\soft\Anaconda3\envs\py2714\include\pyconfig.h
  • D:\soft\Anaconda3\include\pyconfig.h

こんな感じでなんとかビルドできた。動作確認は明日にしよう。