CMakeでOpenCVをビルド(オプション詳細, OpenVINO, Gstreamer, ONNXRUNTIME結合方法等)

タイトルを変更。そのうち記事そのものを移動するかもしれない。また、調子に乗りすぎて余談が過ぎて長くなったので、この部分は最後に移動。暇な人は読んで頂戴。

# [基本]フォルダの準備
OpenCVのビルドの手順を下記に示す。
1. プロクシを使う環境であれば、環境変数でHTTPS_PROXY、HTTP_PROXYの二つにプロクシURLをセットする。cmakeが必要なライブラリをダウンロードしたりするからだ。書き方はこんな感じ。
HTTPS_PROXY=http://hoge.hoge.net:8080
HTTP_PROXY=http://hoge.hoge.net:8080。
 **※Opencvのバイナリはデフォルトで自動的にHTTP_PROXY、HTTPS_PROXYを参照する。特に必要がなければ、ビルドが終わった後は、この設定は消しておくほうが無難。** 
1. Visual Studioを入れる。
2. python対応用DLLをつくる場合は、pythonを入れておく。パスも通しておく。
3. cudaとcudnnを入れる。CUDA_PATHとか環境設定もきちんと済ます。
4. cmakeを入れる。
5. 適当な場所にフォルダを作る。
6. コマンドプロンプトで作ったフォルに移動。
7. 公式からOpencvとOpencv Contribをダウンロード、展開する。フォルダ構成は↓こんな感じ。
```
d:\
┗opencv
 ┣opencv
 ┗opencv_contrib
```
8. opencvの下にbuildフォルダを作る
```
d:\
┗opencv
 ┣opencv
 ┃ ┣build
 ┃ ┗その他のフォルダ
 ┗opencv_contrib
```
8. cmake-guiを起動
FileメニューのDelete cacheを選択。前回の設定を消す。
Where is the soruce codeにOpencvのmakefiule.txtのあるフォルダを入れる。↓このフォルダ
```
d:\
┗opencv
 ┗opencv
```
Where is the binariesにbuildフォルダを指定する。
```
d:\
┗opencv
 ┣opencv
 ┃ ┣build
```
9. configureを押す。5分くらい待つ。
10. オプションリストが出るので必要なオプションを選択
11. オプションリストのOPENCV_EXTRA_MODULES_PATHにopencv_contribのパスを加える。modulesまで入れる。円マーク、もしくは"\\"は使えない。ディレクトリの表現には"/"を使うこと。
* OPENCV_EXTRA_MODULES_PATH d:\opencv\opencv_contrib\modules
```
d:\
┗opencv
 ┣opencv
 ┃ ┣build
 ┃ ┗その他のフォルダ
 ┗opencv_contrib
   ┗modules
```
12. 再びconfigureを押す。2分くらい待つ。
13. Generateを押す。
13. opencv\buildのフォルダにslnファイルが出来ているのでそれをvisual studioで開く。
14. visual studio->ビルド->バッチビルトで必要な出力を選んでビルド。オジサンはINSTALLとopencv_worldのリリースとデバッグをビルドしている。たくさん選択すると時間がかかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/cab885af-466b-4aa5-b5d0-2c0b6d96afc7.png)

# オプション 2024/8/10追記
記事がグダグダになって備忘録になってないので、整理する。

## 必須項目
```
OPENCV_EXTRA_MODULES_PATH PATH = エキストラモジュールへのパス
BUILD_opencv_world = ON
```
* OPENCV_EXTRA_MODULES_PATH PATH = パスを指定
OpenCV拡張モジュール（opencv_contrib）が存在するディレクトリを指定
* BUILD_opencv_world ON
OpenCVのすべてのモジュールを1つの大きなライブラリ（opencv_world）としてビルド

※[注意事項]OPENCV_EXTRA_MODULES_PATHと、WITH_CUDA=ONにした後、もう一度configureを押す。そう死ないと関連したオプションが現れない。

## CUDAを使う場合のオプション設定
```bash:設定例
WITH_CUDA = ON
CUDA_FAST_MATH = ON
WITH_CUBLAS = ON
WITH_CUDNN = ON
PENCV_DNN_CUDA = ON
CUDA_ARCH_BIN = 7.5;8.0;8.6;8.9;9.0
CUDA_ARCH_PTX = 9.0
```
説明
* WITH_CUDA = ON
意味: OpenCVのCUDAサポートを有効化。
効果: CUDA対応GPUを利用してOpenCVの一部の関数を高速化（例: フィルタリング、画像変換、DNN推論）。
* CUDA_FAST_MATH = ON
意味: CUDAでの高速数学演算を有効化。FP16演算が有効になるものと思う。ONにしたら全てのfloatの演算が直ちにFP16になるわけではないと思うが、気分でON。CUDAカーネル内で高速な数学関数（例: __fmul_rn や __fadd_rn）を使用するとのこと。
[余談] 新しめのyoloでは、作成したweightファイル(*.ptや*.onnx)がCPUやonnxruntimeでは動くけど、OpenCVのcuDNNではランタイムエラーになる、なんてことがあるが、このあたりに原因があるかもしれない。FP16はNvidiaとMicrosoftの規格なのでLinuxには無いらしい。OpenCVの開発環境によってはデバッグできないのかもしれない。メモリサイズが違ってくるので、配列の長さの計算が間違ってメモリアクセスエラーとかが起こると推測している。(未確認)
* WITH_CUBLAS = ON
意味: CUDA BLAS（Basic Linear Algebra Subprograms）ライブラリを有効化。
効果: 行列演算などの線形代数処理が高速化。
* WITH_CUDNN = ON
意味: NVIDIA cuDNNライブラリ（Deep Neural Network）を有効化。
効果: OpenCVのDNNモジュールでcuDNNを使用し、ディープラーニング推論を高速化。
* OPENCV_DNN_CUDA = ON
意味: OpenCV DNNモジュールのCUDAバックエンドを有効化。
効果: DNNモデル（YOLO、ResNetなど）の推論がGPU上で高速に実行。
* CUDA_ARCH_BIN = 7.5;8.0;8.6;8.9;9.0
意味: CUDAアーキテクチャを指定。7.5とかの数字は、NVIDIA GPUの演算器のバージョンを表す。指定した数だけ、NVCCコンパイラが処理するので、コンパイル時間がかかるようになる。
効果: NVIDIA GPUのバージョンに合わせて最適化したバイナリを生成。 **指定が多いほどコンパイルに時間がかかる** ので。指定するパラメータ数はなるべく少ないほうがいい。自分のGPUアーキテクチャに合わせて設定。RTX2080は7.5。RTX3090は8.6、RTX4090は8.9。9.0はH100とかかな。
確認先は https://developer.nvidia.com/cuda-gpus#compute 
* CUDA_ARCH_PTX = 9.0
PTX中間コードを生成。
実行時にJITコンパイルが行われるため、未対応の新しいGPUアーキテクチャにも対応可能。
※自分の環境だと、自宅がRTX2080ti、会社がRTX4090なのでCUDA_ARCH_BIN=7.5、CUDA_ARCH_PTX=9.0の方が、コンパイル時間が短縮できると思うがまだ試していない。

## CPU処理の高速化
```bash:設定例
ENABLE_FAST_MATH = ON
WITH_OPENMP = ON
WITH_OPENCL_SVM = ON
CPU_BASELINE = AVX2
MKL_WITH_OPENMP = ON
WITH_OPENCL = ON
OPENCV_DNN_OPENCL = ON
```
説明
* ENABLE_FAST_MATH = ON
高速数学演算を有効化するオプション。コンパイラオプション/fp:fastが付けられる。精度の要らないところでは16bit(float)演算をするようになる。ゲームやAIではONにしても構わない。効果を引き出すには、OpenCVを使うアプリケーション側でも、float16を使うなどの工夫が必要と思う。
[参考]https://www.isus.jp/others/half-precision-floats/
* WITH_OPENMP = ON
OpenMP（Open Multi-Processing）を利用して、マルチスレッド並列処理を有効化するオプション。
* WITH_OPENCL_SVM = ON
CPUとGPU間でメモリを共有することで、データ転送のオーバーヘッドを削減。入れておいても害は無かった。効果は?。
* CPU_BASELINE = AVX2
OpenCVが使用するCPU命令セットのベースラインをAVX2に設定。対象PCのスペックに合わせる。最新CPUならAVX512が使えるが、BIOSの設定変更が必要だったりする。たぶん、ENABLE_FAST_MATHと合わせて使うと効果大。
[AVX2とは]
AVX2はPentiumあたりから搭載された、浮動小数点演算用のレジスタと演算器のこと。SSEとかの進化バージョン。AVX2はcore i7あたりから使える。AVX2には256bitの浮動小数点レジスタ16個がある。256bitレジスタ(YMMレジスタという)一つでFP16型の演算が16個同時に出来る。1コアに16個のYMMレジスタがあるので、i9とかの24コアCPUなら6144個のFP16演算を一発で演算できる計算になる。これが4GHzで動作するわけだから、FLOPSでいうと2.46TFLOPSになり、GPUも真っ青の能力である。ただし、本気で使いこなすには、メモリのロードや書き込みがボトルネックになるので、インラインアセンブラでパイプライン処理とか考慮しないといけない(ような気がする)。AVX512は、512bitのYMMレジスタが32個もあるのでさらに強力だが、規格が安定していないので、CPUやチップセットの組み合わせにより仕様が変わるので動いたり動かなかったりする。
* MKL_WITH_OPENMP = ON
MKLが提供する線形代数や行列演算（例: BLAS、LAPACKなど）の処理を、OpenMPによるスレッド並列化で高速化
* WITH_OPENCL = ON
OpenCVでの OpenCLサポート を有効化。OpenCLは、CPU、GPU、その他のデバイスで並列計算を実行するためのフレームワーク。
* OPENCV_DNN_OPENCL = ON
OpenCVのDNN（Deep Neural Network）モジュールで、OpenCLをバックエンドとして使用する機能を有効化。OpenCVのDNNモジュールでの推論処理が、GPUやCPU内蔵GPUで並列計算されるようになる。TensorFlowやONNXなどのモデル（例: YOLO, MobileNet）を利用した推論が高速化。

## OpenVINO
OpenVINOを使う場合は下記を設定。TBBは必ずも要らないとのことだが、使った方がいい。
```bash:設定例
WITH_OPENVINO = ON
OPENCV_DNN_OPENVINO = ON
WITH_CUDA = OFF ※1
WITH_CUDNN = OFF ※1
OpenVINO_DIR:PATH=path_to_openvino/runtime/cmake
BUILD_TBB = OFF ※2
WITH_TBB = ON
MKL_WITH_TBB = ON
TBB_DIR = path_to_openvino/runtime/3rdparty/tbb
TBB_ENV_INCLUDE = path_to_openvino/runtime/3rdparty/tbb/include
TBB_ENV_LIB = path_to_openvino/runtime/3rdparty/tbb/lib/tbb12.lib
TBB_ENV_LIB_DEBUG = path_to_openvino/runtime/3rdparty/tbb/lib/tbb12_debug.lib
```
※1 このほかCUDA関係はオフにする。(オフにしなくてもビルドできるかもしれないけどOpenVINOを使う環境では、CUDAは使えないと思うので)
※2 OpenVINO入りOpenCVのビルドの仕方は下の方に記載

## Gstreamer
Gstremerを使う場合は下記を設定。先に環境変数の設定を済ませておくと、CMakeが自動的に設定してくれる。下記説類を参照。
```bash:設定例
WITH_GSTREAMER = ON
OPENCV_GAPI_GSTREAMER = ON
GSTREAMER_app_LIBRARY = path/1.0/msvc_x86_64/lib/gstapp-1.0.lib 
GSTREAMER_audio_LIBRARY = path/1.0/msvc_x86_64/lib/gstaudio-1.0.lib
GSTREAMER_base_LIBRARY = path/1.0/msvc_x86_64/lib/gstbase-1.0.lib
GSTREAMER_glib_INCLUDE_DIR = path/1.0/msvc_x86_64/include/glib-2.0
GSTREAMER_glib_LIBRARY = path/1.0/msvc_x86_64/lib/glib-2.0.lib
GSTREAMER_glibconfig_INCLUDE_PATH = path/1.0/msvc_x86_64/lib/glib-2.0/include
GSTREAMER_gobject_LIBRARY = path/1.0/msvc_x86_64/lib/gobject-2.0.lib
GSTREAMER_gst_INCLUDE_= path/1.0/msvc_x86_64/include/gstreamer-1.0
GSTREAMER_gstreamer_LIBRARY = path/1.0/msvc_x86_64/lib/gstreamer-1.0.lib
GSTREAMER_pbutils_LIBRARY = path/1.0/msvc_x86_64/lib/gstpbutils-1.0.lib
GSTREAMER_riff_LIBRARY = path/1.0/msvc_x86_64/lib/gstriff-1.0.lib
GSTREAMER_video_LIBRARY = path/1.0/msvc_x86_64/lib/gstvideo-1.0.lib
```
説明
* 下記の環境変数にGSTREAMERを入れたパスをセットしておけば、libファイルはCMAKEが勝手に探してくれる。 
* [環境変数]GSTREAMER_1_0_ROOT_MSVC_X86_64=C:\Programming\gst\1.0\msvc_x86_64\ (パスは例)
* [環境変数]GSTREAMER_1_0_ROOT_X86_64=C:\Programming\gst\1.0\msvc_x86_64 (パスは例)
※GSTREAMER_1_0_ROOT_MSVC_X86_64とGSTREAMER_1_0_ROOT_X86_64は同じディレクトリを指すが、 **GSTREAMER_1_0_ROOT_MSVC_X86_64の方には最後に\が必要。** なかなかトリッキーな ~~バグ~~ 仕様になっている。
* gstapp-1.0.lib は libgstapp-1.0.a 等になっていることがあるのでwindowsの場合は **gstapp-1.0.libファイルを探して書き換える。** (./msvc_x86_64/lib/の下にあった)
 * WITH_GSTREAMERをONにすると、開発環境では、GstreamerのランタイムとSDKのインストールが必要になる。使用先でもGstreamerのランタイムを入れて、パスを通す必要がある。
* BUILD_SHARED_LIBS=OFFにすればスタティックリンクになって、使用先でのGstreamerランタイムのインストールは不要との情報もあるが、未確認。

## ONNXRUNTIME
onnxruntimeは特に指定しなくてもonnxは使える。基本的には必要ない。純正のonnxruntimeの方がチョット速いとか、最新のYoloに対応としているとか、少しメリットがあるらしい。デフォルトで出てこないオプションがあったり、重複していたりややこしいので、いちおう書いておく。

* ONNX RUNTIME入手先
*https://onnxruntime.ai/
```bash:設定例
WITH_ONNX = ON
ONNXRT_ROOT_DIR = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1
ONNX_INCLUDE_DIR = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\include
ONNX_LIBRARIES = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib\onnxruntime.lib
ONNX_LIBRARY = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib
ORT_INCLUDE = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\include
ORT_LIB = C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib\onnxruntime.lib
```
説明
* WITH_ONNX オン　下記のオプションがしっかり設定されていないと、 **自動的にオフになるので必ず確認。** 
* ONNXRT_ROOT_DIR = バス
onnx runtimeを入れたパスを入れる。例: C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1
* ONNX_INCLUDE_DIR = パス
includeのパス。例: C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\include
* ONNX_LIBRARIES = ファイルのパス。
フォルダパスと思いきや、ファイルまでしっかり指定すること。例: C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib\onnxruntime.lib
* ONNX_LIBRARY = パス
ファイルのパスと思いきや、こちらはフォルダのパス。例:  C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib
* ORT_INCLUDE = パス
includeのパス。例: C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\include
* ORT_LIB = ファイルのパス
フォルダパスと思いきや、ファイルまでしっかり指定すること。例: C:\Programming\lib\onnxruntime-win-x64-gpu-1.20.1\lib\onnxruntime.lib

## 不要項目
C++で使用するだけなら、python、JAVA関係は全てチェックを外して構わない。
テスト関連も不要。
WITH_NVCUVENC、WITH_NVCUVIDはビデオエンコードをGPUで行う場合に必要。SDKをセットしてパスを指定すればいいのだが、指定方法が分からなかった。AIには要らないのでとりあえずOFF。
```bash
BUILD_JAVA = OFF
BUILD_opencv_python_bindings_generator = OFF
BUILD_opencv_java_bindings_generator = OFF
BUILD_opencv_python3 = OFF
BUILD_opencv_python_tests = OFF
BUILD_PERF_TESTS = OFF
BUILD_TESTS = OFF
WITH_NVCUVENC = OFF
WITH_NVCUVID = OFF
```

## コンパイルの高速化
```bash:設定例
ENABLE_CCACHE = ON
ENABLE_PRECOMPILED_HEADERS = ON
CMAKE_C_FLAGS "/MP"を追加
CMAKE_CXX_FLAGS "/MP"を追加
CMAKE_CUDA_FLAGS = --threads 12
CUDA_NVCC_FLAGS = --threads 12
BUILD_TEST = OFF
BUILD_ITT = OFF
WITH_ITT= OFF 
```
説明
* ENABLE_CCACHE = ON
* ENABLE_PRECOMPILED_HEADERS = ON
* CMAKE_C_FLAGS "/MP"を追加 マルチプロセッサの意味
* CMAKE_CXX_FLAGS "/MP"を追加 マルチプロセッサの意味
* CMAKE_CUDA_FLAGS = --threads 12
CUDAコンパイラ（nvcc）に渡されるフラグを設定。--threads 12 は、nvcc コンパイル時に使用する並列ビルドスレッド数に12を指定。論理コア数に合わせる。マルチコアCPUを持つ環境でCUDAコードのビルド時間を短縮。
* CUDA_NVCC_FLAGS = --threads 12
CUDAコンパイラ（nvcc）に直接渡される追加フラグを指定。--threads 12 は、コンパイル時に並列スレッドを12に設定するフラグ。CUDAコード（.cu ファイル）のコンパイルが並列化され、ビルド時間が短縮。
* BUILD_TEST = OFF
OpenCVのテストコードをビルドするかどうかを指定。OFF にすることで、OpenCVのユニットテストや機能テスト用のコードをビルドしなくなる。テストコードを含まないため、ビルド時間が短縮され、生成されるバイナリも軽量化。
* BUILD_ITT = OFF
ITTは主にパフォーマンスプロファイリングやトレースに使用されるため、デバッグを行わない場合には不要
* WITH_ITT= OFF 
ITTは主にパフォーマンスプロファイリングやトレースに使用されるため、デバッグを行わない場合には不要

## デバッグ情報(非推奨、必要な場合)
```bash:設定例
CMAKE_C_FLAGS_DEBUG "/MDd"を追加
CMAKE_CXX_FLAGS_DEBUG "/MDd"を追加
```
説明
CMAKE_C_FLAGS_DEBUG "/MDd"を追加
CMAKE_CXX_FLAGS_DEBUG "/MDd"を追加

 **今のところ、これは指定しない方がいい。ほとんどのOSSは/MDdに対応していないのでトラブルの元。**
デバッグ情報の形式が組込むアプリケーションと形式が合わないと、デバッグモードでビルドした実行ファイルだけ、ランタイムエラーになることがある。例では/MDdを指定したが、アプリケーションのデバッグ情報の形式と合わせること。

### その他OpenCVのオプションの公式説明
* https://www.nvidia.co.jp/docs/IO/59373/VolumeI.pdf
* https://ja.wikipedia.org/wiki/Parallel_Thread_Execution
* https://docs.opencv.org/4.x/db/d05/tutorial_config_reference.html
* https://cmake.org/cmake/help/latest/module/FindCUDA.html

### [参考]NVIDIA製ライブラリ関連のOpenCV CMakeオプションパーフェクトガイド
* https://qiita.com/dandelion1124/items/428bcde6df5ad1c9f65d

## その他留意事項
### とにかく環境変数
最近のWindowsに慣れている人にはなじみがないと思うが、とにかく環境変数を正しく設定するのがコツ。何かうまくいかん、と思ったら環境変数をチェックする。OpenCVに関係なさそうな環境変数も、正しく設定されているか確認する。どこで何を参照しているかわからない。


### Cmake使用時の注意事項
時々configureを押す。WITH_CUDAなどをオンすると、オプション項目が追加されることがある。これを反映させるには、再度configureを押す必要がある。

### OpenCVビルド時の注意事項
* nvccが動作しているときに、ビルドのキャンセルはできない。出力表示の更新は止まるが、バックで動いて最後まで止まらない。

### CUDAのコンパイルはすごく遅い
とにかくあり得ないくらい遅い。バグなのかイジワルなのか、CPU負荷は高くないのにとにかく遅い。まともにビルドすると、1~2日かかる。nvcc.exeのバイナリを編集するとか色々試したが、ちゃんと効果があったのはCMAKEオプションのCUDA_ARCH_BINと、CMAKE_CUDA_FLAGS、CUDA_NVCC_FLAGS。それでも24コアのマシンで2時間ほどかかる。

### OpenVINO入りOpenCVのビルドの仕方
1. OpenVINO SDK フルパッケージをダウンロード、導入
https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit/overview.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/77ffd4db-77d9-4037-8d19-90c56d4ce09a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/5c38d027-caf5-440a-b2a8-c4638a09787b.png)
↑オジサンはこの設定で(2025/4/10)、リンク先のZIPファイルを導入(openvino_toolkit_windows_2025.1.0.18503.6fec06580ab_x86_64.zip(115MB) pdbと書いてある方はデバッグファイル)
2. コマンドプロンプトでruntimeの中にあるsetupvars.batを実行
3. 同じコマンドプロンプト内でCMAKEを起動し、Opencvのビルド設定
4. 同じコマンドプロンプト内でOpencv.slnを開いてビルド。または、コマンドプロンプトを開きsetupvars.batを実行してからOpencv.slnを開いてビルド
5. OpenVINO入りOpenCVを使ったアプリには、OpenVINO関連のDLLが必要になる。OpenVINO入りOpenCVを使ったアプリを起動する前にsetupvars.batを実行するか、必要なDLLのところにPathを通す。またはアプリの実行ファイルと同じディレクトリにOpenVINO関連のDLLをコピーしておく。(DLLのコピーが一番無難かと)
6. いちいちsetupvars.batを起動するのが面倒な向きは、下記公式リンクを参考に環境設定のこと。あくまで **参考** なので自分の環境に合わせて調整のこと。
https://www.intel.co.jp/content/www/jp/ja/support/articles/000033440/software/development-software.html

### OpenVINOはAMDのCPUでも使える
OpenVINOはryzenでも使える。むろん「CPUモードで」の話である。OpenVINOのCPUの処理はOpenCLで、AVX2などにも対応している。カリカリチューンが行われているようで、ノーマルのOpenCVより、 **OpenVINOを組み込んだOpenCVの方がdnn処理が数倍速い。** 
一応下記に、GPU(intelのGPU)が有効かどうか調べて、処理をGPUかCPUに切り替えるサンプルを示す。(AIがコーディングする今時、サンプルコードなんて要らないかもしれないが)
``` C++:C++
#include <openvino/openvino.hpp>


        ov::Core core;
        auto devices = core.get_available_devices();

        // 取得したデバイス名を出力（デバッグ用）
        for (const auto& dev : devices) {
            std::cout << "Available device: " << dev << std::endl;
        }
        // GPU がリストに含まれているかチェック
        bool gpuAvailable = false;
        for (const auto& devName : devices) {
            if (devName.find("GPU") != std::string::npos) {
                gpuAvailable = true;
                break; // 見つかったのでループを抜ける
            }
        }
        
        cvDnnNet = cv::dnn::readNetFromONNX(YoloParams.onnx_file_name);
        cvDnnNet.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
        
        //GPUが有効なら
        if(gpuAvailable)
            cvDnnNet.setPreferableTarget(cv::dnn::DNN_TARGET_OPENCL_FP16);
        else
            cvDnnNet.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
```
※上記のコードを走らすにはアプリのビルドの時もOpenVINOのライブラリが必要になる。下記のような感じでリンカーに指定する。
```bat
$(OPENVINO)\lib\intel64\Release\openvino.lib
$(OPENVINO)\lib\intel64\Release\openvino_c.lib
$(OPENVINO)\lib\intel64\Release\openvino_onnx_frontend.lib
```


# 余談
個人的なメモとはいえ読んでいただける人がいるようで、それになりに気を使ってしまう。
実はC++で画像認識をするのは達成している。紆余曲折があっイチからネットワークモデルを移植するのは断念、YOLOを使ったらあっさり上手くいった。それについては忘れる前に(冬休み中)に書き残したいと思う。
とりあえずcmakeである。

## MAKE
CMakeとは何だろうか。昭和のおじさんにはまずこれが分からない。Makeなら分かる。がCMakeは分からない。ナニコレ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/6b16faee-cad2-4a07-a7f1-34149643839d.png)
昔々の大昔、地表が未だ火の玉で巨大な隕石がボコボコ落ちてた頃、数万円でMS-DOSを買うと、ミカン箱の半分くらいの箱に数枚の5インチフロッピーディスクと、数冊の電話帳なみの分厚いマニュアルが入っていた。フロッピーディスクにはMS-DOSのシステムとコマンド類。紙のマニュアルはコマンドの説明、MASMとCPUとチップセットの説明書であった。MASMの説明書にはMASMの使い方のほか、MS-DOSの全APIの説明。CPUの説明書には8086と8087の全命令の説明がずらり。チップセットの説明書には割り込みとかI/Oとかメモリマップとかが書いてあった。

何のことはない、 **標準機能以外にしたい事があれば「オノレで作れ」** と創造主ザ・ゲイツは仰っているのである。必要な情報は付けたからアセンブラで作れと。 **機械語じゃないだけ有難く思え** ということだ。 まさに創成期。天地創造のころの人々にはここからいろいろ苦労話があるわけだが、46億年の歴史をここに書いてるとキリがないので大幅に端折る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/1ccbeccc-cf2c-4612-8b31-79995e5c629d.png)

エディタとCコンパイラと両生類が地上に出て来たころの話。テキストファイルを作ることに関してはだいぶストレスが減ってきた。それは良いのだが、やたら増殖するソースファイルのほか、ヘッダとかOBJファイルとかライブラリとか、ファイルの管理がややこしくなってきた。特に共同で作業する場合は問題である。環境が同じでないとリンクしても変なエラーが出たりする。しかもコンパイルには気が遠くなるような時間が必要だったので、変更のないファイルはコンパイルしたくない。人々はバッチファイルでコンパイルとリンクをしていたが、だんだんそれも面倒になってきた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/77249179-9efd-4dd2-9dc5-906cd0e4bcd4.png)

というわけでmake.exeというものが出て来た。unixの方では昔からあったのかもしれない。確か、コンパイラに付属のユーティリティとしてオマケで付いてきたのたと思う。それともDOSの外部コマンドに入ってたか。使い方は簡単で、適当なテキストファイルに、バイナリを作るのに必要なファイルやライブラリへのパス、コンパイラオプションとかを記述してmake.exeを実行するとバイナリを作ってくれた。バッチファイルに毛が生えた程度の機能しか無かったが、ファイルのバージョン管理をしてくれたので重宝した覚えがある。そのうちmakefile.txtの中でマクロとか変数とか使えるようになってきたが、なんだかややこしくてその辺の機能は余り使わなかった。

さらに悠久の時を経て哺乳類が地上に出現したころか、IDEというものが世間に出て来た。総合開発環境というもので、エディタとファイルの管理、コンパイラのオプションをGUIで設定してくれるようになった。make.exeは(少なくとも私の頭からは)忘れ去られた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/800a2b29-05f5-4b89-ade1-8da2f1472ed5.png)
ところがこの頃のIDE、かなり高価だったのである。Quick Cで確か2万円くらい、Turbo C++で4万円はしたのではなかろうか。Borland C++やMS Cなど業務用に至っては10万円くらいはしたような気がする。OSに金を取られて、さらにそこで動かすソフトの開発ツールにまで金を取るなんて面白くない、というわけでリーナスとかいう貧乏臭い学生?がコンピュータは自由であるべきだとか何とかゴタクを並べてunixモドキのOSを作り始めた。
このunixもどきがまた貧乏臭いもので、CUIメインの操作環境だった。unixの出来損ないである。ディストリビューションが充実した今のlinuxしか知らない人には想像できないだろうが、当時のlinuxは、日本語フォントは〇indowsからパクッてこいとか、Xウィンドウとかツールの類はunixから~~コピー~~移植してこいとか、パクリと違法コピーの限りなく怪しい「雑誌の付録」であった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464633/843a68a0-eaac-4a19-b66c-7b9606096ee0.png)
ダークサイドに落ちたというか初めからダークサイドにいたlinuxだが、フリーソフトでは唯一に近い本格OSだったので、カウンターパワーとして令和までしぶとく生き残ったのは周知の通りである。linuxのおかげでWindowsの値段も低く抑えられてきたような気がする。まそれはともかくCUIメインだったlinuxの環境でmake.exeは生き残り、斜め上に進化していた(想像)。

## CMake
閑話休題、出来れば避けて通りたかったcmakeだったが、ついに越える時が来た。公式から配布されているOpenCVのバイナリはGPUに対応していないらしく、GPUに対応させるにはソースからリビルドしなければならない。その理由についても近いうちに書く。で、そのリビルドにcmakeが指定されているのだ。リビルトの方法は[ここ](https://swallow-incubate.com/archives/blog/20200508/)や、[ここ](https://www.kkaneko.jp/tools/win/windows_opencv.html)に詳しく書いてあるが、備忘録ということで、つまづきポイントを書いておく。

* CMakeはフリーソフト
昭和のおじさんは、まずコレが分らなかった。この事実を把握するのに数年を無駄にしたと言っていい。創成期を知る昭和のおじさんにとっては、makeコマンドのようなシンプルなツールが単独でソフトウェアになっているとは夢にも思わなかったのである。cmakeは、OSか開発ソフトの一部だろうと思いこんでいたのだ。Visual Studioのパッケージの中にもcmake.exeがあるのでややこしい。「cmakeはフリーソフト」、常識以前の話かもしれないが、どこかにはっきり書いておいてほしいものである。
やることは簡単で、ネットでcmakeと検索して公式と思われるサイトからダウンロード、インストールすればいい。これだけである。
著作権とか大人の事情はあるのだろうが、これくらいの機能はVisaul studioに取り込んでほしいものだ。統合環境なんだから。

* CMakeは必ずもビルドしない
創成期のころのmake.exeはコンパイラを起動し、リンカーを起動するものだったが、CMakeはアチコチから必要なファイルを集めたり、設定ファイル作ったり、Visual Studioのプロジェクトファイルを作ったりもするらしい。必ずしもバイナリのビルドまでするわけではないようだ。

* pythonが必要(ではなかった)
cmakeでopencvをビルドするにはpythonが必要らしい。pythonで動いているのか、opencvのビルドにpythonのライブラリが要るのかよくわからないが、cmakeを入れる前にインストールする必要があるようだ。小生のPCにはAnacondaが入っていたのが、Anacondaでも問題なかった。
[追記]
python関係のオプションをOFFにしてしまえば要らないようだ。標準ではONになっている。