Jetsonの応用を検討

# はじめに
　Jetsonの記事をまとめます。Jetsonを応用するために、まずはJetsonを勉強するところから始めようと考えています。当面は、cuda環境の構築を行い、特定のAIモデルを選択し、気軽に学習できる環境を構築することを目標とします。

# 環境
* Jetson Xavier NX
* USBカメラ（Logicool C270）
* NVIDIA A100 Tensor Core GPU

# 背景
　AIのエッジコンピューティング環境を画像処理のために用意したが、実際にどのように使用してよいか、よくわからないというところがあり、現状活用できていない。Jetsonに関係する情報を集め、サンプルプログラムを動作させるところからはじめ、最終的には[学習環境(NVIDIA A100 Tensor Core GPU)](https://qiita.com/segiori/items/f1eefe5d9284766d22ae)と推論環境(Jetson)の連携を図ることを模索します。

# やりたいこと
　　[遠隔に機械学習環境](https://qiita.com/segiori/items/f1eefe5d9284766d22ae)が準備できたので、以下のNVIDIAが示すネットワークモデルを目標に環境を構築します。
![スクリーンショット 2022-02-26 10.36.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423321/41dd1d96-f2c7-4964-903b-4f9adfa60657.png)

# 調査概要
　[Getting Started With Jetson Xavier NX Developer Kit](https://developer.nvidia.com/embedded/learn/get-started-jetson-xavier-nx-devkit)の顔トラッキングができたので、その次のサンプルプログラムを動作させてみたいと思います。

1. Jetsonのセットアップ
2. （参考）Jetsonの推論結果をRTPでPCに転送する 
3. サンプルスクリプトを作成し、動作させる
4. Jetson内でイメージ分類モデルを学習させる（途中）
5. 遠隔の機械学習環境と連携させる（途中）
6. サンプルではなく、独自の環境を構築する（途中）

# 調査詳細

## 1　Jetsonのセットアップ
　[NVIDIA公式ページ](https://github.com/dusty-nv/jetson-inference)を参考にJetsonのセットアップを行います。VideoWalkThroughsには動画コンテンツもあるのでおすすめできます。

1.　事前にUSBカメラをJetsonに接続しておく

2.　まず現在のJetsonのセットアップ状況を確かめる

　(1).　L4Tバージョンは以下のとおり

~~~bash:L4Tバージョン
$ cat /etc/nv_tegra_release
# R32 (release), REVISION: 6.1, GCID: 27863751, BOARD: t186ref, EABI: aarch64, DATE: Mon Jul 26 19:36:31 UTC 2021
~~~

　(2).　nvidia-l4t-coreバージョンは以下のとおり

~~~bash:nvidia-l4t-coreバージョン
$ dpkg-query --show nvidia-l4t-core
nvidia-l4t-core	32.6.1-20210726122859
~~~

　(3).　JetPackのバージョンは以下のとおり

~~~bash:JetPackバージョン
$ sudo apt show nvidia-jetpack
Version: 4.6-b199
~~~

3.　次にdocker containerをクローンし、docker上でAI環境セットアップ

~~~bash:docker container クローン＆セットアップ
$ git clone --recursive https://github.com/dusty-nv/jetson-inference
$ cd jetson-inference
$ docker/run.sh
~~~

4.　2のAI環境セットアップで0で接続したカメラを自動でマウントしたことを確認

~~~bash:マウント確認
$ cd build/aarch64/bin
$ ls /dev/video*
$ ./video-viewer /dev/video0
~~~

5.　USBカメラから取得したストリーミング映像でリアルタイム物体判定

~~~bash:detectnetと映像の接続
$ detectnet /dev/video0
~~~
![Screenshot from 2022-03-02 04-26-44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423321/d2c3d91a-6c96-e6c6-5ad5-9e05c3c96888.png)

6.　USBカメラから取得したストリーミング映像でリアルタイム物体判定

~~~bash:imagenetと映像の接続
$ imagenet /dev/video0
~~~
![Screenshot from 2022-03-02 05-03-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423321/416ebad8-a833-04eb-b7b2-44c4b92487bf.png)

7.　（参考）

　色々な画像、動画、プロトコルに対応している。手持ちのGenie Nanoで動作させるためには、プロトコル変換（ファイル保存、rtp配信等）する必要があるかもしれない（要調査）。
　[Camera Streaming and Multimedia](https://github.com/dusty-nv/jetson-inference/blob/master/docs/aux-streaming.md)

* MIPI CSI cameras
* V4L2 cameras
* RTP / RTSP
* Videos & Images
* Image sequences
* OpenGL windows

## 2　（参考）Jetsonの推論結果をRTPでHostPC(MacOS)に転送する 
　HostPC(MacOS)のターミナルウインドウをTerminal1, Terminal2と分けて、それぞれで操作します（混乱しやすいので、記載を分けました。）。

1.　(Terminal1)HostPC(MacOS)にGStreamerをインストールする
~~~bash:GStreamerのインストール
$ brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad
$ brew install gst-plugins-ugly
~~~

2.　(Terminal1)HostPC(MacOS)からJetsonにssh接続する
~~~bash:HostPCからJetsonにssh接続
$ ssh -XY xxxx@hostname
~~~

3.　(Terminal1)Jetson上の1-3で起動したdockerコンテナをbashで立ち上げ、detectnetを起動する
~~~bash:既存docker imageへの接続（ポートは1234）
$ sudo docker exec -it (containerid) /bin/bash
$ detectnet /dev/video0 rtp://HostPC名（IPアドレス）:1234
~~~
<b>（注意）sshでリモート接続した後にコンテナをアタッチする必要がある</b>

4.　(Terminal2)MacOSでのRTP受信
~~~bash:GStreamerでポート1234に届くudpパケットを受信する
$ gst-launch-1.0 -v udpsrc port=1234 \
 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! \
 rtph264depay ! decodebin ! videoconvert ! autovideosink
~~~

5.　結果
![IMG_7206.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423321/5ffe95f2-f2bb-7209-59f1-0c51d61b5eef.jpeg)

* nvidiaの公式ページで説明があるように多少の遅延が生じる
* Jetsonそのものにはモニターをつけずに、遠隔PCから確認することも可能になる

## 3　サンプルスクリプトを作成し、動作させる
　まずは、[お手本](https://github.com/dusty-nv/jetson-inference/blob/master/docs/imagenet-example-python-2.md)のとおりmy-recognition.pyスクリプトを作成し、動作させる（nvidiaのページほぼそのまま）。

1.　外部にディスク作成し、それをコンテナからマウントする
~~~bash:
$ cd ~/
$ mkdir my-recognition
$ cd my-recognition
$ touch my-recognition.py
$ chmod +x my-recognition.py
$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/black_bear.jpg 
$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/brown_bear.jpg
$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/polar_bear.jpg 
$ cd jetson-inference
$ docker/run.sh --volume ~/my-recognition:/my-recognition
~~~

2.　my-recognition.pyを修正する
~~~python:my-recognition.py
import jetson.inference
import jetson.utils

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("filename", type=str, help="filename of the image to process")
parser.add_argument("--network", type=str, default="googlenet", help="model to use, can be:  googlenet, resnet-18, ect. (see --help for others)")
args = parser.parse_args()

img = jetson.utils.loadImage(args.filename)

net = jetson.inference.imageNet(args.network)

class_idx, confidence = net.Classify(img)

class_name = net.GetClassDesc(class_idx)

print('classified image as {:s} (class ID {:d}, confidence {:f})'.format(class_name, class_idx, confidence))
~~~

3.　実行する
　一部のモデルは再インストールが必要となる。下記はgooglenetとresnet-18の例
~~~bash:googlenet(default)
$ python3 ./my-recognition.py polar_bear.jpg
~~~
~~~bash:resnet-18
$ python3 ./my-recognition.py polar_bear.jpg --network=resnet-18 
~~~
　推論時間を比較すると圧倒的にgooglenetが速い。

## 4　Jetson内でイメージ分類モデルを学習させる（途中）


# 参考記事

* 記事 
  * [NVIDIAが「Jetson Nano」搭載のAIレースカー「JetRacer」情報を公開！NVIDIA担当者に聞く、Jetson最新情報やTPUとの比較](https://robotstart.info/2019/08/09/jetracer-github.html)
* youtube
  * [NVIDIA JetBot: Jetson Nano Vision-Controlled AI Robot](https://www.youtube.com/watch?v=wKMWjIKaU68)
  * [Jetbotとディープラーニングで自動走行を学習させる](https://www.youtube.com/watch?v=oOnJ04x0YA0)
  * [【Jetson Xavier NX レビュー(3)】学習モデル作成編　コードを書かずにマスクの装着を判定するAIを自作してみた](https://robotstart.info/2020/05/29/jetson-xavier-nx-review-03.html)
  * [Jetsonの各開発キットを比較](https://www.macnica.co.jp/business/semiconductor/articles/nvidia/133162/)
* NVIDIA公式 
  * [自宅でAIを探求する](https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems/jetson-nano-developer-kit/)
  * [Jetson Xavier NX開発者キット及びモジュール](https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems/jetson-xavier-nx/#top)
  * [Getting Started With Jetson Xavier NX Developer Kit](https://developer.nvidia.com/embedded/learn/get-started-jetson-xavier-nx-devkit)
  * [NVIDIA TensorRT](https://developer.nvidia.com/tensorrt)  
  * [GTC November 2021 Keynote with NVIDIA CEO Jensen Huang](https://www.youtube.com/watch?v=jhDiaUL_RaM)
  * [GTC Spring 2021 Keynote with NVIDIA CEO Jensen Huang](https://www.youtube.com/watch?v=eAn_oiZwUXA)
  * [Related Documentation For Jetson](https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/downloads.html#)
  * [Getting Started With Jetson Xavier NX Developer Kit: NextStep](https://developer.nvidia.com/embedded/learn/get-started-jetson-xavier-nx-devkit#next)
* Qiita
  * [Jetson Xavier NX セットアップ＋CUDAデモ](https://qiita.com/futakuchi0117/items/b815fa64563e98602bfc)
  * [jetsonで深層学習をする環境を整える](https://qiita.com/ryota_101020/items/57e0270988f2f55e5932)
  * [TensorRTって何者？](https://qiita.com/Hiroaki-K4/items/e8dc965c7640c67fdf02)
  * [Jetson と TensorRT で画像認識の高速化2019](https://qiita.com/dcm_yamaya/items/dcb149684fb210b39e8c)