デプスカメラRealSenseD435で "紫色のイカ" や "オレンジ色の玉ねぎ" を切り取ったり "金髪の人" を追っかけて距離を測る（１） with Ubuntu16.04

**MobileNet-SSD-RealSense**　[![GitHub stars](https://img.shields.io/github/stars/PINTO0309/MobileNet-SSD-RealSense.svg?style=social&label=Stars)](https://github.com/PINTO0309/MobileNet-SSD-RealSense)
#<font color="#08088A">◆ はじめに</font>
小遣いをチマチマ貯めてついに購入してしまった、**[Intel RealSense D435 (税抜き￥28,350)](https://www.switch-science.com/catalog/3633/)**
360°LiDARの **[RPLidar A1M8](https://www.robotshop.com/jp/ja/rplidar-a1m8-360-degree-laser-scanner-development-kit.html)** より ￥5,000 も高い。
スイッチサイエンスさんのWEBショップでは 「6/26時点 入荷時期未定」 となっていたが、楽天では普通に 「在庫有り」 の店舗が何店舗かあったため即購入。
４月に無謀にも **[自律走行ロボ作成の決意表明](https://qiita.com/PINTO/items/31df88d0b11189a5ba62)** をしてから、７月まで猛烈に突っ走ってきたので、ちょっとだけ他事に浮気してみる。

尊敬するブロガーさんから **マニアック認定** を頂戴していたようなので、今後も張り切ってニッチ路線を邁進していこうと思う。
ギャンブルジャンキーだったヤツが、こうもドップリとハードにハマってしまうものなのだろうか。。。
（最近はタバコとコーヒーを買う以外の小遣いを、世紀末のモヒカンよろしく 「ヒャッハー！！」 と躊躇なく全額ハードへブチ込んでいる。）

セッカチな人はこちらのリンクを踏むと、動きのある画像をすぐに見ることができます。
**[１．"イカ" と "玉ねぎ" の切り抜きサンプルGIF](https://qiita.com/PINTO/items/73b341a3661367a0dc61#-%E6%B7%B1%E5%BA%A6%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E8%83%8C%E6%99%AF%E9%80%8F%E9%81%8E%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%92%E5%91%B3%E8%A6%8B)**
**[２．深度測定サンプルGIF](https://qiita.com/PINTO/items/73b341a3661367a0dc61#-%E6%B7%B1%E5%BA%A6%E3%82%AB%E3%83%A1%E3%83%A9%E7%94%BB%E5%83%8F%E3%82%92ui%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E3%81%A0%E3%81%91%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%92%E5%91%B3%E8%A6%8B)**
**[３．"金髪の人" を追いかけて距離を測るサンプルGIF](https://qiita.com/PINTO/items/73b341a3661367a0dc61#-mobilenet-ssd%E7%89%A9%E4%BD%93%E3%81%BE%E3%81%A7%E3%81%AE%E8%B7%9D%E9%9B%A2%E6%B8%AC%E5%AE%9A%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%92%E5%91%B3%E8%A6%8B)**

#<font color="#08088A">◆ この試行を通して得たいこと</font>

- 画像解析のニーズがものすごく高いことを実感中
    - 基盤検査
    - 製品ラベルの検査
    - 予知保全
    - etc...
- どれほどの精度で深度が測定できるのかを検証
- 庶民感覚のローコストでできる範囲／できない範囲の見極め
- 過去人間系で行わざるを得なかった作業の効率化への寄与度見極め
- 小型ロボットへ搭載することへのメリット／デメリットの見極め
- **[IntelのGithubのサンプル](https://github.com/IntelRealSense/librealsense/tree/v2.12.0/examples)** を見ていたら・・・発想が変かもしれないけど、DNNの **[アノテーション半自動化](https://github.com/PINTO0309/YoloTrainDataGenerate)** で強力な補助ツールとして使えそうだぞ、コレ・・・
- やばい、試したいことが増える・・・１日２４時間では足りない・・・

#<font color="#08088A">◆ 参考にさせていただいた記事、謝辞</font>
**【shrimp_fさん】
[RealSense D435のROSへの導入でつまづいたところ Qiita](https://qiita.com/shrimp_f/items/eba5878a3a5f05f6be2d)**

#<font color="#08088A">◆ 環境</font>
1. Ubuntu 16.04 (検証環境)
2. Windows 10 Pro (Firmwareアップデート用)
3. RaspberryPi3 + Raspbian Stretch (最終導入環境・次回記事)
4. **[Intel RealSense D435](https://www.switch-science.com/catalog/3633/)**
5. **[Intel Movidius Neural Compute Stick](https://www.switch-science.com/catalog/3501/)** (次々回記事)
6. OpenCV3.x

#<font color="#08088A">◆ 作業に掛かる前の前提条件</font>
**[Raspbian Stretch+NCS(Neural Compute Stick)+YoloV2+Webカメラ＋ROSによるリアルタイム複数動体検知環境の構築](https://qiita.com/PINTO/items/b084fe3dc716c42e2867)** の記事を参考に、作業を実施済みであることを前提とする。

#<font color="#08088A">◆ Intel RealSense D435 の外観</font>
とにかく小さくて衝撃的だった。
三脚とType-CのUSBケーブルが付属する。
![9a66d841-060a-621b-2f70-25aa351ced40.png](https://qiita-image-store.s3.amazonaws.com/0/194769/fefd9f70-9c80-6893-b864-db4bc69c0867.png)

タバコの箱と比べるとご覧のサイズ感。
名刺やRaspberryPiとほぼ同じ大きさ。そして、すごく軽い。
![DSC_0076.png](https://qiita-image-store.s3.amazonaws.com/0/194769/5a9ac212-480c-9fcb-b8dc-42011b5d8ccb.png)

Intel Movidius NeuralComputeStick と比べるとこんな感じ。
![72e25e6a-6d59-88d1-9844-0aa1a6751070.png](https://qiita-image-store.s3.amazonaws.com/0/194769/e343d4ea-6d83-d5a4-e4d6-f0e068c6dc02.png)

作成中のロボットのLiDARの上に載せてみる。
横幅10cmのロボットに収まる感じなので相当小さい。
そういえば、**[RGB-Dカメラ用のSLAMアルゴリズム](http://wiki.ros.org/rgbdslam)** を一つだけ試していなかったことを今思い出した。
![1b1622ac-7c9d-7c19-85b4-3f21f21448ed.png](https://qiita-image-store.s3.amazonaws.com/0/194769/0cf6a5ba-c655-aa2d-0a1c-751cb67c3360.png)


#<font color="#08088A">◆ 端末側への要求スペック</font>

- USB 3.1 Gen 1 (USB 2.0でも動作可能)
- Ubuntu 16.xx / Windows 10
- 4GB RAM
- 電源 5V / 700mA

#<font color="#08088A">◆ 作業のおおまかな流れ</font>
本記事は下記のような流れで進める。

1. RealSense D435のキッティング
2. Ubuntu 16.04 PC環境への導入と味見
3. RaspberryPi3(Raspbian Stretch) への導入と味見 【次回記事】
4. RaspberryPi3(Raspbian Stretch) + RealSense D435 で MobileNet-SSD の試行 【次々回記事】

#<font color="#08088A">◆ RealSense D435のキッティング</font>
UbuntuPCからはFirmwareアップデートに成功しなかった。
Neural Compute Stickのときも同じだったが、マニュアル記載どおりの手順ではすんなりいかない。
Intelが提供するマニュアルは基本的に品質が低い。
##<font color="#0B3B39">● 【失敗】Ubuntu16.04PCによるFirmwareのアップデート</font>
下記URLに記載の手順に従い、Firmwareをアップデートする。
ハードウェアが動かなくなるのは嫌なのでメーカー推奨環境で実施する。
2018/06/30時点の最新FirmwareVerは「5.9.13」
**[【参考】 Intel® RealSense™ SDK 2.0 (Build 2.12.0) Github](https://github.com/IntelRealSense/librealsense/releases/tag/v2.12.0)**
**[【参考】 Device Firmware Update (DFU) for Linux](https://www.intel.com/content/dam/support/us/en/documents/emerging-technologies/intel-realsense-technology/Linux-RealSense-D400-DFU-Guide.pdf)**
**[【参考】 Downloads & Tools](https://realsense.intel.com/intel-realsense-downloads/#firmware)**

１．ターミナルを起動し、下記を実行する。

```shell:UbuntuPCで実施、リポジトリのリストへIntelサーバーの追加とDFUツールインストール
$ sudo sh -c 'echo "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo xenial main" | sudo tee /etc/apt/sources.list.d/realsense-public.list'
$ sudo apt-key adv --keyserver keys.gnupg.net --recv-key 6F3EFCDE
$ sudo apt update;sudo apt upgrade
$ sudo apt install intel-realsense-dfu*
$ cd ~;mkdir IntelRealSenseFirmware;cd IntelRealSenseFirmware

$ wget -O IntelRealSenseFirmware.zip https://downloadmirror.intel.com/27924/eng/Intel%C2%AE%20RealSense%E2%84%A2D400%20Series%20Signed%20Production%20Firmware%20v5_9_13.zip
又は
https://downloadcenter.intel.com/download/27924/Latest-Firmware-for-Intel-RealSense-D400-Product-Family?v=t　からブラウザ経由で最新版をダウンロード

$ unzip IntelRealSenseFirmware.zip
又は
$ unzip (ブラウザ経由でダウンロードしたファイル名)

$ rm IntelRealSenseFirmware.zip
```
![masked.png](https://qiita-image-store.s3.amazonaws.com/0/194769/eba190df-b1b9-b784-e58c-64943c77eb3c.png)

２．RealSense D435 を付属のType-CケーブルでPCと接続する。 
３．ターミナルで下記を実行し、Bus番号とDevice番号を記憶する。

```shell:USBのBus番号とDevice番号を確認
$ lsusb
```
![masked.png](https://qiita-image-store.s3.amazonaws.com/0/194769/56462421-1341-a17b-8289-617603a2432d.png)

４．ターミナルで下記を実行し、Firmwareをアップデートする。**`-b`** と **`-d`** は ３． で記憶した番号を指定する。 **`Bus → -b`**、**`Device → -d`**

```shell:Firmwareのアップデート
$ intel-realsense-dfu -b 003 -d 007 -f -i Signed_Image_UVC_5_9_13_0.bin
```

んで、見事にエラーになる。 って、おいっ！！
![masked.png](https://qiita-image-store.s3.amazonaws.com/0/194769/1d6687a4-566f-d489-6385-51ebe3cc7f20.png)

##<font color="#0B3B39">● 【成功】Windows10PCによるFirmwareのアップデート</font>
気を取り直してWindows10環境を使用してFirmwareをアップデートする。
１．ZIP ２種類 **[(1) Windows10用Firmwareアップデートツール](https://downloadmirror.intel.com/27514/eng/Intel%20RealSense%20D400%20Series%20DFU%20Tool%20for%20Windows.zip)**　**[(2) 最新ファームウェアbinファイル](https://downloadmirror.intel.com/27924/eng/Intel%C2%AE%20RealSense%E2%84%A2D400%20Series%20Signed%20Production%20Firmware%20v5_9_13.zip)** をダウンロードして解凍
２．Signed_Image_UVC_5_9_13_0.bin を intel-realsense-dfu.exe と同じフォルダへコピーする
３．RealSenseD435をUSBポートに接続
４．デバイスドライバのインストール完了を待つ
５．intel-realsense-dfu.exe を実行
６．「1」を入力してEnter入力し、画面の指示に従ってアップデート
７．ファームウェアのバージョン確認「2」
![7c5d60e3-4454-a39d-0a46-32bc359fc3aa.png](https://qiita-image-store.s3.amazonaws.com/0/194769/81b8b6df-f6e9-1dc0-13d0-e4c74d29de8f.png)

うまくいったようだ。
![d0ff4ac6-c16f-2638-0cc9-df9ec72932c1.png](https://qiita-image-store.s3.amazonaws.com/0/194769/d5693999-a953-a69e-e14c-c6a6b1c8d4b0.png)

#<font color="#08088A">◆ Ubuntu 16.04 PC環境への導入と味見</font>
まずはありきたりなUbuntu環境へ導入して動作を味見する。
以下、サンプルの動作確認は、**`Ubuntu16.04PC`** の **`USB2.0ポート`** にて実施。
**[【参考】 librealsense Linux Ubuntuへのインストール](https://github.com/IntelRealSense/librealsense/blob/master/doc/installation.md#video4linux-backend-preparation)**

##<font color="#0B3B39">● Ubuntuのudevルール更新</font>

```shell:udevルールの更新
$ cd /etc/udev/rules.d/
$ sudo wget https://raw.githubusercontent.com/IntelRealSense/librealsense/master/config/99-realsense-libusb.rules
$ sudo udevadm control --reload-rules && udevadm trigger
$ sudo reboot
```

##<font color="#0B3B39">● Ubuntu16.04のカーネル更新</font>
<font color="red">**★注意★　Ubuntu16.04の起動が明らかに遅くなる。 必要に迫られない限り実施しないのも一手。**</font>

```shell:Ubuntu16.04カーネルにパッチを充てる
$ cd ~
$ git clone https://github.com/IntelRealSense/librealsense.git
$ cd librealsense
$ sudo chmod 777 ./scripts/patch-realsense-ubuntu-lts.sh
$ ./scripts/patch-realsense-ubuntu-lts.sh
```

##<font color="#0B3B39">● Intel® RealSense™ SDK 2.0のインストール</font>
SDKをインストールする。

１．ターミナルを起動し、下記コマンドを実行する。

```shell:Ubuntu16.04PCへSDKのインストール
sudo apt install -y librealsense2-dkms librealsense2-utils librealsense2-dev librealsense2-dbg libglfw3-dev
```

##<font color="#0B3B39">● RealSenseの素の動作を味見</font>

```shell:デモを実行
$ realsense-viewer
```
![ezgif.com-optimize (19).gif](https://qiita-image-store.s3.amazonaws.com/0/194769/34037654-28ce-de52-0059-ec56c7c7d7f6.gif)

##<font color="#0B3B39">● RealSenseとOpenCVの連携サンプルをビルド</font>
**[【参考】 OpenCV Samples for Intel® RealSense™ cameras](https://github.com/IntelRealSense/librealsense/tree/v2.12.0/wrappers/opencv)**
**[【参考】 Sample Code for Intel® RealSense™ Python Wrapper](https://github.com/IntelRealSense/librealsense/tree/v2.12.0/wrappers/python/examples)**

あとから改造する気満々なので、ソースコードを落として手元でビルドしておく。
なお、ソースコードのビルド時には **cmake3.8.x以上** を要求されるため、一時的にcmakeのバージョンを上げる。
Ubuntu16.04のデフォルトのcmakeバージョンは「3.5.1」？

```shell:cmake3.11.xのビルドとインストール
$ cd ~
$ wget https://cmake.org/files/v3.11/cmake-3.11.4.tar.gz
$ tar -zxvf cmake-3.11.4.tar.gz;rm cmake-3.11.4.tar.gz
$ cd cmake-3.11.4
$ ./configure --prefix=/home/<username>/cmake-3.11.4
$ make
$ make install
$ export PATH=/home/<username>/cmake-3.11.4/bin:$PATH
$ source ~/.bashrc
$ cmake --version
```

```shell:深度を利用した背景透過サンプルを含むOpenCV系サンプル一式の一括ビルド
$ cd ~/librealsense/wrappers/opencv;mkdir build;cd build
$ cmake ..
$ nano ../latency-tool/CMakeLists.txt

target_link_libraries(rs-latency-tool ${DEPENDENCIES})
↓下記のように変更して保存
target_link_libraries(rs-latency-tool ${DEPENDENCIES} pthread)

$ make -j $(($(nproc) + 1))
$ sudo make install
```

##<font color="#0B3B39">● 深度を利用した背景透過サンプルを味見</font>

```shell:深度を利用した背景透過サンプルの味見
$ cd ~/librealsense/wrappers/opencv/build/grabcuts
$ rs-grabcuts
```
一定距離以外の部分が透過する。
かなり綺麗にエッジが抽出されている。
**<font color="red">エクセレント！！</font>**
**【YouTube動画】 https://youtu.be/ihJvynmClqk**
![ezgif.com-optimize (17).gif](https://qiita-image-store.s3.amazonaws.com/0/194769/256fa71e-be1b-3089-a0dd-9ccb1a80c242.gif)

消費電力
![DSC_0091-.png](https://qiita-image-store.s3.amazonaws.com/0/194769/9124759b-20b2-c25d-983c-c1576e06894a.png)

##<font color="#0B3B39">● 深度カメラ画像をUIに表示するだけのサンプルを味見</font>

```shell:深度カメラ画像をUIに表示するだけのサンプルの味見
$ cd ~/librealsense/wrappers/opencv/build/imshow
$ rs-imshow
```
**`赤：近い`** **`青：遠い`** **`黒：測定不能`** という感じでグラデーション表示される。
実際のレスポンスは下図の３倍。
**【YouTube動画】 https://youtu.be/mMImsKPb7qg**
![ezgif.com-optimize (16).gif](https://qiita-image-store.s3.amazonaws.com/0/194769/ada5411f-7ec1-b752-76b7-3ea0259fd4a2.gif)

消費電力
![DSC_0092-.png](https://qiita-image-store.s3.amazonaws.com/0/194769/e37ffd18-e4eb-91a9-b2a2-17bd2373acf4.png)

##<font color="#0B3B39">● MobileNet-SSD＋物体までの距離測定のサンプルを味見</font>

```shell:MobileNet-SSD＋対象物までの距離測定
$ cd ~/librealsense/wrappers/opencv/build/dnn
$ rs-dnn
```
**[こちらの記事(RaspbianStretch+MobileNet-SSD)](https://qiita.com/PINTO/items/b97b3334ed452cb555e2)** の動きに加え、 **対象物までの距離** も計算される。
実際のフレームレートは下図の５倍。
そうです、ごめんなさい。
別に金髪の人を探し出して追っている訳ではないのです。
ちなみに、悟空はちゃんと「人」でした。
**【YouTube動画】 https://youtu.be/StCPRJb5xlg**
![ezgif.com-optimize (18).gif](https://qiita-image-store.s3.amazonaws.com/0/194769/62b55ca5-f478-3e37-a401-e5fea7776a54.gif)

消費電力
![DSC_0090-.png](https://qiita-image-store.s3.amazonaws.com/0/194769/2a7a7fe2-987f-10e1-1a48-78356d7e3f00.png)

#<font color="#08088A">◆ 本日のまとめ</font>

- "深度" の測定精度、高からず低からず
- 物体表面の１cmほどの凹凸があれば見分けがつきそう
- 穴ボコになっている部分を埋めたり、エッジを平滑化するサンプルも公開されているため、かなり綺麗に被写体を切り抜けそう
- ハンパなUSB-Webカメラを買うぐらいなら、RealSenseを１台買ったほうがコストメリットが有りそう
- 大したことをしなければ、データシートに記載されている消費電力700mAを大きく下回る200mA前後で動作する
- USB2.0で普通に動くやん
- モーター駆動しない分、LiDARより低消費電力でエコ
- LiDARより圧倒的に軽い！！
- うまい棒ぐらいのサイズをイメージしていて完全にナメていた、想像以上に小さい
- 地図を作る用途では精度が思うように出なさそう
- 視野角は広めだが、360°探索には敵わない
- DNNのアノテーション地獄、ちょっとは楽できそうなほど綺麗にエッジが取れる
- Mask-RCNNのアノテーションや、Yolo、SSDのアノテーション作業でも結構使えそうな予感、あくまで予感
- 人間系の工数削減目的なら、 **`絶対買い`** と判断
- 素の解像度は普通
- 背景透過のサンプルとMobileNet-SSDをうまく組み合わせることができれば、特定の物体以外をまとめて透過できるのかもしれない

#<font color="#08088A">◆ おまけ</font>
こんなこともできるらしい。
実用イメージは沸かないけど、シンプルに面白い。
**[【YouTube】 Intel RealSense - Face tracking use](https://www.youtube.com/watch?v=wWETz4XU9dU)**
**[【YouTube】 Face Tracking with Intel Real Sense](https://www.youtube.com/watch?v=AJJBZuEnu_Y)**
**[【YouTube】 スイッチサイエンス RealSense D435 with 顔認識](https://www.youtube.com/watch?v=AwPI101Gtog)**
**[【Github】 RealSense SDK 2.0 demo with Dlib and OpenCV](https://github.com/PINTO0309/samplecodes/tree/master/IntelRealSense/rs-dlib-cv)**

下記リポジトリでスイッチサイエンスさんの実装をPythonで再現実装済みです。
**[MobileNet-SSD-RealSense - Github](https://github.com/PINTO0309/MobileNet-SSD-RealSense.git)**

#<font color="#08088A">◆ 次回予告</font>
RaspberryPi3 + Raspbian Stretch へ導入し、Intel Movidius Neural Compute Stick との組み合わせを試行してみようと思う。

#<font color="#08088A">◆ 次回記事</font>
[デプスカメラRealSenseD435で "紫色のイカ" や "オレンジ色の玉ねぎ" を切り取ったり "金髪の人" を追っかけて距離を測る（２） with RaspberryPi3(Raspbian Stretch)](https://qiita.com/PINTO/items/2ad10526f9b2e1c8cdf3)　へ続く