Computer Vision

OpenCV 4.0.1(CUDA 10.0, VTK 8.2.0, Qt5.12.2)をWindowsでビルドしてPythonから使う方法

PythonでOpenCVを使いたい場合、pip install opencv-pythonとすれば簡単にOpenCVを導入できますが、標準で公開されているパッケージはCPU版なのでGPUには対応していません。OpenCVを使った処理では、GPUを使って処理を高速化したい場合も多いため、ここではOpenCVをソースからビルドしてCUDAに対応させる方法を紹介します。

なお、CUDA以外に、VTKとQt5も利用できるようにしています。

より新しいバージョンのOpenCV 4.1.0をPython 3.7用にビルドする手順「OpenCV 4.1.0(CUDA 10.0, VTK 8.2.0, Qt5.12.2)をWindowsでビルドしてPythonから使う方法」も公開しました。

OpenCV 4.1.0であれば、color_detail.hppのバグも修正されています。

ビルド環境

今回は、以下の環境を利用して、OpenCV 4.0.1をソースからビルドします。

また、Python 3.6.8、CUDA 10.0、VTK 8.2.0、Qt 5.12.2については、環境変数PATHにパスを追加してライブラリや実行ファイルが参照できるような状態にしています。

// 環境変数PATHに追加している内容(関係する部分)

// CUDA 10.0
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\libnvvp
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras\CUPTI\libx64

// Git for Windows
C:\Program Files\Git\cmd

// Qt5
C:\Qt\Qt5.12.2\5.12.2\msvc2017_64\bin

// VTK
C:\lib\VTK\bin

// Python 3.6.8
C:\Python36\Scripts\
C:\Python36\

 

OpenCV 4.0.1のビルド

ソースファイルの取得

今回はc:\build\opencv401フォルダ配下にOpenCV 4.0.1のソースコードを取得してきます。コマンドプロンプトで以下のコマンドを実行します。

rem 作業用のフォルダ作成
mkdir c:\build\opencv401
cd /d c:\build\opencv401

rem OpenCVのソース取得
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.0.1
cd ..

rem OepnCV Contribのソース取得
rem OpenCVのビルドにはcontribのopencv_cudevが必須
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 4.0.1
cd ..

OpenCV 4.0.1のビルドには、contribのopencv_cudevが必須になります。OpenCV単体でビルドしようとすると、opencv_cudevが見つからないためビルドエラーになります。

OpenCV 4.0.1のビルド設定

CMake GUIを起動し、Where is the source codeC:/build/opencv401/opencvWhere to build the binariesC:/build/opencv401/opencv/buildを指定してConfigureボタンをクリックします。コンパイラはVisual Studio 15 2017、x64を選択してください。

環境によって設定項目も変わってきますが、「設定変更→Configureボタンをクリック」という作業を何度か繰り返しながら以下のように設定します。(ポイントになる部分には赤い矢印を付けています)

…と言っておきながら、一番重要OPENCV_EXTRA_MODULES_PATHにマークするのを忘れていました。OPENCV_EXTRA_MODULES_PATHopencv_contribのmoduleフォルダを指定して、opencv_contribに含まれる拡張モジュールを読み込ませます

OpenCV 4.0.1のビルド設定

設定項目数は多いのですが、手動で変更している内容(CMakeのShow My Changes)は次のようになります。この項目以外は、CMake側で自動で設定された値になります。

CMAKE_INSTALL_PREFIXOpenCVのインストール先になるので好みに応じて書き換えてください。CPUやCUDAのアーキテクチャは、利用している環境に合わせて設定を行います。(最初はCUDA_ARCH_PTXにも7.5と値を設定していたのですが、Configureで空白に戻るので、空白のままにしています)

CUDA、VTK、QT、Python3を利用するため、WITH_CUDAWITH_VTKWITH_QTOPENCV_PYTHON3_VERSIONBUILD_opencv_python3にチェックを入れます。(一部はCMake側で自動的にチェックが有効になります

BUILD_EXAMPLES:BOOL=1
BUILD_JAVA:BOOL=0
BUILD_LIST:STRING=
BUILD_opencv_java_bindings_generator:BOOL=0
BUILD_PERF_TESTS:BOOL=0
BUILD_TESTS:BOOL=0
CMAKE_INSTALL_PREFIX:PATH=C:/lib/OpenCV401
CPU_BASELINE:STRING=AVX2
CPU_DISPATCH:STRING=AVX2
CUDA_ARCH_BIN:STRING=7.5
CUDA_ARCH_PTX:STRING=
CUDA_FAST_MATH:BOOL=1
CUDA_GENERATION:STRING=Turing
INSTALL_PYTHON_EXAMPLES:BOOL=1
OPENCV_ENABLE_NONFREE:BOOL=1
OPENCV_EXTRA_MODULES_PATH:PATH=C:/build/opencv401/opencv_contrib/modules
OPENCV_PYTHON3_VERSION:BOOL=1
WITH_CUDA:BOOL=1
WITH_QT:BOOL=1

 

設定が完了したら、GenerateボタンでVisual Studio 2017のソリューションを作成し、Open Projectボタンでソリューションファイルを開きます。(作成されたC:\build\opencv401\opencv\build\OpenCV.slnを直接Visual Studio 2017で開いてもOKです)

color_detail.hppの不具合修正

OpenCV 4.0.1のタグ時点では、opencv_cudaimgprocプロジェクトのcolor_detail.hppに不具合があるので修正を行います。この修正を行わずにビルドすると、dynamic initialization is not supported for a __constant__ variableというエラーでビルドに失敗します。

opencv_cudaimgprocプロジェクトのcolor_detail.hppを開いて、96~127行目のconstをconstexprに修正します。

修正したファイルはここからダウンロード(右クリックして名前を付けてリンク先を保存)できるようにしておきました。

//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
constexpr float B2YF = 0.114f;
constexpr float G2YF = 0.587f;
constexpr float R2YF = 0.299f;

//to YCbCr
constexpr float YCBF = 0.564f; // == 1/2/(1-B2YF)
constexpr float YCRF = 0.713f; // == 1/2/(1-R2YF)
constexpr int YCBI = 9241;  // == YCBF*16384
constexpr int YCRI = 11682; // == YCRF*16384
//to YUV
constexpr float B2UF = 0.492f;
constexpr float R2VF = 0.877f;
constexpr int B2UI = 8061;  // == B2UF*16384
constexpr int R2VI = 14369; // == R2VF*16384
//from YUV
constexpr float U2BF = 2.032f;
constexpr float U2GF = -0.395f;
constexpr float V2GF = -0.581f;
constexpr float V2RF = 1.140f;
constexpr int U2BI = 33292;
constexpr int U2GI = -6472;
constexpr int V2GI = -9519;
constexpr int V2RI = 18678;
//from YCrCb
constexpr float CB2BF = 1.773f;
constexpr float CB2GF = -0.344f;
constexpr float CR2GF = -0.714f;
constexpr float CR2RF = 1.403f;
constexpr int CB2BI = 29049;
constexpr int CB2GI = -5636;
constexpr int CR2GI = -11698;
constexpr int CR2RI = 22987;

OpenCVのディスカッションページでは、間違った修正方法が書かれている場合があるので注意が必要です。エラーが発生している「__constant__をconstにすればビルドが通る…」という内容の修正方法は間違いです。

__constant__はCUDAのアノテーションなので、この部分をC/C++のconstに変更してしまうと、ビルドは通るかもしれませんが、全く違った意味のコードになってしまいます

詳細:https://github.com/opencv/opencv/pull/13719

なお、2019/3/17時点の最新ソースでは影響のある部分だけconstexprに置き換えられていますが、上で示したソースのように、96~127行目全てをconstexprに置き換えても問題ありません。(むしろ、このパターンだとROM化するために全てconstexprに置き換えるべきだと思う…)

OpenCV 4.0.1のビルド

Visual Studio 2017のバッチビルドで、INSTALLをリビルド(ビルドでもOK)します。

OpenCV 4.0.1のバッチビルド

OpenCV 4.0.1を使うための設定

OpenCV 4.0.1のフォルダ構成

ビルドが完了すると、以下のようなフォルダ構成でOpenCV 4.0.1が配置されます。

OpenCVの各種ファイルは、ビルド設定のCMAKE_INSTALL_PREFIXで指定したフォルダ(C:\lib\OpenCV401)に展開されます。また、Python 3用のモジュールは、PYTHON3_PACKAGES_PATHで指定したフォルダ配下(C:\Python36\Lib\site-packages\cv2)に配置されます。

// ビルド後のフォルダ構成(一部のフォルダは省略)

// OpenCV 4.0.1の各種ファイル
C:\lib\OpenCV401
├─bin
├─etc
│  ├─haarcascades
│  ├─lbpcascades
│  └─licenses
├─include
│  └─opencv2
├─samples
└─x64
    └─vc15
        ├─bin
        └─lib

// Python 3用のモジュール
C:\Python36
└─Lib
    └─site-packages
        └─cv2
            └─python-3.6

 

PATH設定

OpenCVのDLLファイルが参照できるように、インストール先のbinフォルダ(C:\lib\OpenCV401\x64\vc15\bin)を環境変数PATHに追加します。なお、依存しているCUDA、VTK、Qtなどにもパスを通しておく必要があります。

OpenCVへのパスが通っているかどうかは、whereコマンドで確認できます。もし、whereコマンドでファイルが見つからない(もしくはインストールした場所とは違う場所のOpenCVが先に表示された)場合は環境変数PATHの設定を確認してみてください。

rem whereコマンドでopencv_*.dllを確認
C:\>where opencv_*.dll
C:\lib\opencv401\x64\vc15\bin\opencv_aruco401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_bgsegm401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_bioinspired401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_calib3d401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_ccalib401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_core401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudaarithm401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudabgsegm401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudacodec401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudafeatures2d401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudafilters401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudaimgproc401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudalegacy401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudaobjdetect401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudaoptflow401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudastereo401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudawarping401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cudev401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_cvv401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_datasets401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_dnn401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_dnn_objdetect401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_dpm401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_face401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_features2d401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_ffmpeg401_64.dll
C:\lib\opencv401\x64\vc15\bin\opencv_flann401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_fuzzy401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_gapi401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_hfs401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_highgui401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_imgcodecs401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_imgproc401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_img_hash401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_line_descriptor401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_ml401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_objdetect401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_optflow401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_phase_unwrapping401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_photo401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_plot401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_reg401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_rgbd401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_saliency401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_shape401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_stereo401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_stitching401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_structured_light401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_superres401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_surface_matching401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_text401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_tracking401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_video401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_videoio401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_videostab401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_viz401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_xfeatures2d401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_ximgproc401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_xobjdetect401.dll
C:\lib\opencv401\x64\vc15\bin\opencv_xphoto401.dll

 

依存しているライブラリを含めてPATHが通っていなくてdllファイルを見つけられない場合は、OpenCVの実行時に以下のようなエラーメッセージが表示されます。(Qtには同じようなフォルダが複数ありますが、Qtのwinrt~系のフォルダを指定するとOpenCVでdllファイルが見つからずにエラーが出ます)

C:\>python -c "import cv2"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python36\lib\site-packages\cv2\__init__.py", line 89, in <module>
    bootstrap()
  File "C:\Python36\lib\site-packages\cv2\__init__.py", line 79, in bootstrap
    import cv2
ImportError: DLL load failed: 指定されたモジュールが見つかりません。

 

ちなみに、C/C++で作成されている*.exe形式のサンプルを実行すると、MSVCP140_APP.DLLVCRUNTIME140_APP.DLLが見つからない…というエラーが出る場合があります。

これらのファイルの正体がよく分かりませんが、とりあえずC:\Windows\System32配下のmsvcp140.dllvcruntime140.dllC:\lib\OpenCV401\x64\vc15\binフォルダにコピー(もしくはシンボリックリンクを作成)して、名前をMSVCP140_APP.DLLVCRUNTIME140_APP.DLLに変更すれば、とりあえず動作しました。

ただし、これらのファイルが本当に同じものかどうか分からないため、あくまで暫定的な対応になります。

 

OpenCV 4.0.1をPythonから利用する方法

Pythonの仮想環境作成

cvという仮想環境を作成して、PythonからOpenCVを利用できるようにします。

rem 仮想環境cv作成
python -m venv C:\venvs\cv

rem Python3用のOpenCVモジュールを仮想環境のsite-packagesにコピー
robocopy "C:\Python36\lib\site-packages\cv2" "C:\venvs\cv\Lib\site-packages\cv2" /E

rem 仮想環境をアクティブ化
C:\venvs\cv\Scripts\activate.bat

rem pipのアップデート(任意)
python -m pip install --upgrade pip

rem numpyのインストール(必須)
pip install numpy

 

OpenCVを利用できるかどうか、以下のコマンドで確認できます。

rem OpenCVのバージョン表示
rem 正しくインストールできていれば 4.0.1 と表示される
(cv) C:\>python -c "import cv2; print(cv2.__version__)"
4.0.1

rem OpenCVのビルド情報表示
rem 正しくインストールしていればOpenCVのビルド情報が詳細に表示される
(cv) C:\>python -c "import cv2; print(cv2.getBuildInformation())"

 

C/C++からOpenCVを利用する場合は、OpenCVをインストールしたフォルダ配下にあるinclude、およびlibファイルを参照するようにプロジェクトを設定すればOKです。なお、実行時にはbinフォルダへのパスを通しておく(もしくは実行ファイルと同じ場所に各種dllファイルを配置しておく)必要があります。

 

Python用のOpenCVサンプル(デモ)

ビルド設定で、INSTALL_PYTHON_EXAMPLESにチェックを入れていれば、C:\lib\OpenCV401\samples\pythonフォルダにPythonのサンプルコードが入っています。

色々なサンプルがありますが、demo.pyが全てのサンプルを起動するランチャーになっているので、python demo.pyでランチャーを経由して各種サンプルを起動できるようになっています。