見出し画像

Niantic Lightship ARDK の ハンドトラッキングの実装〜検証まで

OnePlanet XR について

OnePlanet XR というAR/MR技術に専門特化したコンサルティングサービスです。豊富な実績を元に、AR/MR技術を活用した新たな事業の立ち上げ支援や、社内業務のデジタル化/DX推進など、貴社の必要とするイノベーションを実現いたします。

弊社では、Niantic Lightship ARDKを使ったアプリケーションの開発を行っており、サンフランシスコと日本で開催されたNiantic主催のLightship Summitの会場でアプリケーションの動画を流していただきました。

ご相談から受け付けております。ご興味ございましたらお問い合わせください。

https://1planet.co.jp/xrconsulting.html

Niantic Lightship ARDK ハンドトラッキングについて

Lightship ARDK v2.2.0 のリリース時に導入されたハンドトラッキングは、手の平を検出をリアルタイムで行われ、検出されると手の位置とサイズを取得できます。(本機能は実験的な機能なため、リリースを前提にしたアプリケーションの組み込みは推奨していないようです。)


開発環境と動作環境

以下の動作環境を検証を実施しました。

  • iPhone 12 Pro (iOS 15.6)

  • Unity Editor 2020.3.28f1

  • ARDK v2.3.0


開発手順

1. AR Scene Manager をヒエラルキーに配置

2. AR Scene Camera に AR Hand Tracking Manager を追加

3.Hand Tracking の位置と大きさを表示するコンポーネントの作成

手のひらと大きさを表示するためのGame Objectをヒエラルキーに作成。作成したGame Objectにスクリプトを新たに追加します。(スクリプトは以下。)



using System;
using System.Collections.Generic;
using ARDK.Extensions;
using Niantic.ARDK.AR.Awareness;
using UnityEngine;

public class HandTrackingVisualiser:
    MonoBehaviour
  {
    [SerializeField]
    private ARHandTrackingManager _handTrackingManager = null;

    private IReadOnlyList<Detection> _detections;

    private Texture2D _lineTexture;
    private GUIStyle _fontStyle;

    private const int LineThickness = 10;
    private static readonly Color LineColor = Color.yellow;
    private const int TextSize = 100;
    private static readonly Color TextColor = Color.white;

    private void Start()
    {
      _handTrackingManager.HandTrackingUpdated += OnHandTrackingUpdated;

      _lineTexture = new Texture2D(1, 1);
      _lineTexture.SetPixel(0, 0, LineColor);
      _lineTexture.Apply();
      
      _fontStyle = new GUIStyle();
      _fontStyle.fontSize = TextSize;
      _fontStyle.normal.textColor = TextColor;      
    }

    private void OnDestroy()
    {
      _handTrackingManager.HandTrackingUpdated -= OnHandTrackingUpdated;
    }

    private void OnHandTrackingUpdated(HumanTrackingArgs args)
    {
      _detections = args.TrackingData?.AlignedDetections;
    }

    void OnGUI()
    {
      if (_detections == null)
      {
        return;
      }
      foreach (var detection in _detections)
      {
        // Float rectangle to screen position
        var detectionPos = new Vector3(detection.Rect.x, detection.Rect.y, 0);
        var origin = Camera.main.ViewportToScreenPoint(detectionPos);

        var detectionSize = new Vector3(detection.Rect.width, detection.Rect.height, 0);
        var extent = Camera.main.ViewportToScreenPoint(detectionSize);

        var rect = new Rect(origin.x, origin.y, extent.x, extent.y);

        // Draw the lines
        Rect r = rect;
        r.height = LineThickness;
        GUI.DrawTexture(r, _lineTexture);
        r.y += rect.height - LineThickness;
        GUI.DrawTexture(r, _lineTexture);

        r = rect;
        r.width = LineThickness;
        GUI.DrawTexture(r, _lineTexture);
        r.x += rect.width - LineThickness;
        GUI.DrawTexture(r, _lineTexture);

        var score = Math.Round(detection.Confidence * 1000) / 10f;
        GUI.Label
        (
          new Rect(rect.x + 20, rect.y + 20, rect.width, rect.height),
          "Score: " + score + "%",
          _fontStyle
        );
      }
    }
}

実装ポイント


ハンドトラッキングの更新イベント

_handTrackingManager.HandTrackingUpdated += OnHandTrackingUpdated;

・ハンドトラッキングデータの取得
AlignedDetectionsに位置、大きさ、精度の情報を持つハンドトラッキングのデータ、Detectionが検出した数だけ格納されています。(最大で15個まで検出可能。)

private void OnHandTrackingUpdated(HumanTrackingArgs args)
{
  _detections = args.TrackingData?.AlignedDetections;
}

検証結果

  1. 前半は左右の手を同時にトラッキングの検証を実施。トラッキングのスピードも申し分ない精度。

  2. ビニール袋も手のひらとして認識される時がある。スコアは50%ほど。

  3. 沢山の手が載っている画像で検証した結果、全ての手は認識しなかったが、7~8個を同時に認識することができた。

まとめ

実験レベルではあるものの、ハンドトラッキングの精度はパフォーマンスはかなり良かったように思います。ちなみにNiantic Lightship ARDK の ハンドトラッキングの機械学習モデルはMediaPipe社のモデルを使用しています。(実験的な機能なため、当機能は大幅に変更される場合があります。)