RaspberryPi と Movidius ではじめる OpenVINO 深層学習入門

# RaspberryPi と Movidius ではじめる OpenVINO 深層学習入門
OpenVINO をはじめて利用する方向けの、基礎的な説明です。
RaspberryPi と Movidius（後ほど説明）を使って、実際にOpenVINO 深層学習を試します。
RaspberryPiのセットアップや深層学習は、多少知識があることを前提としています。

## OpenVINO　概要
「OpenVINOツールキット」の略。
解説サイトはこちら[製品概要: OpenVINO™ ツールキット](https://www.intel.co.jp/content/www/jp/ja/internet-of-things/solution-briefs/openvino-toolkit-product-brief.html "製品概要: OpenVINO™ ツールキット")ですが、なんだか難しい気がするので簡単に解説すると。

- 様々なインテル製のアーキテクチャ（≒処理装置）上で、効率的にディープラーニングやAIを動作させることができる

- 無償のソフトウェア

- Tensorflow,Caffeなどで作成したモデルをモデル・オプティマイザーというツールで変換・効率化して使うため、作成済のモデルをエッジデバイスで活用できる／開発が容易

## Movidius　概要
![IMG_4304.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/7cbe3d24-6e43-a7c1-fa95-dad861bd1448.jpeg)

Movidius NCS（Neural Compute Stick）という低電力のエッジデバイスにAIを実装可能とするハードウェア。
RaspberryPiのUSBポートに接続すると、深層学習（推論）のプロトタイピングや検証が可能です。

RaspberryPiはARM製のプロセッサが搭載されているため、単体ではOpenVINOツールキットを使うことができません。
Movidius NCSに内蔵されているインテル製のプロセッサ上で、OpenVINOツールキットの推論処理が可能となるため、深層学習を比較的高速に実行することができるようになります。

追記：
今回利用したMovidius Neural Compute Stickは販売中止となったようです。（2019/11）
新しいモデルはNeural Compute Stick 2というものが出ています。

## 使ったハードウェア
- RaspberryPi４ Model B 4GB

- Neural Compute Stick

- RaspberryPiカメラモジュール

- キーボード、マウス、モニタ

- HDMIケーブル

- HDMIミニ変換アダプタ※

- microSDカード 32G以上推奨

- USB充電器　3A以上が必須

- USB Type-Cケーブル※

- microSDカード

- 無線(WiFi)もしくは有線でのインターネット接続

- OSインストール作業用PC（microSDカードへのOSインストール時のみ必要）

※100均で買えます

## RaspberryPiのOSインストール
今回はRaspbian Buster with desktop　をインストールしました。
![スクリーンショット 2020-01-07 15.00.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/edfc0f43-c1fe-2d9a-aed7-7bd18d1b5b33.png)

~~~~
pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
~~~

インストール後、初期設定とあわせてインターネットに接続可能な状態にしてください。

## OpenVINOツールキットのインストール
マニュアル：[Install OpenVINO™ toolkit for Raspbian* OS - OpenVINO Toolkit](https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_raspbian.html "Install OpenVINO™ toolkit for Raspbian* OS - OpenVINO Toolkit")

以降、全てRaspberryPiのLXTerminalから行います。
Movidius NCSはまだ挿し込まないでください、設定が完了してからUSBポートに挿す必要があります。
![IMG_4305.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/d3eeeac6-2a59-730b-50ea-026b3fea7b86.jpeg)

### OpenVINOツールキットをダウンロード
OpenVINOのRaspberryPi用パッケージを[Intel® Open Source Technology Center](https://download.01.org/opencv/2019/openvinotoolkit/ "Intel® Open Source Technology Center") からダウンロードします。
ファイル名が　l_openvino_toolkit_runtime_raspbian_p_＜version＞.tgz のものを選んでください。
2020/01/07時点の最新はR3、[l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz](https://download.01.org/opencv/2019/openvinotoolkit/R3/l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz "l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz") です。

~~~
pi@raspberrypi:~ $ cd ~/Downloads
pi@raspberrypi:~/Downloads $ wget https://download.01.org/opencv/2019/openvinotoolkit/R3/l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz
~~~

### OpenVINOツールキットのインストール先となるディレクトリを作成

~~~
pi@raspberrypi:~/Downloads $ sudo mkdir -p /opt/intel/openvino
~~~

### OpenVINOツールキットのインストール（解凍）

~~~
pi@raspberrypi:~/Downloads $ sudo tar -xf  l_openvino_toolkit_runtime_raspbian_p_*.tgz  --strip 1 -C /opt/intel/openvino
~~~

### CMakeのインストール
必要になるソフトウェア CMake（ビルドツール）をインストールします。

~~~
pi@raspberrypi:~/Downloads $ sudo apt install cmake
~~~

この表示で「Y」を入力します
~~~
以下のパッケージが新たにインストールされます:
  cmake cmake-data libjsoncpp1 librhash0 libuv1
アップグレード: 0 個、新規インストール: 5 個、削除: 0 個、保留: 0 個。
4,330 kB のアーカイブを取得する必要があります。
この操作後に追加で 21.8 MB のディスク容量が消費されます。
続行しますか? [Y/n] Y
~~~

### 環境変数を設定

~~~
pi@raspberrypi:~/Downloads $ echo "source /opt/intel/openvino/bin/setupvars.sh" >> ~/.bashrc
~~~

環境変数の変更後テスト：
新しいLXTerminalを開き、以下の表示が出ることを確認してください。

~~~
[setupvars.sh] OpenVINO environment initialized
~~~

以降の作業はこの表示が出ているLXTerminalで行います。

### USB Rulesの追加
Movidius NCSをUSBポートで認識させるための設定追加を行います。

ログイン中のユーザをグループ users に追加します。

~~~
pi@raspberrypi:~ $ sudo usermod -a -G users "$(whoami)"
~~~

Movidius NCSをUSBポートで動作させるためのUSB rulesをインストールします。
"Udev rules have been successfully installed."と表示されることを確認してください。

~~~
pi@raspberrypi:~ $ sh /opt/intel/openvino/install_dependencies/install_NCS_udev_rules.sh
Updating udev rules...
Udev rules have been successfully installed.
~~~

Movidius NCSを挿し込みます。
![IMG_4306.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/172ba57e-0d6b-577f-cbf7-c40534d254d1.jpeg)

コマンド lsusb でIntel Myriad VPUが認識されていることを確認してください。

~~~
pi@raspberrypi:~ $ lsusb
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 1997:2433  
Bus 001 Device 006: ID 03e7:2150 Intel Myriad VPU [Movidius Neural Compute Stick]
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
~~~

ここで、リブートしておいてください。

~~~
pi@raspberrypi:~ $ sudo reboot
~~~

## Object Detection(物体検出) サンプルでの動作試験

###例）OpenVINO用の作業ディレクトリをホームディレクトリ配下に"OpenVINO"という名前で作成します。
ディレクトリ"face-detection"をその配下に作成します。

~~~
pi@raspberrypi:~ $ mkdir ~/OpenVINO && cd ~/OpenVINO
pi@raspberrypi:~/OpenVINO $ mkdir face-detection && cd face-detection
pi@raspberrypi:~/OpenVINO/face-detection $ 
~~~

### Object Detection(物体検出) サンプルをビルドします

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=armv7-a" /opt/intel/openvino/deployment_tools/inference_engine/samples
~~~

最後に以下が表示され、ビルドファイルが作成できたことを確認します。

~~~
-- Build files have been written to: /home/pi/OpenVINO/face-detection
~~~

make します。
少し時間がかかります。

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ make -j2 object_detection_sample_ssd
~~~

### トレーニング済のモデルをダウンロードします

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ wget --no-check-certificate https://download.01.org/opencv/2019/open_model_zoo/R1/models_bin/face-detection-adas-0001/FP16/face-detection-adas-0001.bin
~~~

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ wget --no-check-certificate https://download.01.org/opencv/2019/open_model_zoo/R1/models_bin/face-detection-adas-0001/FP16/face-detection-adas-0001.xml
~~~

### 画像によるテスト
顔認識を試すために、人の顔が写った画像データを、bitmap（拡張子 .bmp）形式で用意します。

テストデータの準備　Macからsftpでアップロードする例：
PC(mac）からDownloadsフォルダ内のファイルsample_photo.bmpをRaspberryPiへアップロード

~~~
(base) MasamacAir:~ taguchi$ sftp pi@<RaspberryPi IPアドレス>
pi@<RaspberryPi IPアドレス>'s password: 
Connected to pi@<RaspberryPi IPアドレス>.
sftp> ls 
Desktop    Documents  Downloads  MagPi      Music      OpenVINO   Pictures   
Public     Templates  Videos     
sftp> cd OpenVINO
sftp> ls
face-detection  
sftp> cd face-detection 
sftp> lcd Downloads
sftp> lls
sample_photo.bmp
sftp> put sample_photo.bmp
Uploading sample_photo.bmp to /home/pi/OpenVINO/face-detection/sample_photo.bmp
sample_photo.bmp                              100% 1068KB   3.5MB/s   00:00   
sftp> quit
~~~

## テストします

~~~
pi@raspberrypi:~/OpenVINO $ cd /home/pi/OpenVINO/face-detection
pi@raspberrypi:~/OpenVINO/face-detection $ pwd
/home/pi/OpenVINO/face-detection
pi@raspberrypi:~/OpenVINO/face-detection $ ./armv7l/Release/object_detection_sample_ssd -m face-detection-adas-0001.xml -d MYRIAD -i /home/pi/OpenVINO/face-detection/sample_photo.bmp
~~~

### Jpegファイルをbitmapファイルに変換して試したい場合：
アプリケーション　imagemagick　をインストールして利用してみてください。

~~~
pi@raspberrypi:~$ sudo apt-get install imagemagick
~~~

sample_photo.jpgをsample_photo.bmpに変換する
"bmp3:"オプションが必要だと思います

~~~
pi@raspberrypi:~$ convert sample_photo.jpg bmp3:sample_photo.bmp
~~~

### 実行結果の例：
試験用に別途用意した集合写真 sample_photo.bmp の顔を認識できるか試す

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ ./armv7l/Release/object_detection_sample_ssd -m face-detection-adas-0001.xml -d MYRIAD -i /home/pi/OpenVINO/face-detection/sample_photo.bmp
[ INFO ] InferenceEngine: 
	API version ............ 2.1
	Build .................. custom_releases/2019/R3_cb6cad9663aea3d282e0e8b3e0bf359df665d5d0
	Description ....... API
Parsing input parameters
[ INFO ] Files were added: 1
[ INFO ]     /home/pi/OpenVINO/face-detection/sample_photo.bmp
[ INFO ] Loading Inference Engine
[ INFO ] Device info: 
	MYRIAD
	myriadPlugin version ......... 2.1
	Build ........... 30677
[ INFO ] Loading network files:
	face-detection-adas-0001.xml
	face-detection-adas-0001.bin
[ INFO ] Preparing input blobs
[ INFO ] Batch size is 1
[ INFO ] Preparing output blobs
[ INFO ] Loading model to the device
[ INFO ] Create infer request
[ WARNING ] Image is resized from (640, 427) to (672, 384)
[ INFO ] Batch size is 1
[ INFO ] Start inference
[ INFO ] Processing output blobs
[0,1] element, prob = 1    (280,231)-(347,315) batch id : 0 WILL BE PRINTED!
[1,1] element, prob = 0.999512    (189,268)-(255,360) batch id : 0 WILL BE PRINTED!
[2,1] element, prob = 0.998047    (382,202)-(462,294) batch id : 0 WILL BE PRINTED!
[3,1] element, prob = 0.99707    (81,216)-(160,313) batch id : 0 WILL BE PRINTED!
[4,1] element, prob = 0.995605    (377,87)-(473,185) batch id : 0 WILL BE PRINTED!
[5,1] element, prob = 0.993652    (236,141)-(304,215) batch id : 0 WILL BE PRINTED!
[6,1] element, prob = 0.157227    (594,9)-(617,44) batch id : 0
[7,1] element, prob = 0.0776367    (255,348)-(283,379) batch id : 0
[8,1] element, prob = 0.0463867    (566,5)-(602,39) batch id : 0
[9,1] element, prob = 0.0419922    (566,0)-(597,23) batch id : 0
[10,1] element, prob = 0.0419922    (534,0)-(571,23) batch id : 0
[11,1] element, prob = 0.0341797    (592,1)-(613,23) batch id : 0
[12,1] element, prob = 0.0341797    (147,262)-(200,322) batch id : 0
[13,1] element, prob = 0.0341797    (593,46)-(647,128) batch id : 0
[14,1] element, prob = 0.0322266    (531,3)-(582,43) batch id : 0
[15,1] element, prob = 0.0322266    (250,334)-(285,369) batch id : 0
[16,1] element, prob = 0.0322266    (589,-12)-(646,56) batch id : 0
[17,1] element, prob = 0.03125    (241,354)-(286,407) batch id : 0
[18,1] element, prob = 0.03125    (593,10)-(646,86) batch id : 0
[19,1] element, prob = 0.03125    (589,83)-(643,165) batch id : 0
[20,1] element, prob = 0.0302734    (618,-4)-(645,29) batch id : 0
[21,1] element, prob = 0.0302734    (519,133)-(555,164) batch id : 0
[22,1] element, prob = 0.0302734    (510,6)-(615,98) batch id : 0
[23,1] element, prob = 0.0302734    (556,10)-(626,82) batch id : 0
[24,1] element, prob = 0.0302734    (319,160)-(382,233) batch id : 0
[25,1] element, prob = 0.0292969    (548,-2)-(596,33) batch id : 0
[26,1] element, prob = 0.0292969    (526,55)-(609,118) batch id : 0
[27,1] element, prob = 0.0292969    (492,97)-(580,153) batch id : 0
[28,1] element, prob = 0.0292969    (503,122)-(565,187) batch id : 0
[29,1] element, prob = 0.0283203    (560,49)-(624,134) batch id : 0
[30,1] element, prob = 0.0268555    (582,-1)-(621,40) batch id : 0
[31,1] element, prob = 0.0268555    (531,84)-(604,160) batch id : 0
[32,1] element, prob = 0.0268555    (261,162)-(344,222) batch id : 0
[33,1] element, prob = 0.0258789    (575,14)-(595,36) batch id : 0
[34,1] element, prob = 0.0258789    (600,10)-(625,58) batch id : 0
[35,1] element, prob = 0.0249023    (605,0)-(623,22) batch id : 0
[36,1] element, prob = 0.0249023    (551,19)-(588,59) batch id : 0
[37,1] element, prob = 0.0249023    (569,19)-(604,62) batch id : 0
[38,1] element, prob = 0.0249023    (619,15)-(643,66) batch id : 0
[39,1] element, prob = 0.0239258    (499,187)-(517,212) batch id : 0
[40,1] element, prob = 0.0239258    (519,-5)-(569,31) batch id : 0
[41,1] element, prob = 0.0239258    (535,23)-(573,61) batch id : 0
[42,1] element, prob = 0.0239258    (446,164)-(485,204) batch id : 0
[43,1] element, prob = 0.0239258    (246,308)-(279,353) batch id : 0
[44,1] element, prob = 0.0229492    (498,0)-(547,24) batch id : 0
[45,1] element, prob = 0.0229492    (238,345)-(277,381) batch id : 0
[46,1] element, prob = 0.0229492    (528,119)-(595,189) batch id : 0
[47,1] element, prob = 0.0229492    (496,165)-(568,226) batch id : 0
[48,1] element, prob = 0.0229492    (236,149)-(498,365) batch id : 0
[49,1] element, prob = 0.0219727    (544,15)-(565,36) batch id : 0
[50,1] element, prob = 0.0219727    (604,13)-(622,42) batch id : 0
[51,1] element, prob = 0.0219727    (529,125)-(550,149) batch id : 0
[52,1] element, prob = 0.0219727    (541,188)-(566,221) batch id : 0
[53,1] element, prob = 0.0219727    (256,338)-(278,359) batch id : 0
[54,1] element, prob = 0.0219727    (613,8)-(645,44) batch id : 0
[55,1] element, prob = 0.0219727    (458,148)-(490,196) batch id : 0
[56,1] element, prob = 0.0219727    (521,141)-(556,182) batch id : 0
[57,1] element, prob = 0.0219727    (170,262)-(225,330) batch id : 0
[58,1] element, prob = 0.0219727    (210,293)-(267,359) batch id : 0
[59,1] element, prob = 0.0219727    (488,30)-(587,136) batch id : 0
[60,1] element, prob = 0.0219727    (557,119)-(629,186) batch id : 0
[61,1] element, prob = 0.0219727    (591,116)-(643,192) batch id : 0
[62,1] element, prob = 0.0209961    (622,0)-(640,21) batch id : 0
[63,1] element, prob = 0.0209961    (560,9)-(587,35) batch id : 0
[64,1] element, prob = 0.0209961    (560,33)-(580,53) batch id : 0
[65,1] element, prob = 0.0209961    (577,32)-(596,54) batch id : 0
[66,1] element, prob = 0.0209961    (593,26)-(611,52) batch id : 0
[67,1] element, prob = 0.0209961    (591,43)-(615,77) batch id : 0
[68,1] element, prob = 0.0209961    (573,63)-(599,98) batch id : 0
[69,1] element, prob = 0.0209961    (541,28)-(596,91) batch id : 0
[70,1] element, prob = 0.0209961    (535,54)-(570,94) batch id : 0
[71,1] element, prob = 0.0209961    (456,178)-(500,234) batch id : 0
[72,1] element, prob = 0.0209961    (246,287)-(280,329) batch id : 0
[73,1] element, prob = 0.0209961    (495,-3)-(576,52) batch id : 0
[74,1] element, prob = 0.0209961    (455,36)-(550,142) batch id : 0
[ INFO ] Image out_0.bmp created!
[ INFO ] Execution successful

[ INFO ] This sample is an API example, for any performance measurements please use the dedicated benchmark_app tool
~~~

### エラー対処方法　例：

~~~
ncDeviceOpen:859 Device doesn't appear after boot
~~~

sh /opt/intel/openvino/install_dependencies/install_NCS_udev_rules.sh　を再度実施してください。

### 出力ファイル"out_0.bmp"ができていることを確認します。

~~~
pi@raspberrypi:~/OpenVINO/face-detection $ ls
CMakeCache.txt                hello_nv12_input_classification
CMakeFiles                    hello_query_device
Makefile                      hello_reshape_ssd
armv7l                        ie_cpu_extension
benchmark_app                 object_detection_sample_ssd
classification_sample_async   out_0.bmp
cmake_install.cmake           sample_photo.bmp
common                        speech_sample
face-detection-adas-0001.bin  style_transfer_sample
face-detection-adas-0001.xml  targets_developer.cmake
hello_classification          thirdparty
~~~

## 処理前のビットマップ画像（sample_photo.bmp）：
Qiitaで表示するために、Jpeg形式に変換しています
![sample_photo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/bd4615da-3055-5f61-b9e7-b0312b0f819e.jpeg)

## 処理後のビットマップ画像（out_0.bmp）：
Qiitaで表示するために、Jpeg形式に変換しています
![out_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/0bd6d20a-a5f8-a02f-0b8f-52a3c34dcd4a.jpeg)

## OpenVINOの続編、公開されている他のサンプルを試す方法については、以下の記事をご参照下さい。
[RaspberryPi と Movidius ではじめる OpenVINO 深層学習入門2](https://qiita.com/tagucchan/items/e872797b35ef12e37e3c "RaspberryPi と Movidius ではじめる OpenVINO 深層学習入門2")