Visual Studio 2017 + OpenCV 3.4.1 + CUDA 10.0 + Intel TBB 2018U5 ビルド手順

# 環境
・Windows 7 Professional 64bit
・Intel Corei7-3770K
・16GB RAM
・Geforce GTX 780
・Visual Studio 2017 Version 15.7.0
・CMake 3.12.0


# 事前準備
・OpenCV 3.4.1 [ダウンロード](https://opencv.org/opencv-3-4-1.html)
　「Sources」をクリックしてダウンロード。
　ダウンロード後、解凍(e.g. C:\opencv\3.4.1)
　※今回はエクストラモジュール入れてません。
・Intel TBB [ダウンロード](https://github.com/01org/tbb/releases/tag/2018_U5)
　「tbb2018_20180618oss_win.zip」をクリックしてダウンロード。
　ダウンロード後、解凍(e.g. C:\intel_tbb)
　解凍後、下記パスをシステム環境変数に追加。
　　C:\intel_tbb\tbb2018_20180618oss\bin\intel64\vc14
　　C:\intel_tbb\tbb2018_20180618oss\lib
・CUDA Toolkit 10.0
　CUDA 10.0のインストール手順は[こちら](https://qiita.com/East_san/items/62adb216b0e6f801ae1d)に記載してます。
・CMake 3.12.0
　CMake 3.12.0のインストール手順は[こちら](https://qiita.com/East_san/items/b8ebc34dad226865899a)に記載してます。

事前準備完了後、一応再起動。

# CMakeの設定
CMakeを起動し、「Browse Source」と「Browse Build」を選択します。
それぞれBrowse Sourceがダウンロードし、解凍したフォルダ、Browse Buildが
ビルド先のフォルになります。ここでは、次のように設定しました。
Browse Source：C:/opencv/3.4.1/opencv-3.4.1
Browse Build：C:/opencv/3.4.1/build
![WS000000.png](https://qiita-image-store.s3.amazonaws.com/0/92978/c8bdb817-9d84-5104-8ec2-a2035f40f024.png)
「Grouped」と「Advanced」にチェックが入っていることを確認し、
「Configure」を押します。
![WS000001.png](https://qiita-image-store.s3.amazonaws.com/0/92978/ac7e7a31-528d-f041-2048-34dc12baeb4e.png)
「Visual Studio 15 2017 Win64」を選び、「Finish」を押します。
![WS000002.png](https://qiita-image-store.s3.amazonaws.com/0/92978/0808ed9a-5eef-d02d-5f6f-1eb706f33815.png)
「WITH_CUBLAS」、「WITH_CUDA」、「WITH_OPENGL」、「WITH_TBB」にチェックを入れ、
「Configure」を押します。
赤くなっているのがOpenGLとTBBだけになります。OpenGLはそのままで、
TBBを次のように設定し、「Configure」を押します。

| Name             | Value|
|:-----------------|:------------------|
| TBB_DIR          |C:/intel_tbb/tbb2018_20180618oss|
| TBB_ENV_INCLUDE  |C:/intel_tbb/tbb2018_20180618oss/include|
| TBB_ENV_LIB      |C:/intel_tbb/tbb2018_20180618oss/lib/intel64/vc14/tbb.lib|
| TBB_ENV_LIB_DEBUG|C:/intel_tbb/tbb2018_20180618oss/lib/intel64/vc14/tbb_debug.lib|

TBB_VER_FILEのみ赤くなるが値は自動で設定されるので(C:/intel_tbb/tbb2018_20180618oss/include/tbb/tbb_stddef.h)、そのまま「Configure」を押します。
赤くならないことを確認し、「Generate」を押します。
![WS000003.png](https://qiita-image-store.s3.amazonaws.com/0/92978/f4e008d6-39af-af93-86a2-eb73b18a61b8.png)

# Visual StudioでOpenCV.slnのビルド
- CMakeのBrowse Buildで選択したフォルダに、OpenCV.slnがあるので、<br>Visual Studioで開いてください。
- その後、「ALL_BUILD」、「INSTALL」の順にそれぞれ、Debug、Releaseでビルドしていくのですが、今までの設定が正しいかを早く知るために私は「opencv_core」を先にビルドしてみます。何か問題がある場合は、ここでエラーが出る場合が多いです。ですので、不要だと思う場合は、このステップはスキップしていただいても構いません。「opencv_core」のビルドが正常にできれば、正常終了:11になります。
- 「opencv_core」のビルドが問題なければ、Debugで「ALL_BUILD」、「INSTALL」をビルド、Releaseで「ALL_BUILD」、「INSTALL」をビルドします。<br>CUDAを含めるとビルドにかなり時間がかかりますので、寝る前や暇な時にビルドしておいたほうがいいです。
私の環境で、５～６時間掛かりました。
- ビルド完了後、「install\x64\vc15\bin」が作成されていますので、パスを通します(e.g. C:\opencv\3.4.1\build\install\x64\vc15\bin)。

※文字コード関係のwarning C4819が大量に出ますが気にしなくてもいいかと
思います。

以上でビルドに関しては完了です！


# 動作確認
実際に動作するかの確認を行います。

- 「install\include」(e.g. C:\opencv\3.4.1\build\install\include)に下記内容の「opencv_lib.hpp」を保存

```c++:opencv_lib.hpp
// バージョン取得
#define CV_VERSION_STR CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)

// ビルドモード
#ifdef _DEBUG
#define CV_EXT_STR "d.lib"
#else
#define CV_EXT_STR ".lib"
#endif

// Main Module
#pragma comment(lib, "opencv_calib3d" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_core" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_dnn" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_features2d" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_flann" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_highgui" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_imgcodecs" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_imgproc" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_ml" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_objdetect" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_photo" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_shape" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_stitching" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_superres" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_video" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_videoio" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_videostab" CV_VERSION_STR CV_EXT_STR)

// GPU module
#pragma comment(lib, "opencv_cudaimgproc" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudaarithm" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudabgsegm" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudacodec" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudafeatures2d" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudafilters" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudalegacy" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudaobjdetect" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudaoptflow" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudastereo" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudawarping" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_cudev" CV_VERSION_STR CV_EXT_STR)
```

- Visual Studioを起動します
- ソリューション エクスプローラー＞ソースファイルを右クリック＞追加＞新しい項目＞左メニューのVisual C+＋からC++ ファイル(.cpp)を選択＞追加
- ソースファイルに「Source.cpp」が追加されます
- ソリューション エクスプローラー＞ソリューションを右クリック＞プロパティ＞構成をすべての構成
- その後、追加のインクルードディレクトリと追加のライブラリディレクトリを設定します。
e.g.

| 項目             | 追加パス|
|:-----------------|:------------------|
| 追加のインクルードディレクトリ          |C:\opencv\3.4.1\build\install\include;C:\intel_tbb\tbb2018_20180618oss\include;|
| 追加のライブラリディレクトリ  |C:\opencv\3.4.1\build\install\x64\vc15\lib;C:\intel_tbb\tbb2018_20180618oss\lib\intel64\vc14;|

- 「Source.cpp」に下記テストコードを追加（実際には、試したい機能などを記述して実行してみると良いと思います。

```c++:Source.cpp
#include <iostream>
#include <opencv/cv.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv_lib.hpp>

using namespace std;

int main()
{
	//OpenCV ビルド情報の表示
	cout << cv::getBuildInformation() << endl;

	cv::Mat SrcImage = cv::imread("Penguins.jpg");

	cv::namedWindow("OpenCV Test", cv::WINDOW_AUTOSIZE);
	cv::imshow("OpenCV Test", SrcImage);

	//GPU デバイス情報の表示
	cv::cuda::printCudaDeviceInfo(cv::cuda::getDevice());

	//GPU デバイス情報を個々で表示することも可能
	cv::cuda::DeviceInfo info(0);
	cout <<
		"Name (Device ID): " << info.name() << endl <<
		"MajorVersion: " << info.majorVersion() << endl <<
		"MinorVersion: " << info.minorVersion() << endl <<
		"Clock rate:" << info.clockRate() << endl <<
		"FreeMemory: " << info.freeMemory() << endl <<
		"TotalMemory: " << info.totalMemory() << endl <<
		"isCompatible: " << info.isCompatible() << endl <<
		"Global Memory bus width(bits):" << info.memoryBusWidth() << endl <<
		"supports(FEATURE_SET_COMPUTE_10): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_10) << endl <<
		"supports(FEATURE_SET_COMPUTE_11): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_11) << endl <<
		"supports(FEATURE_SET_COMPUTE_12): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_12) << endl <<
		"supports(FEATURE_SET_COMPUTE_13): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_13) << endl <<
		"supports(FEATURE_SET_COMPUTE_20): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_20) << endl <<
		"supports(FEATURE_SET_COMPUTE_21): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_21) << endl <<
		"supports(FEATURE_SET_COMPUTE_30): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_30) << endl <<
		"supports(FEATURE_SET_COMPUTE_35): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_35) << endl <<
		"supports(FEATURE_SET_COMPUTE_50): " << info.supports(cv::cuda::FEATURE_SET_COMPUTE_50)
	<< endl;

	//GPUを使ってRGBからグレースケールの変換テスト
	cv::cuda::GpuMat GPU_SrcImage(SrcImage);
	cv::cuda::GpuMat GPU_DstImage;
	
	cv::cuda::cvtColor(GPU_SrcImage, GPU_DstImage, cv::COLOR_BGR2GRAY);
	cv::namedWindow("GPU Test", cv::WINDOW_AUTOSIZE | cv::WINDOW_OPENGL);
	cv::imshow("GPU Test", GPU_DstImage);
	cv::waitKey(0);

	return 0;
}
```

- 正常にビルドされ、実行すると以下のような出力結果と画像が出てきます。

```text:出力結果

General configuration for OpenCV 3.4.1 =====================================
  Version control:               unknown

  Platform:
    Timestamp:                   2018-10-01T05:05:27Z
    Host:                        Windows 6.1.7601 AMD64
    CMake:                       3.12.0
    CMake generator:             Visual Studio 15 2017 Win64
    CMake build tool:            C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/Bin/MSBuild.exe
    MSVC:                        1914

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (3 files):          + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (2 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (5 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (9 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2

  C/C++:
    Built as dynamic libs?:      YES
    C++11:                       YES
    C++ Compiler:                C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe  (ver 19.14.26428.1)
    C++ flags (Release):         /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP8   /MD /O2 /Ob2 /DNDEBUG 
    C++ flags (Debug):           /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP8   /MDd /Zi /Ob0 /Od /RTC1 
    C Compiler:                  C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe
    C flags (Release):           /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP8    /MD /O2 /Ob2 /DNDEBUG 
    C flags (Debug):             /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP8  /MDd /Zi /Ob0 /Od /RTC1 
    Linker flags (Release):      /machine:x64  /INCREMENTAL:NO 
    Linker flags (Debug):        /machine:x64  /debug /INCREMENTAL 
    ccache:                      NO
    Precompiled headers:         YES
    Extra dependencies:          opengl32 glu32 C:/intel_tbb/tbb2018_20180618oss/lib/intel64/vc14/tbb.lib cudart.lib nppc.lib nppial.lib nppicc.lib nppicom.lib nppidei.lib nppif.lib nppig.lib nppim.lib nppist.lib nppisu.lib nppitc.lib npps.lib cublas.lib cufft.lib -LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0/lib/x64
    3rdparty dependencies:

  OpenCV modules:
    To be built:                 calib3d core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev dnn features2d flann highgui imgcodecs imgproc java_bindings_generator ml objdetect photo python_bindings_generator shape stitching superres ts video videoio videostab
    Disabled:                    js world
    Disabled by dependency:      -
    Unavailable:                 java python2 python3 viz
    Applications:                tests perf_tests apps
    Documentation:               NO
    Non-free algorithms:         NO

  Windows RT support:            NO

  GUI: 
    Win32 UI:                    YES
    OpenGL support:              YES (opengl32 glu32)
    VTK support:                 NO

  Media I/O: 
    ZLib:                        build (ver 1.2.11)
    JPEG:                        build (ver 90)
    WEBP:                        build (ver encoder: 0x020e)
    PNG:                         build (ver 1.6.34)
    TIFF:                        build (ver 42 - 4.0.9)
    JPEG 2000:                   build (ver 1.900.1)
    OpenEXR:                     build (ver 1.7.1)

  Video I/O:
    Video for Windows:           YES
    DC1394:                      NO
    FFMPEG:                      YES (prebuilt binaries)
      avcodec:                   YES (ver 57.107.100)
      avformat:                  YES (ver 57.83.100)
      avutil:                    YES (ver 55.78.100)
      swscale:                   YES (ver 4.8.100)
      avresample:                YES (ver 3.7.0)
    GStreamer:                   NO
    DirectShow:                  YES

  Parallel framework:            TBB (ver 2018.0 interface 10005)

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Intel IPP:                   2017.0.3 [2017.0.3]
           at:                   C:/opencv/3.4.1/build/3rdparty/ippicv/ippicv_win
    Intel IPP IW:                sources (2017.0.3)
              at:                C:/opencv/3.4.1/build/3rdparty/ippicv/ippiw_win
    Lapack:                      NO
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.5.1)

  NVIDIA CUDA:                   YES (ver 10.0, CUFFT CUBLAS)
    NVIDIA GPU arch:             30 35 37 50 52 60 61 70
    NVIDIA PTX archs:

  OpenCL:                        YES (no extra features)
    Include path:                C:/opencv/3.4.1/opencv-3.4.1/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python (for build):            D:/Python27/python.exe

  Java:                          
    ant:                         NO
    JNI:                         C:/Program Files/Java/jdk1.8.0_40/include C:/Program Files/Java/jdk1.8.0_40/include/win32 C:/Program Files/Java/jdk1.8.0_40/include
    Java wrappers:               NO
    Java tests:                  NO

  Matlab:                        NO

  Install to:                    C:/opencv/3.4.1/build/install
-----------------------------------------------------------------


*** CUDA Device Query (Runtime API) version (CUDART static linking) *** 

Device count: 1

Device 0: "GeForce GTX 780"
  CUDA Driver Version / Runtime Version          10.0 / 10.0
  CUDA Capability Major/Minor version number:    3.5
  Total amount of global memory:                 3072 MBytes (3221225472 bytes)
  (12) Multiprocessors x (192) CUDA Cores/MP:     2304 CUDA Cores
  GPU Clock Speed:                               1.03 GHz
  Max Texture Dimension Size (x,y,z)             1D=(65536), 2D=(65536,65536), 3D=(4096,4096,4096)
  Max Layered Texture Size (dim) x layers        1D=(16384) x 2048, 2D=(16384,16384) x 2048
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per block:           1024
  Maximum sizes of each dimension of a block:    1024 x 1024 x 64
  Maximum sizes of each dimension of a grid:     2147483647 x 65535 x 65535
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and execution:                 Yes with 1 copy engine(s)
  Run time limit on kernels:                     Yes
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Concurrent kernel execution:                   Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support enabled:                No
  Device is using TCC driver mode:               No
  Device supports Unified Addressing (UVA):      Yes
  Device PCI Bus ID / PCI location ID:           2 / 0
  Compute Mode:
      Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) 

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version  = 10.0, CUDA Runtime Version = 10.0, NumDevs = 1

Name (Device ID): GeForce GTX 780
MajorVersion: 3
MinorVersion: 5
Clock rate:1032500
FreeMemory: 2530344960
TotalMemory: 3221225472
isCompatible: 1
Global Memory bus width(bits):384
supports(FEATURE_SET_COMPUTE_10): 1
supports(FEATURE_SET_COMPUTE_11): 1
supports(FEATURE_SET_COMPUTE_12): 1
supports(FEATURE_SET_COMPUTE_13): 1
supports(FEATURE_SET_COMPUTE_20): 1
supports(FEATURE_SET_COMPUTE_21): 1
supports(FEATURE_SET_COMPUTE_30): 1
supports(FEATURE_SET_COMPUTE_35): 1
supports(FEATURE_SET_COMPUTE_50): 0

```

![WS000004.png](https://qiita-image-store.s3.amazonaws.com/0/92978/aeb48104-4dda-778b-3ca4-c75b9f47521e.png)

![WS000005.png](https://qiita-image-store.s3.amazonaws.com/0/92978/2098aeb1-e60c-a5fe-6051-3d039d7b8795.png)

以上で全て完了となります！

# トラブルシューティング
私がビルド中に発生したトラブルの解決策について記述。

- 動作確認の際に、Intel TBB関連で「プロシージャエントリポイント。。。」と出てうまくビルドができない。
<br>→OpenCL SDKが入っていて、そのパス(e.g. C:\Program Files (x86)\Intel\OpenCL SDK\1.5\bin\x64)が環境変数に追加されていると発生します。これは、パスの中にIntel TBBと同様のtbb.dllがこの中に含まれており、それが原因ではないかと考えています。そのため、環境変数からパスを消すことで解決します。