ros-openvino-toolkitのインストールからサンプルの拡張までの手引き

# はじめに
みなさんros-openvino-toolkit関係のインストールやビルドをしていて、一発でうまくいったことはありますか？
私はありません。。。
そんな私と同じような境遇の方のため、兼自分用の備忘録としてメモを残しておきます。
基本的には公式の手順通りですので、読者は自分のPCに早く環境を整えたい初心者を想定しています。
過去に色々開発をしていて古いopenCVなどが入っている方は、まっさらにするかバージョンを上げてから取り掛かってください。

##この記事を読んでできるようになること
・rosに対応したopenvinoを使えるようになる
・ros-openvino-toolkitのサンプルを拡張できる

## 環境
intel NUC(Ubuntu18.04)<br>

Python 3.6.9<br>

## 環境構築手順
###環境構築をするまえに...
gitなどがないかたは先にインストールをしておいてください。

```
sudo apt install git curl python3-pip python3-networkx
pip3 install numpy
```

###1. openvinoのダウンロードからビルドまで
まずはopenvinoをダウンロードします。
**注意!:** openvinoのバージョンは必ず2018_R5を選択してください。2020年1月現在、いくつもの新しいバージョンがありますが、2019年の物はすべてうまくいきませんでした(自分の力不足で)。古いのもよろしくないです。

```
cd ~/Downloads
wget -c http://registrationcenter-download.intel.com/akdlm/irc_nas/15078/l_openvino_toolkit_p_2018.5.455.tgz
tar -xvf l_openvino_toolkit_p_2018.5.455.tgz
cd l_openvino_toolkit_p_2018.5.455
sudo -E ./install_cv_sdk_dependencies.sh
```

つぎのコマンドでopenvinoのインストールが始まりますが、基本的に全部acceptやyesを選択して大丈夫です。

```
sudo ./install_GUI.sh
```

つづいて以下のコマンドを入力してください。

```
source /opt/intel/computer_vision_sdk/bin/setupvars.sh
cd /opt/intel/computer_vision_sdk/deployment_tools/inference_engine
sudo chmod 777 samples
cd samples
mkdir build
cd build
cmake ..
make -j8
```

次はUSBのアクセスルールの設定です。

```
cd ~/Downloads

cat <<EOF > 97-usbboot.rules
SUBSYSTEM=="usb", ATTRS{idProduct}=="2150", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
SUBSYSTEM=="usb", ATTRS{idProduct}=="2485", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
SUBSYSTEM=="usb", ATTRS{idProduct}=="f63b", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
EOF

sudo cp 97-usbboot.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
```

次にldconfigをするのですが、今のままだとシンボリックが正しく貼れません。なので、原因となっているファイルをリネームするか、削除しなければいけません。今回は削除をした後に手動でリンクを貼ります。削除をしたくない方はmvコマンドでリネームするなりしてください。

```
cd /opt/intel/common/mdf/lib64

sudo rm igfxcmrt64.so
sudo ln -s libigfxcmrt64.so igfxcmrt64.so

cd /opt/intel/mediasdk/lib64

sudo rm libmfxhw64.so.1 libmfx.so.1 libva-glx.so.2 libva.so.2 libigdgmm.so.1 libva-drm.so.2 libva-x11.so.2

sudo ln -s libmfxhw64.so.1.28 libmfxhw64.so.1
sudo ln -s libmfx.so.1.28 libmfx.so.1
sudo ln -s libva-glx.so.2.300.0 libva-glx.so.2
sudo ln -s libva.so.2.300.0 libva.so.2
sudo ln -s libigdgmm.so.1.0.0 libigdgmm.so.1
sudo ln -s libva-drm.so.2.300.0 libva-drm.so.2
sudo ln -s libva-x11.so.2.300.0 libva-x11.so.2
```

もとに戻って続きをします

```
cd ~/Downloads
sudo ldconfig
rm 97-usbboot.rules
```

nano ~/.bashrcかなにかでbashrcを開いて以下の一文を書き込んでください。

```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/intel/computer_vision_sdk/deployment_tools/inference_engine/samples/build/intel64/Release/lib
```

次のコマンドを入力したら一段落です。

```
source /opt/intel/computer_vision_sdk/bin/setupvars.sh
```

###2. 必要な物のインストール
githubからintelさんのros-openvino-toolkitをcloneしてその中のscriptフォルダに移動します。

```
cd ~/ros_openvino_toolkit/script
```

このディレクトリ内にあるmodules.confというファイルにはopencv=1とかが書いてあります。この引数が1だとenvironment_setup.shの対応している部分のコードが実行され、インストールなどがされます。もし、すでにopencvなどが入っているという方は、インストールしたくない部分の引数を0に変更してください。
**今回はmodules.confのdldtとmodel_zooの引数を0にしてください**
では、modules.confの設定が終わったら下記を実行してください。
**注意 : かなり時間がかかります**

```
./environment_setup.sh
```

終わったら先程引数を0にしたdldtとmodel_zooを手動でインストールします。

```
mkdir -p ~/code && cd ~/code
git clone https://github.com/opencv/dldt.git
cd dldt/inference-engine/
git checkout 2018_R5
./install_dependencies.sh
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j8
sudo mkdir -p /opt/openvino_toolkit
sudo ln -s ~/code/dldt /opt/openvino_toolkit/dldt

cd ~/code
git clone https://github.com/opencv/open_model_zoo.git
cd open_model_zoo/demos/
git checkout 2018_R5
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release /opt/openvino_toolkit/dldt/inference-engine
make -j8
sudo mkdir -p /opt/openvino_toolkit
sudo ln -s ~/code/open_model_zoo /opt/openvino_toolkit/open_model_zoo
```

次に~/.bashrcにパスを記述します。
bashrcを開いて次の3行を入力してください。

```
export InferenceEngine_DIR=/opt/openvino_toolkit/dldt/inference-engine/build/
export CPU_EXTENSION_LIB=/opt/openvino_toolkit/dldt/inference-engine/bin/intel64/Release/lib/libcpu_extension.so
export GFLAGS_LIB=/opt/openvino_toolkit/dldt/inference-engine/bin/intel64/Release/lib/libgflags_nothreads.a
```

これが終わったらワークスペースを作成してros_openvinoのパッケージをインストールしていきます。(catkin_initを忘れずに)

```
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
git clone https://github.com/intel/ros_openvino_toolkit
git clone https://github.com/intel/object_msgs
git clone https://github.com/ros-perception/vision_opencv
git clone https://github.com/intel-ros/realsense
cd realsense
git checkout 2.1.3
```

パッケージをビルドします

```
# Ubuntu 16.04
source /opt/ros/kinetic/setup.bash
# Ubuntu 18.04
source /opt/ros/melodic/setup.bash
 
cd ~/catkin_ws
catkin_make
source devel/setup.bash
sudo mkdir -p /opt/openvino_toolkit
sudo ln -s ~/catkin_ws/src/ros_openvino_toolkit /opt/openvino_toolkit/ros_openvino_toolkit
```

これでビルドは一通り完了です。

###3. 実行するための準備
intelが事前に用意してくれている学習済みモデルのダウンロードやコンバートをしていきます。

```
#基本的には全部ダウンロードしていただいて大丈夫です
#オブジェクトセグメンテーションをする方は以下を実行してください

cd /opt/openvino_toolkit/dldt/model-optimizer/install_prerequisites
sudo ./install_prerequisites.sh
mkdir -p ~/Downloads/models
cd ~/Downloads/models
wget http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
tar -zxvf mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
cd mask_rcnn_inception_v2_coco_2018_01_28
python3 /opt/openvino_toolkit/dldt/model-optimizer/mo_tf.py --input_model frozen_inference_graph.pb --tensorflow_use_custom_operations_config /opt/openvino_toolkit/dldt/model-optimizer/extensions/front/tf/mask_rcnn_support.json --tensorflow_object_detection_api_pipeline_config pipeline.config --reverse_input_channels --output_dir ./output/
sudo mkdir -p /opt/models
sudo ln -s ~/Downloads/models/mask_rcnn_inception_v2_coco_2018_01_28 /opt/models/


#オブジェクトディテクションをする方は以下を実行してください

cd /opt/openvino_toolkit/open_model_zoo/model_downloader
python3 ./downloader.py --name mobilenet-ssd


#とりあえず実行してください
sudo python3 /opt/openvino_toolkit/dldt/model-optimizer/mo.py --input_model /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/mobilenet-ssd.caffemodel --output_dir /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/output/FP32 --mean_values [127.5,127.5,127.5] --scale_values [127.5]


#NCS2つかうよーって方は実行してください
sudo python3 /opt/openvino_toolkit/dldt/model-optimizer/mo.py --input_model /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/mobilenet-ssd.caffemodel --output_dir /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/output/FP16 --data_type=FP16 --mean_values [127.5,127.5,127.5] --scale_values [127.5]
```

次に基本的な機能を使うためのものをインストールします

```
cd /opt/openvino_toolkit/open_model_zoo/model_downloader
python3 downloader.py --name face-detection-adas-0001
python3 downloader.py --name age-gender-recognition-retail-0013
python3 downloader.py --name emotions-recognition-retail-0003
python3 downloader.py --name head-pose-estimation-adas-0001
python3 downloader.py --name person-detection-retail-0013
python3 downloader.py --name person-reidentification-retail-0076
```

ラベルファイルをコピーします(必要のないものはしなくて大丈夫です)

```
sudo cp /opt/openvino_toolkit/ros_openvino_toolkit/data/labels/emotions-recognition/FP32/emotions-recognition-retail-0003.labels /opt/openvino_toolkit/open_model_zoo/model_downloader/Retail/object_attributes/emotions_recognition/0003/dldt
sudo cp /opt/openvino_toolkit/ros_openvino_toolkit/data/labels/face_detection/face-detection-adas-0001.labels /opt/openvino_toolkit/open_model_zoo/model_downloader/Transportation/object_detection/face/pruned_mobilenet_reduced_ssd_shared_weights/dldt
sudo cp /opt/openvino_toolkit/ros_openvino_toolkit/data/labels/object_segmentation/frozen_inference_graph.labels /opt/models/mask_rcnn_inception_v2_coco_2018_01_28/output
sudo cp /opt/openvino_toolkit/ros_openvino_toolkit/data/labels/object_detection/mobilenet-ssd.labels /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/output/FP32
sudo cp /opt/openvino_toolkit/ros_openvino_toolkit/data/labels/object_detection/mobilenet-ssd.labels /opt/openvino_toolkit/open_model_zoo/model_downloader/object_detection/common/mobilenet-ssd/caffe/output/FP16
```

bashrcにパスを書き込みます

```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/openvino_toolkit/dldt/inference-engine/bin/intel64/Release/lib
```

ビルドなどは以上です。おつかれさまでした。

###4. サンプルの実行
普通のUSBカメラで顔検出

```
roslaunch vino_launch pipeline_people_oss.launch
```

入力画像から顔検出

```
roslaunch vino_launch pipeline_image_oss.launch
```

Realsenseで物体検出

```
roslaunch vino_launch pipeline_object_oss.launch
```

RealsenseCameraTopicで物体検出

```
roslaunch vino_launch pipeline_object_oss_topic.launch
```

RealsenseCameraTopicでオブジェクトセグメンテーション

```
roslaunch vino_launch pipeline_segmentation.launch
```

ビデオの入力からオブジェクトセグメンテーション

```
roslaunch vino_launch pipeline_segmentation.launch
```

普通のUSBカメラで個人の識別

```
roslaunch vino_launch pipeline_reidentification_oss.launch
```

その他

```
#run object detection service sample code input from Image
#Run image processing service:
roslaunch vino_launch image_object_server_oss.launch

#Run example application with an absolute path of an image on another console:
rosrun dynamic_vino_sample image_object_client ~/catkin_ws/src/ros_openvino_toolkit/data/images/car.png

#run face detection service sample code input from Image
#Run image processing service:
roslaunch vino_launch image_people_server_oss.launch

#Run example application with an absolute path of an image on another console:
rosrun dynamic_vino_sample image_people_client ~/catkin_ws/src/ros_openvino_toolkit/data/images/team.jpg
```

###サンプルをアレンジしたいひとへ
intelのgitにはrealsenseで顔検出をするとかNCS2を使って推論をするとかのサンプルがありません。なので、自分で作る必要があります。基本的にはyamlファイルやlaunchファイルをちょっといじるだけで動くようになります。
以下はRealsenseカメラとNCS2を使って顔検出をするという想定で説明をします。

**まずはyamlファイルを複製して、それをもとに編集します**
/home/<ユーザ名>/catkin_ws/src/ros_openvino_toolkit/vino_launch/paramにyamlファイルというものが入っています。
今回は顔検出をするのでpipeline_people_myriad.yamlをもとに編集をします。
以下のコマンドでファイルをコピーしてください。

```
sudo cp pipeline_people_oss.yaml 好きな名前.yaml
```

コピーできたらnanoやvimなどのテキストエディタを使って編集をします。
開いてもらうと中身は以下のようになっています(左の数字は見やすいように行数を表示しています)。

```
1  Pipelines:
2  - name: people
3    inputs: [StandardCamera]
4    infers:
5      - name: FaceDetection
6        model: /opt/openvino_toolkit/open_model_zoo/model_downloader/Transportation/object_detection/face/pruned_mobilenet_reduced_ssd_shared_weights/dldt/face-detection-adas-0001.xml
7        engine: MYRIAD
8       label: to/be/set/xxx.labels
9       batch: 1
10     - name: AgeGenderRecognition
11       model: /opt/openvino_toolkit/open_model_zoo/model_downloader/Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013.xml 
12       engine: MYRIAD
13       label: to/be/set/xxx.labels
14       batch: 16
15     - name: EmotionRecognition
16       model: /opt/openvino_toolkit/open_model_zoo/model_downloader/Retail/object_attributes/emotions_recognition/0003/dldt/emotions-recognition-retail-0003.xml
17       engine: MYRIAD
18       label: to/be/set/xxx.labels
19       batch: 16
20     - name: HeadPoseEstimation
21       model: /opt/openvino_toolkit/open_model_zoo/model_downloader/Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001.xml
22       engine: MYRIAD
23       label: to/be/set/xxx.labels
24       batch: 16
25   outputs: [ImageWindow, RosTopic,RViz]
26   confidence_threshold: 0.2
27   connects:
28     - left: StandardCamera
29       right: [FaceDetection]
30     - left: FaceDetection
31       right: [AgeGenderRecognition, EmotionRecognition, HeadPoseEstimation, ImageWindow, RosTopic, Rviz]
32     - left: AgeGenderRecognition
33       right: [ImageWindow, RosTopic,RViz]
34     - left: EmotionRecognition
35       right: [ImageWindow, RosTopic,RViz]
36     - left: HeadPoseEstimation
37       right: [ImageWindow, RosTopic,RViz]
38  
39  OpenvinoCommon:
```

まずは3行目のinputs: [StandardCamera]を**inputs: [RealSenseCameraTopic]**に変更してください。
次に28行目の- left: StandardCameraを**- left: RealSenseCameraTopic**に変更してください。
もしいらない機能があれば、該当する機能の-nameからbatchまでを消して、31行目以下の該当部分を削除してください。
yamlファイルの編集は以上です。

**次はlaunchファイルの編集に取り掛かります**
launchファイルで編集する部分は1箇所のみです。
先程コピーしたyamlファイルと同じ名前のlaunchファイルをさっきと同じ感じでコピーしてください。
そして、2行目の~/param/なんちゃら.yaml" />のなんちゃらの部分を、先程編集していたyamlファイル名に変更してください。

**最後に~/catkin_wsのディレクトリに移動してcatkin_makeをして、source devel/setup.bashを打ち込んでください。**
これで準備が整ったので、

```
roslaunch vino_launch 好きな名前.launch
```

で実行してみてください。

###おまけ
顔の向きの具体的な情報とかは

```
rostopic type /ros_openvino_toolkit/headposes_estimation
```

で確認することができます。
顔の向きをもとにロボットの制御をしたい方などは参考になるかもしれません。