ROS KineticでOpenPose(CPU版/GPU版)を試す準備

# 動機
OpenPoseをROSと連携して動かそうと思う。
CPU版が2018年3月に出たらしいので、まずはCPU版を試してみます。
うまく行けば、ビルドディレクトリを分けて、GPU版も実行してみます。

結論としては、公式のinstructionにしたがうと、自分の環境ならば、何も問題なく実行できました。



# 環境
- Ubuntu 16.04LTS
- GeForce GTX 1080Ti (GPUあるけど、今回はCPU版を試す。あとでGPU版も)
- ROS Kinetic Kame
- CUDA 8.0
- cuDNN 6.0

CUDA, cnDNNあたりは、機械学習用に使っているPCをそのまま使っているので、既に入っている状況。
CPU版を実行したいと思っても、CMakeでの設定時にCUDAとかcuDNNが出てくるので、ビルド時に使っているのだろうか？
まったく、GPUなし、CUDAなし、cuDNNなしの環境では試していないので、あしからず。

**=注意=**
Ubuntu純正の環境なら何も問題なくできるけれども、
WindowsにVM使ってUbuntuを入れている環境でやってみると、CMakeでビルドファイルを作るあたりで、エラーで以降進めません。原因・場所を検証中。

CMake-guiで、フォルダを指定して、Configureボタンを押すタイミングで、うまく行く場合はcaffe関係のファイルをダウンロードしてくるんだけども(CMakeLists.txtにもそういったコマンドが書いてあるし)、VM環境だとダウンロードに失敗している様子。
環境違いによる影響があるのかなぁと思いつつ、比較しているのが対照的なので、自分一人では分からない。

- Windows + VM(Ubuntu) + GPUなし　　　　　 => 失敗
- Ubuntu + GPU(CUDA, cuDNNインストール済み) => 成功



# 参考情報
[OpenPose ソース](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md#cpu-version)
[Ubuntu14.04にCaffeをインストール(CPUモード)](https://qiita.com/TD72/items/1bab76e395243defcc06)
[空飛ぶロボットのつくりかた　機械学習のお勉強（DeepPose, OpenPose](http://robonchu.hatenablog.com/entry/2017/09/11/141836)
[OpenPoseをROSで動かす](https://qiita.com/slowsingle/items/3ba6ec991d951ccd7518)



# OpenPoseのインストール

Ubuntu16.04LTSに、今回はCPU版のインストールを目指します。


## 1. Clone OpenPose

適当な作業用ディレクトリを作成して、その中で

```
$ git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose
```
すると、openposeを持ってこれる。



## 2. Prerequisites
### CMake GUIのダウンロードとインストール

```
sudo apt-get install cmake-qt-gui
```
今回は、CPU版をまずは入れるので、cuda, cudnnあたりをスキップして、Ubuntu - Other prerequisitesの、Caffe prerequisitesを実行

```　　
$ cd openpose
```
して、

```
$ sudo bash ./ubuntu/install_cmake.sh
```
を実行。インストールの許可を聞かれるので、全部yes。
ログを見ている感じだと、cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-debのダウンロード、インストールがされているっぽい。

（のちほどCMakeするときに、caffe関係のファイルをzipでダウンロードすることなどが、CMakeLists.txtに書いてある様子）。


OpenCVが入っていなければ、

```
$ apt-get install libopencv-dev
```
権限で怒られたら、sudoをつけとく。

### GPU版の時
GPU版の時は、cudaやcudnnが未インストールならば、それらを入れるためのシェルを動かす様子。


　　
## 3. OpenPose Configuration
次に、CMakeでビルドするための各種ファイルの生成を行う。  
CMake-GUIの起動は、

```
$ cmake-gui
```
GUIが起動したら、それぞれの空欄を埋めていく。

1. パスの設定
[Where is the source code]には、git cloneしてきたディレクトリのパス、[..../openpose/]を指定する。
[Where to build the binaries]には、[..../openpose/build]を指定する。
（フォルダが無くても、勝手に作ってくれる。 mkdir buildしておいてもよい）

2. 設定の確認
[Configure]ボタンを押す。
(buildディレクトリが無ければ、作りますか？と聞かれるので[OK])

3. コンパイラの指定
つぎに、コンパイラの指定をする。
デフォルトで選ばれているが、[Unix Makefile]を選択して、[finish]。
しばらく、モデルのダウンロードに時間がかかるが（1~2分）、問題なければ、Configure doneのテキスト表示が下のログに出る。
上半分が赤いのは、問題ない。ただ、新規・変更箇所を明示しているだけっぽい。

4. 設定の修正

- CPU版を生成するには、上の設定リストから、[GPU_MODE]のvalueを選び(ダブルクリック)、[CPU_ONLY]に変更する。
- GPU版のときは、とくに何もいじらずに次へ。

5. 変更後の設定確認
上半分の設定を変更したら、（常に）再度[Configure]ボタンを押す。
問題なければ、下半分にはエラーは出ないはず。

6. ビルドファイル生成
問題なければ、[Generate]ボタンを押下
（一瞬で終了する。下に、"Generating done"のテキストが表示されている）
buildディレクトリに、何かしらファイルが生成されているはず。


__=余談(追記 18/04/17)=__
VM環境で、CPU版を入れようとしたときに、CMakeのconfigureを実行しても、エラーが出て動けない状況になった。CMake時のCMakeLists.txtを読み込んで、各設定をしたり、必要なもののダウンロードをしている様子だが、caffe関連のダウンロードに失敗して以下のようなエラー。

```
Caffe will be built from source now.
CMake Error at /usr/share/cmake-3.5/Modules/ExternalProject.cmake:1915 (message):
 No download info given for 'openpose_caffe' and its source directory:

 /home/{user_name}/.../openpose/3rdparty/caffe

 is note an existing non-empty directory. ......
```

openpose->3rdparty->caffeフォルダ内を確認すると、本来は必要なライブラリ、インクルードファイルがダウンロードされるはずだがされていない。
上の設定の部分でも、

- Caffe_INCLUDE_DIRS
- Caffe_LIBS 
が、NOTFOUNDとなっている。

CMakeLists.txtを読む限り、caffeのgitからCaffeをもってきているようなので（正確には、どこかのブランチのタイミングのもの？）、/openpose/3rdpartyディレクトリに対して、手動でgit cloneをしてみて、もう一度、Configureをしてみる。

```
git clone https://github.com/BVLC/caffe.git
```

もう一度、Configureしてみると(CPU版の時は、GPU_MODE=CPU_ONLYに変更)、ビルドに必要なファイルが生成されていく（一度、doxygenが無いよ！とエラーが起きたので、apt-getで、インストールして再度,Configureの実行、generateボタンを押下）。




CMake

## 4. ビルド

次に、プロジェクトのビルドを行う。
このビルドはそれなりに動作が重たいものとなるので、VMなどで実行するときは、コア数を増やしたり、メモリを増やしたりしたほうがいい様子。

```
cd build/
make -j`nproc`
```
と書いてあるけど、`nproc`とは打たずに、使用可能なCPU数を書くみたいだ。
なので、

```
$ nproc
```
で数を調べてCPUの数を書くか、引数無しにすれば、勝手に数を判断して実行してくれるっぽいので、

```
cd build/
make -j
```
として、自分は実行。GPUのある自分の環境だと(nprocすると、8)、2分くらいでビルド終了。

# OpenPoseの利用

OpenPoseを他のプロジェクトで使うためには、
さらに設定が必要そう。CMakefile.txtに

[OpenPose from other Projects (Ubuntu Only)](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md#openpose-from-other-projects-ubuntu-only)

とりあえず、デモへ！という人はこちらのQuick Startへ。
[Quick Start](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/quick_start.md#quick-start)

Webcamで試してみるには、下のように実行する。
よく実行結果で見かける、体全体のボーン推定をするには、

```
$ ./build/examples/openpose/openpose.bin
```
を実行。さすがCPU版。0.5FPS（2秒に一回）とのこと。体感はもっと遅い。

顔の輪郭、目などの器官の位置の表示、手指のボーン推定をするには、

```
$ ./build/examples/openpose/openpose.bin --face --hand
```
こちらはさらに負荷が高いのか、0.3FPS(3秒に一回)。
やはりGPU版にしないとダメやね。

画像を指定するなら、リンク先のようにオプションで指定する。

__実行時の注意は、openposeディレクトリにして上を実行すること__。buildディレクトリに移動して実行しようとしたら、/openpose/models/pose/coco/pose_deploy_linevec.prototxtが無い！って怒られる(ちゃんとファイルはある)。実行時に内部で、ファイル実行をした場所を取得してパスの参照をしてるっぽい。

GPU版で実行すると、通常のボーン推定は7.4FPSくらい、face/hand推定にすると5.1FPSでした。約14~15倍高速に。ウェブカメラの映像見ててもストレス無いしね。

# ROSとの連携

まずOpenPose APIを利用するためには、OpenPoseヘッダーやライブラリをインストールしなければならないということで、

```
$ cd build/
$ sudo make install
```
を実行する。しばらく待つと、hppファイルなどが、/usr/local/includeや、/usr/local/lib 以下に配置される。

## CMakeListの設定

公式の設定と、こちらの情報を頼りに
[OpenPose](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md#openpose-from-other-projects-ubuntu-only)
[OpenPoseをROSで動かす](https://qiita.com/slowsingle/items/3ba6ec991d951ccd7518)

gitでコードを公開してくれているが、C++なのでpythonに翻訳しながら頑張って書き換えてみよう。


## パッケージの生成

/catkin_ws/srcに移動して、下のように新規パッケージを生成

```
$ catkin_create_pkg openpose_ros rospy roscpp std_msgs
```

つぎに、CMakeLists.txtを編集する。

120行目前後（行を挿入して行くので大体）あたりの、

```
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
```
を、次のように追加。

```
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
  /usr/local/cuda/include
  /home/{user_name}/.../openpose/include
  /home/{user_name}/.../openpose/3rdparty/caffe/include
)
```
openposeをクローンしてきたディレクトリを指定する。
ライブラリは、150行目辺りに、次のようにコメントアウトされているので、

```
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )
```
となっているのを、

```
target_link_libraries(${PROJECT_NAME}_node
  ${catkin_LIBRARIES}
  /usr/lib/x86_64-linux-gnu/libglog.so
  /usr/lib/x86_64-linux-gnu/libgflags.so
  /usr/lib/x86_64-linux-gnu/libgflags_nothreads.so
  /usr/local/lib/libopenpose.so
  /usr/local/lib/libcaffe.so
)
```
と書き換えたり、公式を参照したが、gflagsとか、glogとか見慣れない単語があって、そのまわりで、catkin_makeするときにエラーが発生する。
[ubuntu14.04にCaffeもインストールする](https://qiita.com/masataka46/items/ac22818aac89f9c9dd0e)
あたりの情報を見ていると、Caffeインストール時のprerequisitesな様子?

[Caffeの公式サイト](http://caffe.berkeleyvision.org/install_apt.html) の必要なものを再度インストール・チェックしているが、

```
$ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
$ sudo apt-get install --no-install-recommends libboost-all-dev

$ sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
```
最後の、gflags, glogあたりは最新版が入っていた。んーちょっと行き詰まった感じか。