AIでHand Gesture対応のスマートミラー! – 検証編 –

複数記事に分けて解説しています.

AIでHand Gesture対応のスマートミラー! – 機能とセットアップ –
AIでHand Gesture対応のスマートミラー! – 作成編 –
AIでHand Gesture対応のスマートミラー! – 検証編 – 

Hand Gesture Recognitionの仕組み

MediaPipe

今回のHand Gesture RecognitionはGoogleがオープンソースで開発しているMediaPipeの1つである"Hands"を使用しています.

上図の流れでHand Gesture Recognitionを実行しています. まずはカメラを通して得た画像から手を検出し, 手を囲む四角形の座標を特定します(HandDetection). 次に, その座標をもとに画像を切り取り, 手だけが映るようにし, 手らしさを決定づける21個の座標を特定します(HandLandmark). 最後に, もともと用意をしていたジェスチャーの種類毎の座標と検出した21個の座標を照らし合わせどんなジェスチャーをしているか認識します(Cosine Distance).

HandDetection(Single Shot Detector)

HandDetectionにはSingle Shot Detector(SSD)が使用されています. SSDは物体検出でよく用いられる手法で, 物体の境界を決定します. MediaPipeではSSDによって, 画像内の手を検出します.

HandLandmark

Hand LandmarkではSSDで検出した手の画像から手を形作る特徴的な21個の点を検出します.

Cosine Distance

“Hand Landmarkで検出した21個の点"と"あらかじめ用意した既知の21個の点"からなるベクトル同士の距離(Cosine Distance)を算出し, その近さを評価します. 近ければ近いほどそのHand Gesture同士は似ているということになり, Hand Gesture Recognitionすることができます. ジェスチャーとしては, 例えば以下のようなものが用意されています.

ジェスチャーの実装や既知のベクトルの設定には以下のサイトを参考にしました.

ジェスチャー信号選び

今回のシステムとしてはTVのON/OFF, YouTubeのPlay/Pause用にジェスチャー信号を用いたいところです. 用意した10個のジェスチャーの内, 2つに絞ります.

約1分程度, カメラの前で, 動きをつけながらある一つのジェスチャーをし, Hand Gesture Recognitionした結果をCosineDistance毎に頻度計測しました. カメラの前でポーズしたジェスチャー以外にも誤検出しています. そのCosineDistanceは一定の値を取らない一方で, カメラの前でポーズしたジェスチャーのCosineDistanceは0.1-0.2の間で分布しています.

0.2以下のCosineDistanceに絞って頻度測定してみると, “palm_opened", “peace", “fist"の3つが他クラスに対する信号強度比が大きいです.

1時間程度, カメラに手をかざさずにCosineDistanceが0.2以下のものに限ってbackgroundの頻度計測をしました. “palm_opened"と"peace"に比べて"fist"の方が誤検出の頻度が高いです. こうした理由からジェスチャー信号としては"palm_opened"と"peace"を用いています.

おわり

いかがだったでしょうか、皆さんの実装の一助になれば幸いです.