TensorFlow Liteを使用して、Androidで人間のポーズをリアルタイムで追跡する

オンデバイスインテリジェンスのためのGoogle Coralソリューション：

✅姿勢推定：さまざまな身体の関節を特定することにより、画像内の人々の姿勢を推定します。

![alt](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F448511%2F1c91ac72-82aa-82e2-5fab-691bfbe63d88.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&w=1400&fit=max&s=dd6466e244d15dbeaa980e41ec09dad1)

PoseNetは、主要な身体部分の位置を検出することにより、画像またはビデオ内の人物の姿勢を推定するビジョンモデルです。 例として、モデルは画像内の人の肘や膝の位置を推定できます。 ポーズ推定モデルは、画像内の人物を識別しません。 主要な身体部分の位置のみ。

TensorFlow Liteは、デバイスのカメラを使用してリアルタイムで1人の主要な身体部分を検出および表示するAndroidサンプルアプリケーションを共有しています。

![alt](https://miro.medium.com/max/296/1*9xLYRa4IoExmiWbpkw8rFg.gif)

このサンプルアプリケーションを使用すると、アプリ開発者や機械学習の専門家が軽量モバイルモデルの可能性を簡単に探ることができます。

##### PoseNetサンプルアプリケーション
Javaで記述された既存のAndroidサンプルとは対照的に、PoseNetサンプルアプリはKotlinで開発されました。 このアプリの開発目標は、誰でも簡単にPoseNetモデルを最小限のオーバーヘッドで使用できるようにすることでした。 サンプルアプリには、モデルの複雑さを抽象化するPoseNetライブラリが含まれています。 以下の図は、アプリケーション、PoseNetライブラリ、およびTensorFlow Liteライブラリ間のワークフローを示しています。

![alt](https://miro.medium.com/max/722/1*cAuzaEOuqTX9DJfKv6FqUg.png)

##### PoseNetライブラリ
PoseNetライブラリは、処理されたカメラ画像を取得し、人の主要な身体部位がどこにあるかに関する情報を返すインターフェースを提供します。 この機能は、推定されたRGBビットマップでTensorFlow Liteインタープリターを実行し、Personオブジェクトを返すメソッドであるtimateSinglePose（）によって提供されます。 このページでは、PoseNetの入力と出力を解釈する方法について説明します。

```

// Estimate the body part positions of a single person.
// Pass in a Bitmap and obtain a Person object.
estimateSinglePose(bitmap: Bitmap): Person {...}
```

Personクラスには、主要な身体部分の位置とそれに関連する信頼スコアが含まれています。 人の信頼スコアは、各キーポイントの信頼スコアの平均です。これは、キーポイントがその位置に存在する確率を示します。

```
// Person class holds a list of key points and an associated confidence score.
class Person {
  var keyPoints: List<KeyPoint> = listOf<KeyPoint>()
  var score: Float = 0.0f
}
```

各KeyPointは、特定のBodyPartの位置とそのキーポイントの信頼スコアに関する情報を保持します。

```
// KeyPoint class holds information about each bodyPart, position, and score.
class KeyPoint {
  var bodyPart: BodyPart = BodyPart.NOSE
  var position: Position = Position()
  var score: Float() = 0.0f
}

// Position class contains the x and y coordinates of a key point on the bitmap. 
class Position {
  var x: Int = 0
  var y: Int = 0
}

// BodyPart class holds the names of seventeen body parts.
enum class BodyPart {
  NOSE, 
  LEFT_EYE, 
  RIGHT_EYE, 
  ... 
  RIGHT_ANKLE
}
```

#####PoseNetサンプルアプリ
PoseNetサンプルアプリは、カメラからフレームをキャプチャし、画像上のキーポイントをリアルタイムでオーバーレイするデバイス上のカメラアプリです。
アプリケーションは、着信カメラ画像ごとに次の手順を実行します。

- カメラプレビューから画像データをキャプチャし、YUV_420_888からARGB_888形式に変換します。
- RGB形式のフレームデータのピクセルを保持するBitmapオブジェクトを作成します。 モデルに渡すことができるように、ビットマップを切り取ってモデルの入力サイズに合わせます。
- PoseNetライブラリーのtimateSinglePose（）関数を呼び出して、Personオブジェクトを取得します。
- ビットマップを画面サイズに戻します。 Canvasオブジェクトに新しいビットマップを描画します。
- Personオブジェクトから取得したキーポイントの位置を使用して、キャンバスにスケルトンを描画します。 特定のしきい値（既定では0.5）を超える信頼スコアを持つキーポイントを表示します。

ポーズレンダリングをカメラフレームと同期するために、ポーズとカメラの個別のViewインスタンスの代わりに、単一のSurfaceViewが出力表示に使用されました。 SurfaceViewは、Viewキャンバスを取得、ロック、およびペイントすることにより、画面を遅滞なく画面上に配置します。

##### デバイス上で実行する
GitHubからソースコードをダウンロードし、READMEを参照して実行方法を確認して、アプリを試してみることをお勧めします。

##### ロードマップ上
将来的には、このサンプルアプリのその他の機能を検討していきたいと考えています。
- マルチポーズ推定
- GPUデリゲートを使用したGPUアクセラレーション
- NNAPIデリゲートを使用したNNAPIアクセラレーション
- レイテンシを減らすためのモデルのトレーニング後の量子化
- ResNet PoseNetモデルなどの追加のモデルオプション

(Eileen MaoとTanjin Prity、Googleのエンジニアリング実習インターン)

![alt](https://qiita-user-contents.imgix.net/https%3A%2F%2F1.bp.blogspot.com%2F-YR5hB3S-gTk%2FXkIrTp3h2YI%2FAAAAAAAAAH8%2F9tyUuSKpAUcoq0Psp4jph_1tu8hPz12hgCLcBGAsYHQ%2Fs640%2F%2525E6%2525AD%2525A3%2525E6%252596%2525B9%2525E5%2525BD%2525A2%2525E6%2525B5%2525B7%2525E6%25258A%2525A5.jpg?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&w=1400&fit=max&s=c34474b63150b2966ca080f6c5c25fd2)

Google Coral海外代理店：Gravitylink (https://store.gravitylink.com/global)