JetsonNano を用いた リアルタイム 物体認識 チュートリアル

# 1. はじめに
2019年7月現在での「Jetson Nano を用いた リアルタイム 物体認識」について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

---
# 2. 参考文献
- [ラズパイマガジン 2019年8月号](https://amzn.to/2K77COv)

---
# 3. このスライドを見てできること
- JetsonNano を用いたリアルタイム物体認識が動かせるようになる。

---
# 4. 前提条件
- ハードウェア：[JetsonNano 開発者キット](https://amzn.to/2xY1fXU)
- カメラ：[ラズベリーパイ カメラモジュールV2](https://amzn.to/2y0lQuU)
- 電源：[ラズパイ用5V 3.0A](https://amzn.to/30MGriA)
- クライアントPC：Windows10
- sshソフト：[TeraTerm](https://ja.osdn.net/projects/ttssh2/)
- VNCクライアント：[VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/)
- 無線マウス（[Logicool M280](https://amzn.to/30KlggT)）
- 有線キーボード（[ELECOM TK-FCM077PBK](https://amzn.to/30S2DYJ)）
- HDMIケーブル
- LANケーブル

---

# 5. JetsonNanoのセットアップ
- [小型 AI コンピュータ NVIDIA Jetson Nano 開発者キットのセットアップ](https://qiita.com/tsutof/items/66e68c75b462c4faf1cb)を参考に、JetsonNanoをセットアップする。
- HDMIケーブルを用いて外部ディスプレイへの出力、キーボードおよびマウスが問題なく使えることを確認すること。
- セットアップ時に作成するアカウントのユーザ名およびパスワードは忘れないよう控えておくこと。
- SDカード容量はケチらず[32GB](https://amzn.to/30PLgrt)、[64GB](https://amzn.to/2O9EpYq)、[128GB](https://amzn.to/2JGAb64)くらいのものを使い、余裕をもたせるとよいかもです。（micro SDカードは、UHS-I U3対応クラスから選ぶと書き込み速度が速いと思うよ。）

---
# 6. ラズパイカメラモジュールV2の接続
- JetsonNanoをシャットダウンした状態で、JetsonNanoにラズパイカメラモジュールV2を接続する。
- 接続方法は通常のラズパイと同じです。
![IMG_20190714_132103.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/40ce61fe-3815-d901-3b39-104a65d617e5.jpeg)

---
# 7. IPアドレスの確認
- ssh接続やVNCクライアントを使いたいため、ifconfigコマンドを用いてJetsonNanoのIPアドレスを確認する。

```shell:コマンドプロンプト
# IPアドレスの確認
$ ifconfig
eth0: flags=
        inet 192.168.100.183
```

---
# 6. TeraTermでssh接続
- TeraTermクライアントを用いて、JetsonNanoにssh接続する。
- 事前にJetsonNanoのIPアドレス、ユーザ名、パスワードをひかえておくこと。

![TeraTerm2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/7fb0ab67-877a-4ec9-5f35-c7acae289d20.png)

---
# 7. VNCの有効化
- デフォルト状態ではVNC接続が有効でないため、[Jetson Nanoにリモートデスクトップ(VNC)環境を用意する](https://qiita.com/iwatake2222/items/a3bd8d0527dec431ef0f)を参考に、VNCを有効化する。
- 無事VNC接続が成功したら以下のような接続画面となる。
- カメラモジュールを用いたプログラムの場合、出力先がディスプレイであるためTeraTermなどのssh接続では正常動作しない場合がある。そのためVNCクライアント等を用いて、GUIごとリモート接続しGUI内のターミナル端末で操作することをおすすめする。

![ログイン後.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/3698c202-4b07-1420-53bb-98c47b45920c.png)

---
# 8. swapの設定
- JetsonNanoには物理メモリが4GB搭載されているが、AI処理を実行する際のメモリ不足を解消するため、以下のコマンドを事項しswapを設定する。
- swapサイズは物理メモリの2倍にあたる8GBとしました。（SDカードサイズの空き容量内で設定すること。swap推奨サイズは4GBまたは6GBらしいです。）

```shell:コマンドプロンプト
# swapfileの作成
$ sudo dd if=/dev/zero of=/var/swapfile bs=1024 count=$((8*1024*1024))

# root以外からのアクセスを禁止
$ sudo chmod 600 /var/swapfile

# swapの作成
$ sudo mkswap /var/swapfile

# swapの有効化
$ sudo swapon /var/swapfile

# swapサイズの確認
$ free
```

---
# 9. swapの再起動後有効化
- JetsonNano再起動後もswapが有効になるよう設定する。

```shell:コマンドプロンプト
# /etc/fstabの編集
$ sudo vi /etc/fstab
# ファイル末尾に1行追加
/var/swapfile    nano    swap    swap    0    0
```

![fstabの設定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/5f66460c-e75d-1520-453b-df78b94cb800.png)

---
# 10. cmakeのインストール
- デモプログラムをビルドするためのcmakeをインストールする。

```shell:コマンドプロンプト
# ホームディレクトリに移動
$ cd

# cmakeのインストール
# 途中でアーカイブ取得の確認が表示されたら「Y」キーを押下する。
$ sudo apt install cmake
```

![cmakeのインストール.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/8e8a14ea-07f8-340d-8914-00abd00b32f0.png)

---
# 11. NVIDIA jetson-inferenceデモプログラムのビルド
- リアルタイム物体認識で用いるNVIDIA jetson-inferenceデモプログラムをビルドする。

```shell:コマンドプロンプト
# ホームディレクトリに移動
$ cd

# jetson-inferenceのソース取得
$ git clone --recursive https://github.com/dusty-nv/jetson-inference.git

# ビルド
$ cd jetson-inference
$ madir build
$ cd build
$ cmake ../

# cmake中に「了解」画面がでてきたら「Enter」キー押下で了解する。
# cmakeが終わったら、makeする（両方とも時間かかるよ）
$ make
```

![cmake了解.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/84c2bb47-5038-b5c7-8436-ef29da1581be.png)

![cmake了解2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/fdb57977-e6b2-44e2-8401-65dfaddb92bc.png)

---

# 12. ビルドモジュールの確認
- ビルドが成功したことを確認する。

```shell:コマンドプロンプト
# ディレクトリ移動
$ cd ~/jetson-inference/build/aarch64/bin/

# ビルドモジュールの確認
$ ls
```

![binの中身.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/fbb62ca2-79d0-a163-1785-93623e021f74.png)

---

# 13. GoogleNetを用いた物体認識の実行
- imagenet-cameraコマンドにgooglenet引数を指定して物体認識プログラムを実行する。
- 初回実行時は起動までに5分から10分くらいかかります。
- JetsonNanoに小型扇風機などを向けて冷やしてあげましょう。

```shell:コマンドプロンプト
# ディレクトリ移動
$ cd ~/jetson-inference/build/aarch64/bin/

# 物体認識プログラムの実行
$ ./imagenet-camera googlenet
```

---

# 14. GoogleNetを用いた物体認識の結果確認
- 数分待つとJetsonNanoのGUI上にカメラ映像が表示されます。
- すかさず「マウス」や「キーボード」など近くにあるものをカメラに映しましょう。
- カメラ映像の右上に「物体認識率」および「物体推測名」が表示されれば成功です。

- 認識結果：84.28% mouse, computer mouse
![mouse.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/1338a72c-681e-d784-e94f-eb10dcdae59a.png)

- 認識結果：73.03% computer keyboard, keypad
![keyboard.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/c607e359-78f8-fa75-d1ad-ae7e4ae5d280.png)

---
# 15. 補足その1：参考文献について
- 参考文献[ラズパイマガジン 2019年8月号](https://amzn.to/2K77COv) には 20W電源動作設定、GPIOの使い方、USBカメラ利用方法、detectnet-cameraを用いた「顔認識」、「人認識」、「瓶・カンの認識」、「犬の認識」についての記載がもりだくさんでした。ぜひ書籍をお買い求めのうえお試しください。
- 私は「瓶・カンの認識」にチャレンジしましたが、うまく矩形表示させることができませんでした。うまくいかなかった要因は検証に用いた「瓶・カン」の種類がよくなかったのかもしれません。

---
# 16. 補足その2：無線LANについて
- JetsonNanoには標準では無線LANカードが搭載されていません。
- 以下のM.2無線カードおよびアンテナはJetsonNanoで動作することを確認しましたので、購入をご検討されている方はご参考ください。
- M.2無線カードを利用した感想としては、無線機能は十分なのですがアンテナ線やアンテナが邪魔のように思います。電波状況に問題がないようならUSBドングルタイプの無線の方がよいのかもしれません。
- あると便利：[M.2 無線LANカード](https://amzn.to/32FVFHV)
- あると便利：[無線LANアンテナ](https://amzn.to/30JTC3F)

![IMG_20190715_225758.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/03a55d39-5217-7e13-ea40-4f067cc09e37.jpeg)

---
# 17. 補足その3：ホスト名接続について
- DHCP環境下でIPアドレス接続していると、IPアドレスが固定でないためIPアドレスが変わったときに接続できなくなります。
- [ホスト名をhostname.localでJetsonにアクセス](https://qiita.com/karaage0703/items/b14c249aa33112669ee4#%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E3%82%92hostnamelocal%E3%81%A7jetson%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9)の記事を参考に、JetsonNanoのホスト名を有効にするとssh接続やVNCクライアント接続の時に楽（ ホスト名.local で接続可能）ができます。
- Windowsをご利用の方でそもそもホスト名の名前解決ができないよって方は、[Bonjour Print Services (Windows)](https://support.apple.com/kb/dl999?locale=ja_JP)をインストールすることでホスト名の名前解決が可能になるかと思います。

```shell:コマンドプロンプト
# ホスト名の確認
$ echo $HOSTNAME
nano-desktop

# ホスト名を有効
$ sudo apt-get install avahi-daemon
```
![TeraTerm.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/c8fc2f61-2bbf-70da-d14d-4cbf92028b24.png)

![NVC.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/97a85102-b8f1-bdc8-4cc3-39a5b37f2fbb.png)

---
# 18. 補足その4：VS Code開発
- JetsonNanoでもVS Codeエディタを使いたい場合、素直にJetsonNano自体にイントールする方法もいいですが、クライアントOS（Windows／MacOS X）側にVS CodeエディタをインストールしVS Codeの拡張機能「SSH FS」を用いてJetsonNanoにVS Code上からssh接続する方法があります。この方法はとてもカッコいいのでぜひ試してみてください。
- 利点としては、TeraTerm等のssh接続ではJetsonNano内のAI処理結果の出力画像ファイルを直接見ることはできませんが、この「SSH FS」ならVS Code上から画像ファイルを参照することができてクールです。（ただし今回のようなカメラ映像のリアルタイム確認には向いていないかもしれません。）
- 参照：[Visual Studio CodeでSSHごしにファイルを編集する](https://qiita.com/informationsea/items/5c9f05c81a41fb885460)

- みんな大好きレナ・ソーダバーグ（JetsonNano上の画像ファイル）
![レナ・ソーダバーグ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/83930ec0-d30a-def7-ee0e-9326f1682b7e.png)

- SSH FSの設定画面
![SSH_FS.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/c60565b3-5c36-e218-c26b-684c45236035.png)


---
# 19. 補足その5：exFATを認識させる
- USBメモリを外部ストレージとして扱いたいのでexFATフォーマットを扱えるようにする。
- USBメモリはWindowsなどであらかじめexFAT形式でフォーマットしておく。その際、ボリューム名をつけておくとJetsonNano上でもその名称で認識する。

```shell:コマンドプロンプト
# exFAT関連をインストールしexFATを有効化
$ sudo apt-get install exfat-fuse exfat-utils

# USBスロットにexFATフォーマットのUSBメモリを刺す
# USBメモリのディレクトリに移動（nanoはユーザ名、SanDisk64GBはボリューム名なので適宜読み替えてください。）
$ cd /media/nano/SanDisk64GB
$ ls
```

---
# 20. 補足その6：ファンをつける
- ちなみに[ファン](https://amzn.to/30Q319N)も購入しましたが、こちらは[コマンドラインから設定](https://qiita.com/karaage0703/items/b14c249aa33112669ee4#fan%E5%88%B6%E5%BE%A1%E3%81%AE%E6%96%B9%E6%B3%95)をおこなわないと付けただけでは動作しないようです。このコマンドはJetsonNanoを再起動すると設定クリアされるみたいです。どこの設定をいじれば常にファン回転100%にできるかご存じの方がいらっしゃいましたら教えてください。

```shell:コマンドプロンプト
# ファンを100%（255）で回転するよう設定
# ファンを動作させるには20W動作モードで動作させないと駄目みたいです。
$ sudo sh -c 'echo 255 > /sys/devices/pwm-fan/target_pwm'
```

- 私の購入したファンは[DC12Vファン](https://amzn.to/30Q319N)のようです。本来は[DC5Vファン](https://amzn.to/30OrtbP)を取り付けるべきのようですが、高すぎて買い直す気がおきませんでした。いちようDC12Vファンでもゆっくり回転しているので使えなくはないです。
- ファンを使う場合は、20Wモードで動作させる必要があり別途[5V4.0Aアダプタ](https://amzn.to/2Obefo2)と[ジャンパーピン](https://amzn.to/30MJwPG)を用意する必要があります。
- ファン取り付けにはネジが別途必要のようですが、どのネジを購入すればよいかご存じの方がいらっしゃいましたら教えてください。

![IMG_20190715_223438.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/8c7ee2da-dc11-723f-12d0-57d28e2c16ab.jpeg)

---
# 21. 補足その7：日本語入力をできるようにする
- Jetson兄弟（TX1、TX2）などでは、日本語入力対応することでAI系の処理が正常動作しないこともあるらしく、日本語入力は有効にしていない方の方が多いと聞きますが、やっぱり日本語入力できた方が便利かなと思い日本語入力対応（Mozc）してみました。
- [Ubuntu 18.04 LTSを日本語環境に変更する方法](https://muroiwataru.net/entry/ubuntu-jp)や、古いUbuntu 16.04などの日本語入力対応の記事などを参考にするとよいと思います。
- また、漢字変換方法をMac風に変えたい方は、[Ubuntu 18.04のキー設定（Capsと変換・無変換キー）](https://blog.sakaki333.com/blog/view/11)などを参考にするとよいかと思います。
- 私の環境で日本語入力での不具合事象がありましたら、改めてこちらに追記したいと思います。

---
# 22. 補足その8：ケースについて
- 「まま、はだかのままじゃいゃー。」ってことで、[ケース](https://amzn.to/30MN9oQ)＆[薄型ファン](https://amzn.to/30FJdWG)をつけてみました。
- ファンについてはまたしても12Vファンでした。5Vファンを見つけた方はそっちをゲットすることをおすすめします。
- 付属のファンねじではネジ穴にあわず、針金でとめています。
- 小型の40mmファンではなく、ケース自体が大型ファンになってるJetsonNanoケースが登場したら人気でるような気がします。

![IMG_20190717_204540.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/6efc5c92-df77-1319-0a70-e4773bb4edca.jpeg)

---
# 23. 補足その9：GPU Activity Monitor（gpuGraph.py）
- GPUの使用率を可視化したいぜ！と思った方はgpuGraphをセットアップしましょう。
- gpuGraphのセットアップ手順が見当たらず、しかもしっかりはまった（pip3がないよ、numpyがないよ、matplotlibがないよ、ft2build.hがありません等）ので、実行までのセットアップ手順をお伝えします。

```shell:コマンドプロンプト
# カレントディレクトリに移動
$ cd

# gpuGraphの取得
$ git clone https://github.com/JetsonHacksNano/gpuGraph

# ディレクトリ移動
$ cd gpuGraph

# pip3のインストール
$ sudo apt install python3-pip

# numpyのインストール
$ sudo pip3 install numpy

# matplotlibの必要モジュールをインストール
# 「ft2build.h: そのようなファイルやディレクトリはありません」対策
$ sudo apt-get install libfreetype6 libfreetype6-dev

# matplotlibをインストール
$ sudo pip3 install matplotlib

# gpuGraphを起動（バックグラウンド実行）
$ python3 gpuGraph.py &
```

![gpuGraph.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/63e64fe2-346b-fa80-b452-cdc689c7ba2b.png)


---
# 24. 補足その10：感動を味わえる JetsonNano shellスクリプト集
- [株式会社ProsCons](https://proscons.co.jp/)のエンジニアチームみなさまが提供する感動を味わえる JetsonNano shellスクリプト集についてです。JetsonNanoをまっさらな状態から画像認識系のもろもろセットアップに役立つ必読Qiita記事だと思います、JetsonNanoビギナーにおすすめです。
- [Jetson Nano で簡単な画像認識・骨格姿勢検知を動かす基本設定色々デモ](https://qiita.com/ProsConsInc/items/51d77edf85e3ba673338)
- [GitHub：tools for Jetson Nano](https://github.com/ProsConsInc/jetson-nano)

- [10_run_darknet.sh](https://qiita.com/ProsConsInc/items/51d77edf85e3ba673338#10_run_darknetsh)のshellスクリプトを実行して、Darknet（フレームワーク）でTiny YOLO v3（オブジェクト認識）を実行するとこんな感じのレクタングル（矩形）になりました。

![yolov3-tiny_CUP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/7f0af23c-d9f9-e3dd-2e5c-a2fdaee935a0.png)

# 25. 補足その11：Jetson Nanoを起動直後から CPUフルパワーで稼働させるやつ

```shell:コマンドプロンプト
# ディレクトリを移動
$ cd /opt/

# シェルファイルを新規作成
$ sudo vi autoexec_root.sh

#＝＝＝ここから autoexec_root.sh ＝＝＝
#!/bin/sh

# MAXNモードの時 CPU4コアで動作
sleep 5
sudo nvpmodel -m 0

# 最高速（最大動作周波数）で動作
sleep 5
sudo jetson_clocks

# 冷却ファンの制御100%で動作
sleep 5
sudo sh -c 'echo 255 > /sys/devices/pwm-fan/target_pwm'
#＝＝＝ここまで autoexec_root.sh ＝＝＝

# cronで起動ブート時にシェルを実行するように1行追記（/bin/shをつけて実行してるので、シェルファイルにパーミッションは付与しとかなくてもOK）
$ sudo crontab -e
@reboot /bin/sh /opt/autoexec_root.sh

# OS再起動
$ sudo shutdown -r now

# cronログの確認
$ journalctl -u cron
q
```

```shell:/opt/autoexec_root.sh
#!/bin/sh

# MAXNモードの時 CPU4コアで動作
sleep 5
sudo nvpmodel -m 0

# 最高速（最大動作周波数）で動作
sleep 5
sudo jetson_clocks

# 冷却ファンの制御100%で動作
sleep 5
sudo sh -c 'echo 255 > /sys/devices/pwm-fan/target_pwm'
```


---
# 26. おわりに
みなさまの学習の参考になれば幸いです。

2019/07/14 TAKAHIRO NISHIZONO