Pythonパッケージ版のMediaPipeが超お手軽 + 簡易なMLPで指ジェスチャー推定

* この記事は[TensorFlow Advent Calendar 2020](https://qiita.com/advent-calendar/2020/tensorflow)の9日目の記事です。

# MediaPipe(Pythonパッケージ版)
**Pythonパッケージ版のMediaPipeが超お手軽です。**

```bash
pip install mediapipe
```
pipでインストールして、、、


```python
import mediapipe as mp
```
importして、、、

```python
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5,
)
```

インスタンス作って、、、

```python
image = cv2.imread('XXXXXXXX.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = hands.process(image)
```
process()に画像投げ込んだら、手のランドマークをゲット🦔！
<img src="https://user-images.githubusercontent.com/37477845/101514487-a59d8500-39c0-11eb-8346-d3c9ab917ea6.gif" width=80%>
※別途、描画処理が必要です。

CPU動作でもかなり早い！
むしろGPU対応していない気がする（ドキュメントのどっかに非対応な旨が書いてあるはあず、、、

# MediaPipe(Pythonパッケージ版)がサポートする機能(2020/12/17時点)
Pythonパッケージ版のMediaPipeは、現時点で以下の4機能をサポートしています。

[Hands](https://google.github.io/mediapipe/solutions/hands)
<img src="https://user-images.githubusercontent.com/37477845/101514487-a59d8500-39c0-11eb-8346-d3c9ab917ea6.gif" width=50%>
[Pose](https://google.github.io/mediapipe/solutions/pose)
<img src="https://user-images.githubusercontent.com/37477845/101512555-7ab23180-39be-11eb-814c-9fad59e0cf9a.gif" width=50%>
[Face Mesh](https://google.github.io/mediapipe/solutions/face_mesh)
<img src="https://user-images.githubusercontent.com/37477845/101512592-869df380-39be-11eb-8a80-241e272cc195.gif" width=50%>
[Holistic(Pose, Face Mesh, Handsを一度に推定)](https://google.github.io/mediapipe/solutions/holistic)
<img src="https://user-images.githubusercontent.com/37477845/101908209-1336f480-3bff-11eb-9f3f-5a3055821ebd.gif" width=50%>

# MediaPipe(Pythonパッケージ版)サンプルプログラム
上記のサンプルプログラムは以下で公開しています。
<a href="https://github.com/Kazuhito00/mediapipe-python-sample"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/Kazuhito00/mediapipe-python-sample.png" width="460px"></a>

# おまけ：簡易なMLPで指ジェスチャー推定
あまりにも簡単に手のランドマークが取れるようになったので、
簡易なMLPと組み合わせて、以下のようなプログラムも作ってみました。
せっかくMediaPipe自体の動作が早いので、なるべく邪魔しないようにTensorflow-Lite
で作っています。

手のランドマーク座標を入力に3分類(パー、グー、指差し)するモデルと、
指差し時の軌跡を入力に4分類(静止、時計回り、反時計回り、移動)するモデルを
組み合わせて動かしています。
![Finger Gesture Demo](https://user-images.githubusercontent.com/37477845/102222442-c452cd00-3f26-11eb-93ec-c387c98231be.gif)

### 「パー」「グー」「指差し」の分類

![hand_landmarks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140207/2ab2ab0d-7183-dad7-12bc-a079b8d4c364.png)
手のランドマークのIDはこんな感じ↑なので、、、

![preprocess1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140207/a25df62f-cccb-a8a8-63e7-1c2733704d05.png)
こんな感じに前処理して、、、（ID:0が最終的に0,0になっているの少々無駄ですが、、、）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140207/55386a27-205e-6541-9b48-bd911f1c5256.png" width=75%>
こんな感じの簡易なMLPにぶち込んでます🦔

### 「静止」「時計回り」「反時計回り」「移動」の分類
![preprocess2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140207/6d43e2ba-8865-d99d-3064-41f8a3763b2b.png)
人差指の座標履歴を16点ほど取って、こんな感じに前処理して、、、（T-15が最終的に0,0になっているの少々無駄ですが、、、）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140207/c8faf618-86c0-d197-17ec-17d88abe17c5.png" width=75%>
こんな感じの簡易なMLPにぶち込んでます🦔

# プログラム
上記のプログラムもGithubで公開しています。
適当MLPなので、もっとイカした構造にすると、もっと精度が上がります🦔
<a href="https://github.com/Kazuhito00/hand-gesture-recognition-using-mediapipe"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/Kazuhito00/hand-gesture-recognition-using-mediapipe.png" width="460px"></a>