はじめに

iPad ProやiPhone 11 Proのような特別なカメラでなくても手形状を認識することが、Vision Frameworkでできるようになっています。

WWDCではこちらのセッション(https://developer.apple.com/documentation/vision/detecting_hand_poses_with_vision)で紹介されました。

本記事では簡単にVision Frameworkについてセッション内容を踏まえて説明したのち、サンプルコードを参考にデモアプリを作ってみての所感を書きます。

VisionFramework

VisionframeworkはiOS11から追加されたフレームワークです。初回リリース時点では機械学習による顔検出、物体検出部分をCoreMLから抜き出したものでした。モデルが既に組み込まれているので、開発者がモデルを用意せずとも機械学習による認識を利用できる利点があります。バージョンが進むに伴ってのVision フレームワークの進歩は対象を人間に絞って挙げると以下のようになっています。

  • iOS11
    • 顔の特徴点認識実装
  • iOS12
    • VNDetectFaceRectanglesRequestで顔の回転角を取得
  • iOS13
    • VNDetectHumanRectanglesRequestで人体を矩形として認識
  • iOS14
    • VNDetectHumanHandPoseRequestで手の関節等部位認識
    • VNDetectHumanBodyPoseRequestで体の関節等部位認識

HandPose

利用の流れ

VNImageRequestHandlerに対してVNDetectHumanHandPoseRequestを与えることで手の情報をリクエストします。ResultとしてVNRecognizedPointsObservationが返されます。これは、検出した手の観測点(ランドマーク)の二次元座標を保持しています。

この観測点については framework内に記述されており、

Finger Joints Anatomy Keys follow definitions from: https://handcare.assh.org/Anatomy/Joints

https://www.assh.org/handcare/safety/jointsに準拠して作られているようです。 この点群から手形状を分類する処理を書く必要があります。

デモで行っていた処理

iOSDCのデモでは2本指を使ったお絵かきアプリが紹介されていました。公開されているコードを見ると、アプリ内では人差し指と親指の指先の距離が一定距離未満になった場合に2本指の中心に点を描画していました。

また、指先が基準値以上に離れている場合でも、バッファとして指先の座標を描画用の変数に入れつつ描画しない状態を中間状態として保持しており、これによりスムーズに線を描画することができるようです。

作成デモ

環境

  • iPhone 6s
    • iOS 14.0
  • Xcode Version 12.0

どんなアプリ?

手を1つ認識してグーチョキパーの該当する絵文字を表示するアプリ

検出方法

想定している手が3種類しかなく、今回は手の状態を大雑把に分けても問題ないと判断しました。

グー、チョキ、パーを比較した際にグーだけが中指を折り込んでいるので、中指が折り込んでいる場合、possibleStone とし、さらに親指以外の他の指が全て折り込んでいる場合にStoneとしました。

また、中指が立っていて薬指が折り込んでいる場合にpossibleScissors とし、人差し指以外が折り込んでいる場合Scissorsとしました。

上の条件のどれにも当てはまらない場合にpossiblePaper、人差し指と小指が立っている場合にPaper としました。

フローチャートで書くならこのような感じです。

状態判断フローチャート

今回のアプリでは、実はpossible~の中間層でも対応した手を表示しています。中間層を用意した理由としては以下のようになっています。

  • 今回のアプリで想定される3種をpossible段階で既に十分に切り分けられている
  • 計測状況によって観測点を見失うことがあり、完全な状態を得るのは難しい

実際に作ってみたところ特に小指が外れやすく、それだけで厳密な3状態に入ることができませんでした。

手形状認識において、全ての点を検出できない場合を想定しない完全な条件は厳しすぎると感じました。これはユーザビリティ的にも良くなく、誤検出の少なさと検出しやすさを両立できるような条件を探る必要があると思いました。

実際に使用した際の動作デモはこのようになっています。

pros and cons

pros

  • 認識用にマーカー不要で、指関節の位置をある程度精度良く認識できる
  • 指折りも手を正面にしっかり置いた場合認識される
    • 今回は細かい処理も必要ないほど単純だったので指先が第3関節と比較してどちらが上かで指折りを判断した

cons

  • 機械学習由来の検知なので、大きさの計測には単体では使えない
  • 背景色によって誤検知や検知できなくなる時がある
  • カメラに対して手が傾いている場合正しく認識されない時がある
    • 画像認識では一般的な弱点
  • Framework内で小指の表記が統一されていない( pinky↔︎little )
  • パターン毎に書かないといけないため数が増えるとコスト増

まとめ

開発者側がうまく処理を書けるなら便利に使えそうだと感じました。

既存の他ライブラリでの手形状の判断処理がそのまま流用できそうですね。移行コストはさほど高くない印象を受けました。

判断処理のテンプレートなどがAppleや外部ライブラリなどで補完されるとより普及すると思われます。

Kinectを使った位置測定などで画像認識は行ってきましたが、こんなに簡単にiPhoneのカメラを用いて関節位置推定ができるのはひとえにVision frameworkの推定モデルのおかげですね。Mediapipeなど、Handtrackingできるモデルは複数ありますので、その間での比較もなされるといいでしょうが、ひとまず触りとして本記事を書きました。iOSアプリ開発者としては気軽に使えるモデルがAppleから提供されることは非常に価値があることだと思います。