スポーツがうまくなりたい・・・そうだ、姿勢推定してうまい人との差を取れれば・・・！！　～初級編：colaboratory、openposeで簡単動画の姿勢推定～

# はじめに
ボルダリングを始めたが全く上手くならない…そうだ！！姿勢推定して他の人と比べて悪いところを具体的に見える形にすれば良いんだ！

というところから、まずはcolaboratoryで姿勢推定（openpose）をやってみようとなりました。

動画リンク結果↓（全然推定できてない。。。）
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/GIaGO8RIuIs/0.jpg)](http://www.youtube.com/watch?v=GIaGO8RIuIs)

# システム構成
今回のシステム構成はこんな感じです。
主に使用するのは、Google Driveとgoogle colaboratoryのみです。
すべてクラウド上なので、ブラウジング用の貧弱なパソコンさえあればOKです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/2af75582-1108-ea30-f46c-f20d5bc0b390.png)

Tips：colaboratoryとは？
無料で使うことができ、ほとんどの主要ブラウザで動作する、設定不要のJupyterノートブック環境です。 Googleが、機械学習の教育、研究用に使われることを目的に、無償提供しています。
引用：[秒速で無料GPUを使う】深層学習実践Tips on Colaboratory](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)

# では、さっそく実装しましょう。
今回は、下記記事の内容を主に参考にしております。@nanako_ut様感謝します。
[tensorflow（tf-openpose）で画像から骨格推定](https://qiita.com/nanako_ut/items/974466acf065b95f984a)

手っ取り早くコードを見たい方は、下記をどうぞ！
https://github.com/sugupoko/OpenPose_movie/blob/master/OpenPose_movie.ipynb

## Colaboratoryにアクセス！（初めての方向け）
まずは、このURLアクセスしてみてください。
https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja

そして、”ファイル→python3の新しいノートブック”をクリックしてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/5ec9bfa7-6824-a020-bf90-5fda3b82f4b1.png)

そうすると、下記のような新しいページが表示されます。
これで準備OKです！

ここにコードを記述して、”Shift+enter”でpythonスクリプトを簡単に実行できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/9535b23a-f276-fb7d-497d-aaeff1d07e64.png)

## さあ、開発環境整備しましょう
Openposeを動作させるためには、５つの作業が必要となります。

~~~OpenPose_movie.ipynb
# SWIG を準備
!apt-get -q -y install swig

# TF-openposeをクローン
!git clone https://www.github.com/ildoonet/tf-openpose

#  ------- 変更点：ここから 挿入 ------- 
# クローンしたディレクトリに入る
%cd tf-openpose
#  ------- 変更点：ここまで 挿入 ------- 

# openpose動作のための、ライブラリをインストール
!pip3 install -r requirements.txt

# Openposeのモデルをダウンロード
%cd models/graph/cmu
!bash download.sh
%cd ../../../

# pafprocessをインストール
%cd tf_pose/pafprocess
!ls
!swig -python -c++ pafprocess.i && python3 setup.py build_ext --inplace
%cd ../../
~~~

# 実験！！
## まずは、静止画で実験してみる。
こんなのができれば成功です！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/d27aa8c9-56cb-eeac-fba3-125741e3b83f.png)

~~~OpenPose_movie.ipynb
# ネットから画像DL
!wget https://www.pakutaso.com/shared/img/thumb/150415022548_TP_V.jpg

# 実行！！
%run -i run.py --model=mobilenet_thin --resize=432x368 --image=150415022548_TP_V.jpg
~~~

## 続いて、動画で実行
ここに一癖あったので、ちょっと苦労しました。

### まずは、Googleドライブから動画を読み込むための作業
下記のコードを実行。

~~~py:OpenPose_movie.ipynb
from google.colab import drive
drive.mount('./gdrive')
drive_root_dir="./gdrive/My Drive/Colab Notebooks/"
~~~

URLにアクセスし次へを連打していくとURLがまた表示されるので、それを入力。
こんな画面が出ればOK。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/841f10cb-5033-e85a-56d8-9985732361c1.png)

### Googleドライブからcolabへ動画をコピー
下記のようなコマンドを入力することで、コピーすることができます。ディレクトリは個々で異なるので、置いてある動画の場所に応じて変更してください。

~~~OpenPose_movie.ipynb
!cp './gdrive/My Drive/Colab Notebooks/movies/climbing2.mp4' "./"
~~~

### 最後に、実行です！！
もとからある、run_video.pyだとうまく実行できなかったので、スクリプトを改造し実行しちゃいます。
ちょっとややこしいのが、DNNに入力するサイズは16の倍数を前提としているところです。
なのでスクリプト中では、Wは540 -> 544に変更しています。ただし動画を保存するときは、元のサイズで！

~~~py:OpenPose_movie.ipynb
import argparse
import logging
import time
import os

import cv2
import numpy as np
import matplotlib.pyplot as plt

from tf_pose import common
from tf_pose.estimator import TfPoseEstimator
from tf_pose.networks import get_graph_path, model_wh

movie_name = 'climbing2'

img_outdir = './img'
os.makedirs(img_outdir, exist_ok=True)

# 動画作成
fourcc = cv2.VideoWriter_fourcc('m','p','4', 'v')
video  = cv2.VideoWriter('ImgVideo2.mp4', fourcc, 30.0, (540, 960))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='tf-pose-estimation Video')
    
    outimg_files = []
    count = 0
    w = 544 
    h = 960
    e = TfPoseEstimator(get_graph_path('mobilenet_thin'), target_size=(w, h))
    
    # 動画出力先
    cap = cv2.VideoCapture('climbing2.mp4')

    # 動画用の画像作成
    while True:
        ret, image = cap.read()
        
        if ret == True:
            # １フレームずつ処理
            count += 1
            if count % 100 == 0:
                print('Image No.：{0}'.format(count))
            
            humans = e.inference(image, resize_to_default=(w > 0 and h > 0), upsample_size=4)
            image = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)
            
            # 画像出力
            outimg_file = '{}/{:05d}.jpg'.format(img_outdir, count)
            cv2.imwrite(outimg_file, image)
            video.write(image)       
            
        else:
            break
    video.release()
~~~

### 最後に保存
最後にGoogleドライブのコピーで終了です。

~~~OpenPose_movie.ipynb
!cp './ImgVideo2.mp4' "./gdrive/My Drive/Colab Notebooks/movies/"
~~~



# まとめ
OpenPoseで全然推定できなかったので、どう改善していくか考えなきゃいけません。。。
例えば、データセットを増やすとか？（いやいや厳しい。。。）

下記の記事のように野球のスイングだと取れているんですけどねぇ。。。
https://qiita.com/nanako_ut/items/1a9ce5d4eca672b38d2d

良いアイデアや、論文を知っている方募集しています！！

とはいえ、
姿勢推定のハードルは高くないので、みなさん試しにやってみましょう！！
python, colaboratoryの初心者でも数時間でできちゃいます。