Google ColabでVideoPose3Dを動かしてみた

[JustinemmerichさんのJupyter Notebook](https://github.com/Justinemmerich/VideoPose3D/blob/master/Notebook/Facebook_VideoPose3D_Inference_in_the_wild_Detectron.ipynb)を参考にして、**Google Colab**上で、**VideoPose3D**を動かしてみましたので、メモとして残します。

そのまえに、簡単に、VideoPose3Dを整理します。

## [VideoPose3D](https://github.com/facebookresearch/VideoPose3D) とは
[Detectron](https://github.com/facebookresearch/Detectron) という 2Dの [Human Pose Estimation](https://qiita.com/KYoshiyama/items/9f5f5a13f957e138380b) のデータを元に、動画ファイルから3Dの関節の位置情報を推定するもの

##導入の前提
[Python3のディストリビューション](https://ja.wikipedia.org/wiki/Anaconda_(Python%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3))、[PyTorch](https://ja.wikipedia.org/wiki/PyTorch)（コンピュータビジョンや自然言語処理で利用されているTorchを元に作られた、**Pythonのオープンソースの機械学習ライブラリ**）が必要

## 導入手順 ##
#### 1. GPUの準備（Google Colab でGPUを利用できるようにする）（以下のサイトを参考）
- [【秒速で無料GPUを使う】TensorFow(Keras)/PyTorch/Chainer環境構築 on Colaboratory](https://qiita.com/tomo_makes/items/f70fe48c428d3a61e131)

#### 2. Pytorch と Caffe2 を導入 （以下手順で、CUDA, cuDNNも併せて導入される）
```
!wget https://anaconda.org/pytorch/pytorch/1.2.0/download/linux-64/pytorch-1.2.0-py3.6_cuda10.0.130_cudnn7.6.2_0.tar.bz2
!tar xvjf pytorch-1.2.0-py3.6_cuda10.0.130_cudnn7.6.2_0.tar.bz2
!cp -r lib/python3.6/site-packages/* /usr/local/lib/python3.6/dist-packages/
```

#### 3. Caffe2 環境が構築されているかの確認
```
# To check if Caffe2 build was successful
!python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"
# To check if Caffe2 GPU build was successful
!python -c 'from caffe2.python import workspace; print(workspace.NumCudaDevices())'
```

#### 4. [COCOデータセット（画像を扱う機械学習のためのデータセットの一つ）](https://qiita.com/leetmikeal/items/7c0d23e39bf38ab8be23)の導入
```
!apt-get install python-dev
!pip install cython
!pip install pycocotools
!git clone https://github.com/cocodataset/cocoapi.git
!cd cocoapi/PythonAPI && make install

import os
os.environ['COCOAPI'] = ":/content/cocoapi"
```

#### 5. Detectron の導入
```
!rm -r detectron
!git clone https://github.com/facebookresearch/detectron
!pip install -r detectron/requirements.txt
!cd detectron && make
!python detectron/detectron/tests/test_spatial_narrow_as_op.py
```

#### 6. VideoPose3D の導入 & Video Script を Detectron Tools Folder へコピー
```
!rm -r VideoPose3D
#copy file from VideoPose3d
!git clone https://github.com/facebookresearch/VideoPose3D
!cp VideoPose3D/inference/infer_video.py detectron/tools/infer_video.py
```

#### 7. Pretrained Human3.6m Coco Model をダウンロード
```
!mkdir VideoPose3D/checkpoint
os.chdir('VideoPose3D/checkpoint')
!wget https://dl.fbaipublicfiles.com/video-pose-3d/pretrained_h36m_detectron_coco.bin
os.chdir('../..')
```

#### 8. 3D Pose Estimation 用のビデオを用意
Youtubeから取得して特定部分を切り取る
今回、**フジテレビ SPORTS**でUpされていた、[【圧巻の演技!】紀平梨花選手＜女子ショートプログラム／四大陸フィギュアスケート選手権2020 in 韓国＞ノーカット配信](https://www.youtube.com/watch?v=lVHkKpHTV3k)を利用しました。

```
YOUTUBE_ID ='lVHkKpHTV3k'

!pip install -q youtube-dl
#download video

!rm youtube.mp4
!youtube-dl -f 'bestvideo[ext=mp4]' --output "youtube.%(ext)s" https://www.youtube.com/watch?v=$YOUTUBE_ID

!rm -r videos
!mkdir videos   
  
# cut the first 5 seconds
!ffmpeg -y -loglevel info -i youtube.mp4 -ss 00:00:53 -t 00:00:10 videos/video.mp4
```

#### 9. Detectron を用いて2D座標を計算
```
!rm -r output
!mkdir output
!python detectron/tools/infer_video.py \
    --cfg detectron/configs/12_2017_baselines/e2e_keypoint_rcnn_R-101-FPN_s1x.yaml \
    --output-dir output \
    --image-ext mp4 \
    --wts https://dl.fbaipublicfiles.com/detectron/37698009/12_2017_baselines/e2e_keypoint_rcnn_R-101-FPN_s1x.yaml.08_45_57.YkrJgP6O/output/train/keypoints_coco_2014_train:keypoints_coco_2014_valminusminival/generalized_rcnn/model_final.pkl \
   videos    
```

#### 10. VideoPose3Dの入力に合わせたDetectronの出力を用意
```
!rm -r ./VideoPose3D/data/detectronoutput
!mkdir ./VideoPose3D/data/detectronoutput
!cp output/video.mp4.npz VideoPose3D/data/detectronoutput/video.mp4.npz
os.chdir('VideoPose3D/data') # This script must be launched from the "data" directory
!python prepare_data_2d_custom.py -i detectronoutput -o myvideos
os.chdir('../../')
```

#### 11. VideoPose3Dを使用して3Dジョイントを計算
```
# 以下2.2で実施しないと失敗する
!pip install matplotlib==2.2
!rm -r VideoPose3D/video.mp4
!cp ./videos/video.mp4 VideoPose3D/video.mp4
os.chdir('VideoPose3D')
!python run.py -d custom -k myvideos -arc 3,3,3,3,3 -c checkpoint --evaluate pretrained_h36m_detectron_coco.bin --render --viz-subject video.mp4 --viz-action custom --viz-camera 0 --viz-video video.mp4 --viz-output output.mp4 --viz-export outputfile --viz-size 6
```

#### 12. 結果の表示（ジョイントのエクスポート）
```
#inspect joints export 

import numpy as np
data  = np.load('outputfile.npy')
lst = data
for item in lst:
    print(item)
```

#### 13. 結果の表示（ジョイントビデオ）
```
#display video
def show_local_mp4_video(file_name, width=640, height=480):
  import io
  import base64
  from IPython.display import HTML
  video_encoded = base64.b64encode(io.open(file_name, 'rb').read())
  return HTML(data='''<video width="{0}" height="{1}" alt="test" controls>
                        <source src="data:video/mp4;base64,{2}" type="video/mp4" />
                      </video>'''.format(width, height, video_encoded.decode('ascii')))

show_local_mp4_video('output.mp4', width=960, height=720)
```

#### 14. ジョイントビデオのダウンロード
```
from google.colab import files
files.download('output.mp4')
files.download('outputfile.npy')
```

##参考サイト
-[VideoPose3Dを動かしてみた（Detectronから）](https://qiita.com/timtoronto634/items/ee018ac89e6b9f779194)
-[Google Colab リセットポイントのメモ](https://qiita.com/samacoba/items/56919806c2e8c840a71c)
-[GPU マシンを Google Colaboratory のランタイムとして利用する](https://qiita.com/hoto17296/items/22e8a4d24f21b90013f3)