OpenCVのNuGetパッケージまとめ（2017年版）

## はじめに
* この記事は[OpenCV Advent Calendar 2017](http://qiita.com/advent-calendar/2017/opencv)の10日目の記事です．
* 他の記事は[目次](https://qiita.com/advent-calendar/2017/opencv)にまとめられています．
* この記事は現在公開されているOpenCVのNuGetパッケージの調査結果になります．どのNuGetパッケージを使うかを選択する際に参考になりましたら幸いです．
  * Windows環境じゃない人ごめんなさい
  * ソースからビルド派，インストーラ派の人ごめんなさい

## NuGetとは
[NuGet](https://www.nuget.org)とは，.NET Framework対応のパッケージ管理システムです．また，Visual Studio 2012以降から標準でNuGetがインストールされているため，ユーザーはNuGetそのものを追加でインストールすることなくNuGetを利用できます．

## NuGetパッケージ一覧
[NuGetのパッケージ検索](https://www.nuget.org/packages)でOpenCVパッケージを探したところ，執筆時点（2017/12/9）では以下のOpenCVパッケージが公開されているようです．NuGetパッケージのインストール方法については[OpenCVの環境構築（OpenCV 3.0／3.1）](http://www.buildinsider.net/small/opencv/003#nuget)を参照ください．

| ID                | NuGetパッケージ名         |
|:--------------------|:------------|
| [1] | [opencv3](https://www.nuget.org/packages/opencv3/) |
| [2] | [opencv3.1](https://www.nuget.org/packages/opencv3.1/) |
| [3] | [opencv.win.native](https://www.nuget.org/packages/opencv.win.native/) |
| [4] | [opencv.win.native.static](https://www.nuget.org/packages/opencv.win.native.static/) |
| [5] | [opencvdefault](https://www.nuget.org/packages/opencvdefault/) |
| [6] | [opencvcontrib](https://www.nuget.org/packages/opencvcontrib/) |
| [7] | [OpenCV31-vc12-x64](https://www.nuget.org/packages/OpenCV31-vc12-x64/) |
| [8] | [opencvcuda-release](https://www.nuget.org/packages/opencvcuda-release/) |

## 検証環境
本記事の検証は以下の環境で実施しました．

| 項目                | 内容         |
|:--------------------|:------------|
| CPU | Intel Core i7-6700HQ 2.60GHz |
| メモリ | 64GB |
| GPU | NVIDIA GeForce GTX 1060 / 6GB |
| OS | Windows 10 Pro 64bit |
| Visual Studioバージョン | Visual Studio 2013, Visual Studio 2015 |
| CUDA | CUDA 9.0 |

## 各NuGetパッケージの紹介
ここでは前述のNuGetパッケージに関する特徴をまとめます．

### [1] opencv3

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencv3/> |
| OpenCVバージョン        | 3.0.0       |
| Visual Studioバージョン | VS2013       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 有     |
| ビルド可否             | 〇           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/1e721e3d6916fe403f4dcd8899b0874b)を参照下さい．

### [2] opencv3.1

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencv3.1/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2013, VS2015       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 無     |
| ビルド可否             | 〇           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/62f945de6313180cdfad7e0935d6869a)を参照下さい．

### [3] opencv.win.native

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencv.win.native/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2015       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 無     |
| ビルド可否             | 〇           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/33a38d75ea5fd28123c86d8de6e85242)を参照下さい．
また，今回は未検証ですが，OpenCV 3.2でVS2015/VS2017に対応したバージョンもあるようです．
<https://www.nuget.org/packages/opencv.win.native/320.1.1-vs141>

### [4] opencv.win.native.static

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencv.win.native.static/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2015       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 無     |
| ビルド可否             | 〇           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/c3226c88db4ddb54e87867c65227bc28)を参照下さい．

#### 注意点
OpenCVや3rdpardyライブラリはstatic libraryのため、プロジェクト設定にて、ランタイムライブラリを`/MD`（デバッグビルドの場合は`/MDd`）に指定するとビルドエラーが起きるのでご注意ください．以下にリリースビルド時のエラーメッセージを抜粋します．

<pre>
1>opencv_imgproc310.lib(imgwarp.obj) : error LNK2038: 'RuntimeLibrary' の不一致が検出されました。値 'MT_StaticRelease' が MD_DynamicRelease の値 'main.obj' と一致しません。
1>opencv_imgproc310.lib(opencv_imgproc_pch.obj) : error LNK2038: 'RuntimeLibrary' の不一致が検出されました。値 'MT_StaticRelease' が MD_DynamicRelease の値 'main.obj' と一致しません。
</pre>

このNuGetパッケージを使用する場合，ランタイムライブラリを`/MT`（デバッグビルドの場合は`/MTd`）にする必要があります．

### [5] opencvdefault

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencvdefault/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2013, VS2015       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 無     |
| ビルド可否             | 〇（x64のみ）           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/6a1d26a37a99e1808a264232a301b3b6)を参照下さい．

#### 注意点
VS2013, VS2015ともにパッケージ内にx86向けのライブラリが配置されているものの，x86向けでビルドした際にリンクエラーが起きます・・・．

<pre>
1>main.obj : error LNK2001: 外部シンボル ""void __cdecl cv::imshow(class cv::String const &,class cv::_InputArray const &)" (?imshow@cv@@YAXABVString@1@ABV_InputArray@1@@Z)" は未解決です。
1>main.obj : error LNK2001: 外部シンボル ""public: void __thiscall cv::Mat::deallocate(void)" (?deallocate@Mat@cv@@QAEXXZ)" は未解決です。
1>main.obj : error LNK2001: 外部シンボル ""public: void __thiscall cv::Mat::create(int,int const *,int)" (?create@Mat@cv@@QAEXHPBHH@Z)" は未解決です。
</pre>

### [6] opencvcontrib

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencvcontrib/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2015       |
| プラットフォーム           | x86, x64     |
| opencv_contribの有無  | 有     |
| ビルド可否             | 〇（x64のみ）           |

`cv::getBuildInformation()`の出力結果は[こちら](https://gist.github.com/atinfinity/c6cf854cde9a4b6e7cae6125cb843958)を参照下さい．
このパッケージの大きな特徴（だと個人的に感じているの）はOpenGL supportとVTK supportが有効になっている点です．

```
  GUI: 
    QT:                          NO
    Win32 UI:                    YES
    OpenGL support:              YES (glu32 opengl32)
    VTK support:                 YES (ver 7.0.0)
```

#### 注意点
パッケージ内にx86向けのライブラリが配置されているものの，x86向けでビルドした際にリンクエラーが起きます・・・．

<pre>
1>main.obj : error LNK2001: 外部シンボル ""void __cdecl cv::imshow(class cv::String const &,class cv::_InputArray const &)" (?imshow@cv@@YAXABVString@1@ABV_InputArray@1@@Z)" は未解決です。
1>main.obj : error LNK2001: 外部シンボル ""public: void __thiscall cv::Mat::deallocate(void)" (?deallocate@Mat@cv@@QAEXXZ)" は未解決です。
1>main.obj : error LNK2001: 外部シンボル ""public: void __thiscall cv::Mat::create(int,int const *,int)" (?create@Mat@cv@@QAEXHPBHH@Z)" は未解決です。
</pre>

### [7] OpenCV31-vc12-x64

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/OpenCV31-vc12-x64/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2013       |
| プラットフォーム           | x64     |
| opencv_contribの有無  | 無     |
| ビルド可否             | ×           |

私の環境ではビルドできませんでした・・・．NuGetパッケージをインストールすると通常インクルードパス、ライブラリパスなどは自動的に設定されるのですが，このパッケージではその設定がうまくできていないようです．

### [8] opencvcuda-release

| 項目                | 内容         |
|:--------------------|:------------|
| URL | <https://www.nuget.org/packages/opencvcuda-release/> |
| OpenCVバージョン        | 3.1.0       |
| Visual Studioバージョン | VS2013       |
| プラットフォーム           | x64     |
| opencv_contribの有無  | 有     |
| ビルド可否             | ?           |

cudaモジュールが使える唯一のNuGetパッケージです．
ただし，CUDA 7.5に依存しているようで私の環境では動作確認できませんでした・・・．

## NuGetパッケージの使い分け
### （NuGetパッケージという選択肢の中で）できるだけ新しいOpenCVを使いたい
* [3] opencv.win.native一択
    * 厳密には最新の<https://www.nuget.org/packages/opencv.win.native/320.1.1-vs141>を使う必要あり

### VS2017で使いたい
* [3] opencv.win.native一択
    * 厳密には最新の<https://www.nuget.org/packages/opencv.win.native/320.1.1-vs141>を使う必要あり

### opencv_contribも使いたい
* [1] opencv3
* [6] opencvcontrib

### vizモジュールを使いたい
* [6] opencvcontrib 一択

### cudaモジュールを使いたい
* 残念ながらNuGetパッケージを使わない方がよいでしょう

## おわりに
* 明日は[fukushima1981](https://twitter.com/fukushima1981)せんせーの記事で，タイトルは<b>「世代別マイクロアーキテクチャごとのOpenCVベンチマーク大会」</b>となっています．すごく楽しみで眠れなさそうです！！！

## 余談（その１）
OpenCV公式がNuGetパッケージ作ってくれるといいのに・・・と思っている人はやっぱりいるようで[Please produce current C++ NuGet package for OpenCV #9320](https://github.com/opencv/opencv/issues/9320)というissueが既に作られています．このissueにある公式メンバのコメントは以下の通りです．

![issue9320.png](https://qiita-image-store.s3.amazonaws.com/0/31158/eebcc044-516d-06fd-e4e2-9278f6e29416.png)

コメントに出てくるVcpkgについては[UnaNancyOwen](https://twitter.com/UnaNancyOwen)さんの[Vcpkgを使用してOpenCVを導入する](https://qiita.com/UnaNancyOwen/items/54c6334f269d03646cad)という記事が参考になります．また，記事執筆時点ではNuGetの方が初心者に優しい気がしている（ボタンをポチポチするだけでインストールできる）ので，公式がNuGet版パッケージを出してくれるといいなーと個人的には思ったりしています．

## 余談（その２）

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Advent Calendarのネタは，OpenCV 3.3.1（自前ビルド）vs OpenCV4Tegra vs ARM Compute Libraryあたりでそろそろ準備しよう</p>&mdash; dandelion (@dandelion1124) <a href="https://twitter.com/dandelion1124/status/934401801171824640?ref_src=twsrc%5Etfw">2017年11月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

当初上記ツイートに書いたネタで記事を書く予定だった・・・のですが，自宅のJetson TX2が起動しなくなりまして，急遽ネタ変更になりました．このお蔵入りになったネタは[この本](https://dandelion1124.booth.pm/items/668611)の続編（？）などで公開出来たらいいなーと思っています．