librealsense2にCuda9.2とPCLを紐づけてWindows10でビルド

こんにちは、すすむです。
半導体エンジニアをやりながら機械学習について学んでます。

[Intel RealSense D435](https://software.intel.com/en-us/realsense/d400)を手に入れたのでまずは環境整備しました。

#やること
librealsense2をCuda, PCL, OpenCV, Python紐づけでVisual Studio 2017で
ビルドしました。いくつか複雑な手順があったので備忘録です。


##環境
CPU: Intel(R) Core(TM) i7-8700
GPU: NVIDIA GTX 1070Ti

Windows 10 Home
CUDA 9.2

Visual Studio Community 2017 (version 15.8.1)
Visual C++ SDK : VC15 (version 14.15)
CMake 3.12.0
Python 3.6.6
Point Cloud Library 1.8.1

##ビルドするもの
librealsense 2.16.0 (with CUDA9.2／PCL／Python／OpenCV)


#下準備
まずはRealSenseデバイスをWindows 10のUSB3ポートに接続して
ファームウェアを更新しましょう。
方法は他サイトでも紹介されているため割愛します。
こちらの[公式](https://downloadcenter.intel.com/download/27514?v=t)(英語)に手順およびファームウェアのファイルがあります。


#Pythonインストール
[Python](https://www.python.org/)もしくは[Anaconda](https://www.anaconda.com/download/)どちらでも良いのでインストール。
以下では Python 3.6.6 をインストールした体で進めます。
環境変数Pathの設定、並びに設定後のPC再起動をお忘れなく。
↓
Numpy (for OpenCV), pybind11 (for librealsense)と連携のためにpipで
numpyパッケージをインストールしておきましょう。
管理者権限のコマンドラインにて

```
> pip install numpy pybind11
```

#Cuda9.2インストール
Cuda9.2のNVidia[公式](https://developer.nvidia.com/cuda-toolkit)にて、「Network」及び「Local」の2種の
インストーラから「Local」の方をダウンロードして起動、
「Custom Install」を選び「Visual Studio Integration」を
探しチェックを入れてインストール。
↓
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\
Common7\IDE\VC\VCTargets\BuildCustomizations　の下に
　CUDA 9.2.props
　CUDA 9.2.targets
などのCUDA関連ファイルがあればOKです。


#OpenCVインストール
librealsense2 ビルドの前提である Open CV について、CUDAとの
連携ビルドには注意が必要です。筆者の[こちらの記事](https://qiita.com/Susumu0417/items/c0823f6649d2dddc1679)をご参考ください。


#PCLインストール
[こちら](http://unanancyowen.com/pcl181/)で公開されているPCL-1.8.1のビルド済みライブラリを活用します。
(必要パッケージを全て自力でビルドするのは非常に手間が掛かります。。。)

"PCL 1.8.1 All-in-one Installer MSVC2017 x64" というリンクから
.exeインストーラをダウンロードして実行、設定はデフォルトでOKです。

環境変数に以下を設定。
```PCL_ROOT = C:\Program Files\PCL1.8.1```
```OPENNI2_INCLUDE64 = C:\Program Files\OpenNI2\Include\```
```OPENNI2_LIB64 = C:\Program Files\OpenNI2\Lib\```
```OPENNI2_REDIST64 = C:\Program Files\OpenNI2\Redist\```

環境変数のPathに以下を設定。
```%PCL_ROOT%\bin```
```%OPENNI2_REDIST64%```
```%PCL_ROOT%3rdParty\FLANN\bin```
```%PCL_ROOT%3rdParty\Qhull\bin```
```%PCL_ROOT%3rdParty\VTK\bin```


設定後に再起動をお忘れなく。


#librealsense2インストール
[こちら](https://github.com/IntelRealSense/librealsense)からlibrealsense2をダウンロード、解凍して始めます。
解凍後ファイルは例えばC:\の下などに置けばOKです。


##librealsense2 メタデータの有効化
librealsense2でRealSenseデバイスを制御できるようにします。

RealSenseをPCのUSB3ポートに接続した状態で
①PowerShellを管理者権限で起動 (ホームボタンを右クリック)

②Set-ExecutionPolicyコマンド
　↓
　ExecutionPolicy を "Unrestricted" に変更。
　(セキュリティ上はあまり良くないので後でAllsignedなどに
　 戻した方が良いかも)

③以下でメタデータを有効化

```
>cd C:\librealsense-xxx\scripts
>.\realsense_metadata_win10.ps1 -op install
```

##CUDA関連ファイルの編集
CUDA連携でビルドするためには、いくつかのファイルに問題が
あるため編集が必要になります。

####host_config.h
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include\crt
の下にある host_config.h について以下のように編集。

```C++:host_config.h
#if _MSC_VER < 1600 || _MSC_VER > 1913    //131行目あたり
↓
#if _MSC_VER < 1600 || _MSC_VER > 1915    //VC++ 14.15でビルドできるように
```

####pointcloud.cpp
C:\librealsense-xxx\src\proc の下にある pointcloud.cpp に
コードミスがあるため修正します。

```C++:pointcloud.cpp
#ifdef RS2_USE_CUDA
#include "../cuda/cuda-pointcloud.cuh"
#elif __SSSE3__
#include <tmmintrin.h> // For SSE3 intrinsic used in unpack_yuy2_sse
#endif

↓

#ifdef RS2_USE_CUDA
#include "../cuda/cuda-pointcloud.cuh"
#include <tmmintrin.h>     //この一行を加える
#elif __SSSE3__
#include <tmmintrin.h> // For SSE3 intrinsic used in unpack_yuy2_sse
#endif
```

(備考)
CMakeで「BUILD_WITH_CUDA」が指定されたとき、上記コード中の
「RS2_USE_CUDA」が True となり、その下のヘッダが読み込まれます。
したがって改変前のコードでは「BUILD_WITH_CUDA」を指定すると
「#include \<tmmintrin.h>」は飛ばされることになります。

しかし、本ファイルをコンパイルする際に \<tmmintrin.h> が必須となる
ようコーディングされているため、CUDAの有無に関わらずこれを Include
するように訂正が必要になります。


##CMake
Cmake で以下指定で「Configure」
```Where is the source:  C:/librealsesne-xxx```
```Where to build the binaries:  C:/librealsesne-xxx/build```
↓
ビルドオプションで「Visual Studio 15 2017 X64」を選択。
↓
オプションを以下のように設定。

|Name|Value|
|:------------|:------------|
|BUILD_CV_EXAMPLES|ON|
|BUILD_EASYLOGGINGPP|ON|
|BUILD_EXAMPLES|ON|
|BUILD_GRAPHICAL_EXAMPLES|ON|
|BUILD_PCL_EXAMPLES|ON|
|BUILD_PYTHON_BINDINGS|ON|
|BUILD_RS400_EXTRAS|ON　(なければ「Add Entry」)|
|BUILD_SHARED_LIBS|ON|
|BUILD_UNIT_TESTS|ON|
|BUILD_WITH_CUDA|ON|
|BUILD_WITH_STATIC_CRT|ON　(なければ「Add Entry」)」|
|CMAKE_CONFIGURATION_TYPES|Debug;Release;MinSizeRel;RelWithDebInfo|
|CMAKE_INSTALL_PREFIX|C:/Program Files/librealsense2|
|DOTNET_VERSION_EXAMPLES|4.0|
|DOTNET_VERSION_LIBRARY|3.5|
|ENFORCE_METADATA|ON|
|HWM_OVER_XU|ON|
|OpenCV_DIR|(OpenCVビルドして設定したPath)|
|PYBIND11_INSTALL|ON|
|PYBIND11_CMAKECONFIG_INSTALL_DIR|share/cmake/pybind11|
|USE_PYTHON_INCLUDE_DIR|ON|
|USE_SYSTEM_LIBUSB|ON|
↓
「Configure」
↓
以下が自動でセットされるのを確認。

|Name|Value|
|:------------|:------------|
|CUDA_HOST_COMPILER|\$(VCInstallDir)Tools/MSVC/\$(VCToolsVersion)/bin/Host\$(Platform)/$(PlatformTarget)|
|CUDA_TOOLKIT_ROOT_DIR|C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.2|
↓
「Configure」⇒「Generate」


##Visual Studio でビルド
Visual Studio を管理者権限で起動。
C:\librealsesne-+++/build の下にできた「librealsense2.sln」を開く。

####Projectファイルの設定変更
Solution Explorerで「Library」→「realsense2」を右クリックして
「properties」を選択。
↓
下図のように Propertiesウィンドウにおいて

・Configurationタブを「Active」に

・Code Generation の「Runtime Library」項目にて
　　- Debugビルドの時は「Multi-threaded Debug DLL (/MDd)」
　　- Releaseビルドの時は「Multi-threaded DLL (/MD)」
　をそれぞれ指定。(下図はReleaseビルドの例)

・同様のことを
　　- 「Library」→「realsense-file」
　　- 「Tools」→「rs-rosbag-inspector」
　に対しても行う。

![VS設定1.png](https://qiita-image-store.s3.amazonaws.com/0/270214/1b22ab10-837f-8ec3-3a54-26cb3f151433.png)


####ビルド
ツールバーからBuildタブ→「Build Solution」
↓
Solution Explorer上でCMakePredefinedTargets→INSTALLを選択した状態で
ツールバーからBuildタブ→「Project Only →「Build Only INSTALL」
↓
Solution Configurationで「Release」についても同様に行う。
(！！上記 "Projectファイルの設定変更" を再度行うのを忘れずに！！)


#Pythonで動作確認
####.pydファイルのコピー
C:\librealsense-master\build\Release\pyrealsense2.cp36-win_amd64.pyd
を以下にコピー
↓
C:\Program Files\Python36\Lib\site-packages

####パスの設定
環境変数
```realsense2_DIR = C:\Program Files\librealsense2```

環境変数Path
```%realsense2_DIR%\bin```

↓
再起動

####pyrealsense2 で RealSense D435 の操作確認
RealSenseデバイスをUSB3ポートに接続
↓
コマンドラインを起動

```
>cd C:\librealsense-master\wrappers\python\examples
>python opencv_viewer_example.py
```

↓
RealSenseの映像が表示されれば成功！


#おわりに
いかがでしたでしょうか？ご参考になれば幸いです。

今後、画像処理/機械学習や半導体のトピックスについて
随時ご紹介していくので是非フォローいただけると嬉しいです！