VideoPose3Dを動かしてみた（Detectronから）

CVPR2019のVideoPose3Dを[有志の実装](https://github.com/tobiascz/VideoPose3D)を参考にして動かしてみました。環境設定苦労したのであまりスマートじゃないですが日本語訳としてメモ残します。誰かの参考になれば。

[3D human pose estimation in video with temporal convolutions and
semi-supervised training](https://arxiv.org/pdf/1811.11742.pdf)

![alt](https://github.com/facebookresearch/VideoPose3D/blob/master/images/demo_yt.gif?raw=true)

 ![alt](https://github.com/facebookresearch/VideoPose3D/blob/master/images/convolutions_1f_naive.png?raw=true)


[論文紹介ページ](https://dariopavllo.github.io/VideoPose3D/), [GitHub](https://github.com/facebookresearch/VideoPose3D)



元論文のコードでは、自分で用意した動画を使うところまでは公開されていなかったので、GitHubのissueから見つけたtobiasczさんという方の[こちらの](https://github.com/tobiascz/VideoPose3D)のコードを動かします。
基本的にはこれに従い、エラーに対応するだけです。

全体の流れとしては、まずDetectronで2Dpose推定して、そのデータをVideoPose3Dに流す、となります。

それぞれのステップは独立してるので、今回は別々に環境用意しました。（というか、Detectronで用意した環境が後半でうまく動かなかったので後半用の環境も用意しました）

#環境
Ubuntu 18.04.2 LTS
NVIDIA Driver Version: 390.116
ffmpeg4.0

#ダウンロードするものまとめ
その都度書いてありますが、最初にまとめておきます。
・[e2e_keypoint_rcnn_R-101-FPN_s1x.yaml](https://github.com/facebookresearch/Detectron/blob/master/configs/12_2017_baselines/e2e_keypoint_rcnn_R-101-FPN_s1x.yaml)
・[COCO keypointsの重みファイル](https://www.dropbox.com/sh/vi5byf0du9g50lw/AABGVezeuHuipOzaFGdGGvbaa?dl=0)
・[chackpointファイル](https://dl.fbaipublicfiles.com/video-pose-3d/d-pt-243.bin)
・data_3d_h36m.npz　（後述のコードを実行してください）

#動画とフレーム画像の用意
動画は好きなものをどうぞ。
フレームはffmpegで用意します。割愛。
ちなみにffmpegはインストールされてないと最後の可視化ができません。

#Detectron(2Dpose推定)
元はおそらくセグメンテーションですが、poseの部分だけ活用します
###Detectron用仮想環境
公式がpython2.7で動かしてるらしいので、それに従います。
Caffe2を使う関係でCUDA8, cudnn7にします。

```
conda create -n detectron python=2.7 numpy=1.16.2 matplotlib scipy yaml pyyaml=3.12 protobuf opencv
conda activate detectron
conda install -c anaconda cudatoolkit==8
conda install -c pytorch cuda80
conda install cudnn
conda install pytorch-nightly cuda80 -c pytorch #これでcaffe2が入る

#好きなディレクトリに移り
git clone https://github.com/tobiascz/VideoPose3D.git
```


###VideoPose3D/detectron_tools/　の下に以下のファイルを置きます
・用意したフレーム画像
・[e2e_keypoint_rcnn_R-101-FPN_s1x.yaml](https://github.com/facebookresearch/Detectron/blob/master/configs/12_2017_baselines/e2e_keypoint_rcnn_R-101-FPN_s1x.yaml)（[DetectronのGitHub](https://github.com/facebookresearch/Detectron)からdownload）
・[COCO keypointsの重みファイル](https://www.dropbox.com/sh/vi5byf0du9g50lw/AABGVezeuHuipOzaFGdGGvbaa?dl=0)　（もしなくなってたら[こちらを参照](https://github.com/tobiascz/VideoPose3D/issues/2)）

###Detectron実行
```
python infer_simple.py --cfg e2e_keypoint_rcnn_R-101-FPN_s1x.yaml --output-dir demo/output --image-ext jpg --wts model_final.pkl input_floder
```
input_folder(フレーム画像の場所)の中にある--image-extの拡張子の画像に対して2Dpose推定を行います。
他に指定しているのは用意したファイルとかです。
2Dposeが書かれた画像と.npzファイルが生成されるはずです。これが2Dposeデータです

![nishikori441pose.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372888/c0bed596-8e08-03fc-114c-4d503d686227.png)



#VideoPose3D　（本題）

###仮想環境構築
python2のままやろうとしたらいろいろ行き詰まったのでpython3の環境作ってしまいました。
pythonのバージョン以外はさっきと同じです。numpy1.16.3だと途中でつまるので注意してください。

```
conda create -n videopose python=3.6 numpy=1.16.2 matplotlib scipy yaml pyyaml=3.12 protobuf opencv
conda activate videopose
conda install -c anaconda cudatoolkit==8
conda install -c pytorch cuda80
conda install cudnn
conda install pytorch-nightly cuda80 -c pytorch #これでcaffe2が入る

```

### ファイルの移動
・/VideoPose3D/data/にdetectronで先程作ったdata_2d_detections.npzを置く
・/VideoPose3D/data/にdata_3d_h36m.npzを置く。これは[公式の手順](https://github.com/facebookresearch/VideoPose3D/blob/master/DATASETS.md)でダウンロードできます。以下にコピペ

```
cd data
wget https://www.dropbox.com/s/e35qv3n6zlkouki/h36m.zip
python prepare_data_h36m.py --from-archive h36m.zip
cd ..
```

・/VideoPose3D/checkpoint/ に[chackpointファイル](https://dl.fbaipublicfiles.com/video-pose-3d/d-pt-243.bin)（ダウンロードします）を置く

・/VideoPose3D/に元の動画を置く


###エラー回避のためのいろいろ

ここまでがやり方として書かれてましたが、そのままでは動かなかったので以下やったことをメモしておきます。

・run_wild.pyの66行目np.loadの中に　encoding = 'latin1'　という引数を追加

```
# こうなる
keypoints = np.load('data/data_2d_' + args.keypoints + '.npz',encoding = 'latin1')
```



・common/visualization.py　の中でffmpegのパスを通す（？）。
※自分のffmpegの場所を指定してください

```
#import文などのあとで
plt.rcParams['animation.ffmpeg_path'] =  '/usr/bin/ffmpeg'
```

### 動かす

```
python run_wild.py -k detections -arc 3,3,3,3,3 -c checkpoint --evaluate d-pt-243.bin --render --viz-subject S1 --viz-action Directions --viz-video input_video.mp4 --viz-camera 0 --viz-output output_video.mp4 --viz-size 5 --viz-downsample 1 --viz-skip 0

```
input_videoとoutput_videoの部分を![undefined]()
指定してください。他はそのままで大丈夫のはずです。

公式のデモほどきれいに一致はしていないですが、調整すればさらによくなることが議論されてはいます
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">フレームのずれを調整 <a href="https://t.co/0eSvSXHHkq">pic.twitter.com/0eSvSXHHkq</a></p>&mdash; U_Atsuhiro (@Tim23164199) <a href="https://twitter.com/Tim23164199/status/1127385740059353088?ref_src=twsrc%5Etfw">May 12, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>




# おしまい
とりあえず動かしてみました。


初記事でしたが参考になったら幸いです