NVIDIA JetsonTX2でtf-openposeを動かすまでメモ（2018年10月確認）


<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">JetsonTX2でFPS4くらいでopenpose動かせた <a href="https://t.co/GQw8R3vmRi">pic.twitter.com/GQw8R3vmRi</a></p>&mdash; ysdyt (@yutatatatata) <a href="https://twitter.com/yutatatatata/status/1054790672211800064?ref_src=twsrc%5Etfw">2018年10月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Nvidia Jetson TX2でtf-openposeを動かすまでの記録 2018年10月14日版です。

参考リンクの通り、過去にもすばらしい記事が書かれているのですが、内容が少し古くなりつつあるのでそのあたりの差分を意識しつつ更新した内容になっています。

基本的には以下のQiita記事に沿って実行しました。

- [NVIDIA Jetson TX2でTensorFlowによる人体姿勢推定プログラムを動かせるようになるまで](https://qiita.com/ababa831/items/57b43e788d684c380866)

Jetson TX2とは？ tf-openposeとは？ みたいな話は上記記事の冒頭を参照してください。



## Jetson TX2の初期設定

上記記事の通りに実行して初期設定を完了できました。

記事内容通り、Jetsonの初期設定に別途必要なubuntuマシンは、vertualboxなどを使わずに物理的な別マシンを用意しました。

**1.JetPackのダウンロード** では、2018年10月段階では「JetPack 4.1 Developer Preview *Early Access*」が出ていましたが、自分は「JetPack 3.3」をインストールしました。（※ JetPackのDLにはNVIDIA Developersサイトへの無料のアカウント作成が必要です）



スクショ付きの手順書として、Classmethodさんのページも参考になりました。画面のUIが最新版のものと少し違いますが、内容的にはほぼ一緒でした。

- [NVIDIA Jetson TX2をセットアップしてみた](https://dev.classmethod.jp/etc/jetson-setup/)

自分が少し迷ったのは Network Interface Selectionの箇所で、これはセットアップしているネットワーク環境で異なるので自分の場合は"eth0"ではありませんでした。たしか、`ifconfig`で一覧表示されるものの中から、global IPがついているものが一つだけあったのでそれを選択しました。



USBリカバリーモードに切り替えるステップも、物理ボタンを押しながら「ほんとにこれで合ってるんか...」と心配な気持ちになりますが、手順書通りに進めればなんやかんや大丈夫でした。



## モロモロのインストール

以下、今回はPython3.5環境での構築が前提となっています。

また、以下の**3.virtualenvのインストール**でvirtualenvで作成する `openpose`という名前の仮想環境下でtf-openposeを動かすことを目標として進めます。

まずは、

1. python3.5
2. pipのインストール
3. virtualenvのインストール

までは[こちらのページ](https://qiita.com/ababa831/items/57b43e788d684c380866)通りです。



### Tensoflowのインストール

ここから少し参考にしている記事と違う方法を行います。



(1)TensorFlowのコンパイルに必要なメモリ容量が８GB以上なので、スワップ領域を確保

```console
$ fallocate -l 8G swapfile
$ chmod 600 swapfile
$ mkswap swapfile
$ swapon swapfile
$ swapon -s
```



(2)配布されているwhlファイルからpip3でtensorflowをインストールする

元ページではここからBazelというビルドツールなどを使ってTensoflowをビルドしますが、自分の環境では上手くいきませんでした。そこで[こちらのページ](https://twdlab.hatenablog.com/entry/2018/06/19/102332)の方法を参考にしました。

[こちら](https://devtalk.nvidia.com/default/topic/1031300/tensorflow-1-8-wheel-with-jetpack-3-2-/)のNVIDIA公式ページが配布しているtensorflowのwhlファイルをダウンロードします。上記でダウンロードしたJetPack3.3向けとなっているPython3.5用のファイルをDL

virtualenvで作成した仮想環境にいる状態で以下を実行します。

```console
$ pip3 install DLしたファイル.whl
```


インストールの確認には、仮想環境下で `pip3 freeze`して `tensorflow==1.11.0rc1`が表示されればok

※ `sudo pip3 install DLしたファイル.whl` のように、sudoにすると仮想環境下ではなく、システム側にinstallされてしまうので注意



### OpenCV3.4.0のインストール

厄介なところです。これも参照元のQiitaページでは上手く行かなかったので、[こちらのページ](https://jkjung-avt.github.io/opencv3-on-tx2/)を参考にしました。

（※ 以下の一連のinstall作業でも、`pip3`で入れるところは`sudo` を外さないと仮想環境下にインストールされないかもしれません。このあたりちょっと自身ないので、一旦sudoつけてやってみて、うまくいかなかったらsudo外してやってみる、みたいな感じがいいかもです。）



(1)まずは、古いopencv系package・numpy・使わないその他packageを削除

```console
### Remove all old opencv stuffs installed by JetPack (or OpenCV4Tegra)
$ sudo apt-get purge libopencv*
### I prefer using newer version of numpy (installed with pip), so
### I'd remove this python-numpy apt package as well
$ sudo apt-get purge python-numpy
### Remove other unused apt packages
$ sudo apt autoremove
```

(2)念の為、apt packageをupdateしておく

```console
### Upgrade all installed apt packages to the latest versions (optional)
$ sudo apt-get update
$ sudo apt-get dist-upgrade
```

(3) ガベージコレクション系のものも念の為update（強く推奨、らしいのでやっとく）

```console
### Update gcc apt package to the latest version (highly recommended)
$ sudo apt-get install --only-upgrade g++-5 cpp-5 gcc-5
```

(4)もろもろ依存関係のpackageを全部入れる

```console
### Install dependencies based on the Jetson Installing OpenCV Guide
$ sudo apt-get install build-essential make cmake cmake-curses-gui \
                       g++ libavformat-dev libavutil-dev \
                       libswscale-dev libv4l-dev libeigen3-dev \
                       libglew-dev libgtk2.0-dev
### Install dependencies for gstreamer stuffs
$ sudo apt-get install libdc1394-22-dev libxine2-dev \
                       libgstreamer1.0-dev \
                       libgstreamer-plugins-base1.0-dev
### Install additional dependencies according to the pyimageresearch
### article
$ sudo apt-get install libjpeg8-dev libjpeg-turbo8-dev libtiff5-dev \
                       libjasper-dev libpng12-dev libavcodec-dev
$ sudo apt-get install libxvidcore-dev libx264-dev libgtk-3-dev \
                       libatlas-base-dev gfortran
$ sudo apt-get install libopenblas-dev liblapack-dev liblapacke-dev
### Install Qt5 dependencies
$ sudo apt-get install qt5-default
```

(5)Python3系のopencvに関するpackageもインストール

```console
### Install dependencies for python3
$ sudo apt-get install python3-dev python3-pip python3-tk
$ sudo pip3 install numpy
$ sudo pip3 install matplotlib
```

(6) matplotlibにおけるフォント表示問題を解決するいつものやつ

```console
### Modify matplotlibrc (line #41) as 'backend      : TkAgg'
$ sudo vim /usr/local/lib/python3.5/dist-packages/matplotlib/mpl-data/matplotlibrc
```

(7)Python2系についても同じ操作をやっとく

```console
### Also install dependencies for python2
### Note that I install numpy with pip, so that I'd be using a newer
### version of numpy than the apt-get package
$ sudo apt-get install python-dev python-pip python-tk
$ sudo pip2 install numpy
$ sudo pip2 install matplotlib
### Modify matplotlibrc (line #41) as 'backend      : TkAgg'
$ sudo vim /usr/local/lib/python2.7/dist-packages/matplotlib/mpl-data/matplotlibrc
```



(8)OpenGL関連のコンパイルエラーを解決するために少しスクリプトをイジる

正直、これの意味はわからないけど一応やっといた

```console
$ sudo vim /usr/local/cuda/include/cuda_gl_interop.h
```

62~68あたりにあるスクリプトを以下のように書き変える

```console
//#if defined(__arm__) || defined(__aarch64__)
//#ifndef GL_VERSION
//#error Please include the appropriate gl headers before including cuda_gl_interop.h
//#endif
//#else
 #include <GL/gl.h>
//#endif
```

書き換えたら移動してリンクを貼る

```console
$ cd /usr/lib/aarch64-linux-gnu/
$ sudo ln -sf tegra/libGL.so libGL.so
```



(9)opencv-3.4.0のダウンロード・cmake・コンパイル

```console
### Download opencv-3.4.0 source code
$ mkdir -p ~/src
$ cd ~/src
$ wget https://github.com/opencv/opencv/archive/3.4.0.zip \
       -O opencv-3.4.0.zip
$ unzip opencv-3.4.0.zip
### Build opencv (CUDA_ARCH_BIN="6.2" for TX2, or "5.3" for TX1)
$ cd ~/src/opencv-3.4.0
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local \
        -D WITH_CUDA=ON -D CUDA_ARCH_BIN="6.2" -D CUDA_ARCH_PTX="" \
        -D WITH_CUBLAS=ON -D ENABLE_FAST_MATH=ON -D CUDA_FAST_MATH=ON \
        -D ENABLE_NEON=ON -D WITH_LIBV4L=ON -D BUILD_TESTS=OFF \
        -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF \
        -D WITH_QT=ON -D WITH_OPENGL=ON -D BUILD_opencv_python3=ON ..
$ make
$ sudo make install
```

makeを実行したときに、Python2と3について以下のように Libraries や numpy がインストールされた場所が表示されればok

```
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.12)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.12)
--     numpy:                       /usr/local/lib/python2.7/dist-packages/numpy/core/include (ver 1.15.2)
--     packages path:               lib/python2.7/dist-packages
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.5.2)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.5m.so (ver 3.5.2)
--     numpy:                       /usr/local/lib/python3.5/dist-packages/numpy/core/include (ver 1.15.2)
--     packages path:               lib/python3.5/dist-packages
```



最後に、インストールの確認

```console
$ ls /usr/local/lib/python3.5/dist-packages/cv2.*
/usr/local/lib/python3.5/dist-packages/cv2.cpython-35m-aarch64-linux-gnu.so
$ ls /usr/local/lib/python2.7/dist-packages/cv2.*
/use/local/lib/python2.7/dist-packages/cv2.so
```

**Python3で`cv2.cpython-35m-aarch64-linux-gnu.so`、Python2で`cv2.so`というのが見つかればok**

Python2/3それぞれで `import cv2`が通るかも確認してみる。



※ちょっと確度があいまいだが、仮想環境下でも動かすためには 

```console
$ ln -s /usr/local/lib/python3.5/dist-packages/cv* (仮想環境のパス)/lib/python3.5/site-packages
```

のように、仮想環境下のパスにもリンクを貼ってあげないといけないかも。

つまり、`/usr/local/lib/python3.5/dist-packages/`がシステム側のパッケージインストール場所で、`(仮想環境のパス)/lib/python3.5/site-packages`が仮想環境下のパッケージインストール場所。ここをリンク関数`ln`で繋いであげる。



### その他、他の依存packageもインストールしておく

```console
$ sudo pip install protobuf
$ sudo apt-get install python3-tk
```



## tf-openposeのインストール

こちらもtf-openposeの元ページの内容が結構更新されているので、Qiitaの内容とはいろいろ違ってます。

[tf-openposeのGithubのreadme](https://github.com/ildoonet/tf-pose-estimation)に従う。

(1)tf-openposeをダウンロードして、requirement.txtの中身をインストール

```console
$ git clone https://www.github.com/ildoonet/tf-openpose
$ cd tf-openpose
$ pip3 install -r requirements.txt
```

(2)後処理のためのc++ライブラリーをbuildする

```console
$ cd tf_pose/pafprocess
$ swig -python -c++ pafprocess.i && python3 setup.py build_ext --inplace
```



## tf-openposeのリアルタイム姿勢推定を動かす

(1) run_webcam.pyのコードを少しイジる（※念の為イジる前のファイルをバックアップしておくのが吉）

`run_webcam.py`の45行目にある

`cam = cv2.VideoCapture(args.camera)`を

`cam = cv2.VideoCapture("nvcamerasrc ! video/x-raw(memory:NVMM), width=(int)368, height=(int)368,format=(string)I420, framerate=(fraction)30/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink")
`

に書き換える。

(2)tf-openposeを実行する

```console
$ python3 run_webcam.py --model=mobilenet_thin --resize=432x368 --camera=0
```

実行すると学習済みファイルのinitializationやtensorflowの起動でやや時間がかかるが、別ウィンドウがポップアップし、姿勢推定が始まる（コケた場合でも、自分の場合なぜかもう一度同じコマンドを実行すると2回目はうまくいったりする）



<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">JetsonTX2でFPS4くらいでopenpose動かせた <a href="https://t.co/GQw8R3vmRi">pic.twitter.com/GQw8R3vmRi</a></p>&mdash; ysdyt (@yutatatatata) <a href="https://twitter.com/yutatatatata/status/1054790672211800064?ref_src=twsrc%5Etfw">2018年10月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



## 感想

ここで使っている[tf-openpose-estimation](https://github.com/ildoonet/tf-pose-estimation)が内容更新されていることもあり、qiitaなどにある古いhow toサイトではやり方が違っているところが多々ありますが、それは元ページのREAD.MEを読みながら適宜対応という感じです。

もっとも厄介だったのが、**vertualenvを使った仮想環境下でOpenCVを入れるところ**でした。

基本的にsudoでインストールすると仮想環境下（`(仮想環境のパス)/lib/python3.5/site-packages`）ではなく、システム側（`/usr/local/lib/python3.5/dist-packages/`）にパッケージがインストールされます。apt-getでインストールする系のものは基本的にsudoを使わないと権限が無くて入れられないようなので仕方がないですが、pip3で入れる系のパッケージは`sudo pip3`でインストールするとシステム側にインストールされてしまい仮想環境下ではパッケージがみつからないというどこにインストールされたのか迷子状態になってしまいます。（自分がLinuxの基本的なところをきちんと理解してないことも原因ですが...）

最後の方はゴニョゴニョしているうちに、「あ、なんかうまく出来てたわ」みたいな状態になってしまいました…再現性...



## その他トラブルメモ

(1)`h5py`がインストールできない？

ubuntuでのpython3にh5pyをインストールする場合、pipだとコケるけど、 `sudo apt-get install python3-h5py` すると入って、tensorflowも問題なくパスできるということらしい…



(2)`pyzmq`というもののインストールにコケる

`sudo apt-get install libzmq3-dev` した後に `pip3 install pyzmq` すると上手くいった





## 参考リンク

- https://github.com/ildoonet/tf-pose-estimation
  - ここで使っているtf-openposeの元ページ
- [NVIDIA Jetson TX2でTensorFlowによる人体姿勢推定プログラムを動かせるようになるまで](https://qiita.com/ababa831/items/57b43e788d684c380866) 
  - 最も参考になったページです！
- [Jetson TX2 環境構築 リベンジマッチ(JetPack3.2.1) Openposeを導入するまで](https://twdlab.hatenablog.com/entry/2018/06/19/102332) 
  - tensorflowとopencvのインストールについて非常に参考になりました