LoginSignup
8

More than 5 years have passed since last update.

UnityとRealSenseで手(指関節)の認識

Last updated at Posted at 2017-06-04

色々怪しい所が見え始めてくるRealSenseのHandModuleですが、
新しい情報はあまり公開されてないようなので、一例と思い、タイトル通りの記事を投稿します。

Version
Unity:5.6.1f1 Personal
RealSenseSDK:2016 R3
Device:SR300

動かし方
空のシーンを作ってカメラに下のコードをコピペして作ったスクリプトをアタッチするだけです。

using System;
using System.Collections.Generic;
using UnityEngine;
using Intel.RealSense;
using Intel.RealSense.Hand;

public class HandTest : MonoBehaviour
{
    SenseManager SenseM;
    HandModule HandM;
    HandData HandD;

    List<GameObject> PointsL = new List<GameObject>();
    List<GameObject> PointsR = new List<GameObject>();
    List<JointData> JointsL = new List<JointData>();
    List<JointData> JointsR = new List<JointData>();

    float SphereSize = 0.03f;

    void Start()
    {
        int n = Enum.GetNames(typeof(JointType)).Length;
        for (int i = 0; i < n; i++)
        {
            var goL = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            var goR = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            goL.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);
            goR.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);
            PointsL.Add(goL);
            PointsR.Add(goR);
            JointsL.Add(new JointData());
            JointsR.Add(new JointData());
        }

        SenseM = SenseManager.CreateInstance();
        HandM = HandModule.Activate(SenseM);
        HandM.FrameProcessed += Hand_FrameProcessed;
        HandD = HandM.CreateOutput();
        SenseM.Init();
        SenseM.StreamFrames(false);
    }

    private void Hand_FrameProcessed(object sender, FrameProcessedEventArgs args)
    {
        HandD.Update();
        IHand[] hand;
        if (HandD.QueryHandData(AccessOrderType.ACCESS_ORDER_BY_ID, out hand) == Status.STATUS_NO_ERROR)
        {
            foreach (IHand h in hand)
            {
                int n = Enum.GetNames(typeof(JointType)).Length;
                if (h.BodySide == BodySideType.BODY_SIDE_LEFT)
                {
                    for (int i = 0; i < n; i++)
                    {
                        var jt = (JointType)Enum.ToObject(typeof(JointType), i);
                        JointsL[i] = h.TrackedJoints[jt];
                    }
                }
                if (h.BodySide == BodySideType.BODY_SIDE_RIGHT)
                {
                    for (int i = 0; i < n; i++)
                    {
                        var jt = (JointType)Enum.ToObject(typeof(JointType), i);
                        JointsR[i] = h.TrackedJoints[jt];
                    }
                }
            }
        }
    }

    void Update()
    {
        int n = Enum.GetNames(typeof(JointType)).Length;
        for (int i = 0; i < n; i++)
        {
            PointsL[i].transform.position = JointsL[i].positionWorld;
            PointsR[i].transform.position = JointsR[i].positionWorld;
        }
    }

    void OnDestroy()
    {
        HandM.FrameProcessed -= Hand_FrameProcessed;
        HandD.Dispose();
        SenseM.Dispose();
    }
}

※怪しいポイント※
・MIRROR_MODE_HORIZONTALを適用すると認識がおかしくなる。
・TRACKING_MODE_FULL_HANDを適用しなくても何故か動いてしまう。
・HandConfigurationの値をデバッガで見ても信用ならない。

参考
https://software.intel.com/sites/landingpage/realsense/camera-sdk/v2016r3/documentation/html/index.html?doc_devguide_introduction.html

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8