• 【Unity/Kinect】手势识别Gesture


    在Unity的AssetStore官方商店下载Kinect v2 Examples案例包,参考KinectDemos/GestureDemo这个文件夹下的例子。

    自定义一个类,实现KinectGestures.GestureListenerInterface接口。参考案例中的CubeGestureListener中的用法。下面演示监听SwipeLeft向左划,SwipeRight向右划,SwipeUp向上划的手势Gesture。其中包含了一些修改界面UI显示当前手势状态等功能,如不需要可以去掉(主要是用来调试)。

    using UnityEngine;
    using System.Collections;
    using System;
    //using Windows.Kinect;
    
    public class PeopleGestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
    {
        [Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
        public int playerIndex = 0;
    
        [Tooltip("GUI-Text to display gesture-listener messages and gesture information.")]
        public GUIText gestureInfo;
    
        // singleton instance of the class
        private static PeopleGestureListener instance = null;
    
        // internal variables to track if progress message has been displayed
        private bool progressDisplayed;
        private float progressGestureTime;
    
        // whether the needed gesture has been detected or not
        private bool swipeLeft;
        private bool swipeRight;
        private bool swipeUp;
        
    
        /// <summary>
        /// Gets the singleton CubeGestureListener instance.
        /// </summary>
        /// <value>The CubeGestureListener instance.</value>
        public static PeopleGestureListener Instance
        {
            get
            {
                return instance;
            }
        }
        
        /// <summary>
        /// Determines whether swipe left is detected.
        /// </summary>
        /// <returns><c>true</c> if swipe left is detected; otherwise, <c>false</c>.</returns>
        public bool IsSwipeLeft()
        {
            if(swipeLeft)
            {
                swipeLeft = false;
                return true;
            }
            
            return false;
        }
    
        /// <summary>
        /// Determines whether swipe right is detected.
        /// </summary>
        /// <returns><c>true</c> if swipe right is detected; otherwise, <c>false</c>.</returns>
        public bool IsSwipeRight()
        {
            if(swipeRight)
            {
                swipeRight = false;
                return true;
            }
            
            return false;
        }
    
        /// <summary>
        /// Determines whether swipe up is detected.
        /// </summary>
        /// <returns><c>true</c> if swipe up is detected; otherwise, <c>false</c>.</returns>
        public bool IsSwipeUp()
        {
            if(swipeUp)
            {
                swipeUp = false;
                return true;
            }
            
            return false;
        }
        
    
        /// <summary>
        /// Invoked when a new user is detected. Here you can start gesture tracking by invoking KinectManager.DetectGesture()-function.
        /// </summary>
        /// <param name="userId">User ID</param>
        /// <param name="userIndex">User index</param>
        public void UserDetected(long userId, int userIndex)
        {
            // the gestures are allowed for the primary user only
            KinectManager manager = KinectManager.Instance;
            if(!manager || (userIndex != playerIndex))
                return;
            
            // detect these user specific gestures
            manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft);
            manager.DetectGesture(userId, KinectGestures.Gestures.SwipeRight);
            manager.DetectGesture(userId, KinectGestures.Gestures.SwipeUp);
    
            if(gestureInfo != null)
            {
                gestureInfo.text = "Swipe left, right or up to change the slides.";
            }
        }
    
        /// <summary>
        /// Invoked when a user gets lost. All tracked gestures for this user are cleared automatically.
        /// </summary>
        /// <param name="userId">User ID</param>
        /// <param name="userIndex">User index</param>
        public void UserLost(long userId, int userIndex)
        {
            // the gestures are allowed for the primary user only
            if(userIndex != playerIndex)
                return;
            
            if(gestureInfo != null)
            {
                gestureInfo.text = string.Empty;
            }
        }
    
        /// <summary>
        /// Invoked when a gesture is in progress.
        /// </summary>
        /// <param name="userId">User ID</param>
        /// <param name="userIndex">User index</param>
        /// <param name="gesture">Gesture type</param>
        /// <param name="progress">Gesture progress [0..1]</param>
        /// <param name="joint">Joint type</param>
        /// <param name="screenPos">Normalized viewport position</param>
        public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture, 
                                      float progress, KinectInterop.JointType joint, Vector3 screenPos)
        {
            // the gestures are allowed for the primary user only
            if(userIndex != playerIndex)
                return;
    
            if((gesture == KinectGestures.Gestures.ZoomOut || gesture == KinectGestures.Gestures.ZoomIn) && progress > 0.5f)
            {
                if(gestureInfo != null)
                {
                    string sGestureText = string.Format ("{0} - {1:F0}%", gesture, screenPos.z * 100f);
                    gestureInfo.text = sGestureText;
                    
                    progressDisplayed = true;
                    progressGestureTime = Time.realtimeSinceStartup;
                }
            }
            else if((gesture == KinectGestures.Gestures.Wheel || gesture == KinectGestures.Gestures.LeanLeft || 
                     gesture == KinectGestures.Gestures.LeanRight) && progress > 0.5f)
            {
                if(gestureInfo != null)
                {
                    string sGestureText = string.Format ("{0} - {1:F0} degrees", gesture, screenPos.z);
                    gestureInfo.text = sGestureText;
                    
                    progressDisplayed = true;
                    progressGestureTime = Time.realtimeSinceStartup;
                }
            }
            else if(gesture == KinectGestures.Gestures.Run && progress > 0.5f)
            {
                if(gestureInfo != null)
                {
                    string sGestureText = string.Format ("{0} - progress: {1:F0}%", gesture, progress * 100);
                    gestureInfo.text = sGestureText;
                    
                    progressDisplayed = true;
                    progressGestureTime = Time.realtimeSinceStartup;
                }
            }
        }
    
        /// <summary>
        /// Invoked if a gesture is completed.
        /// </summary>
        /// <returns>true</returns>
        /// <c>false</c>
        /// <param name="userId">User ID</param>
        /// <param name="userIndex">User index</param>
        /// <param name="gesture">Gesture type</param>
        /// <param name="joint">Joint type</param>
        /// <param name="screenPos">Normalized viewport position</param>
        public bool GestureCompleted (long userId, int userIndex, KinectGestures.Gestures gesture, 
                                      KinectInterop.JointType joint, Vector3 screenPos)
        {
            // the gestures are allowed for the primary user only
            if(userIndex != playerIndex)
                return false;
            
            if(gestureInfo != null)
            {
                string sGestureText = gesture + " detected";
                gestureInfo.text = sGestureText;
            }
            
            if(gesture == KinectGestures.Gestures.SwipeLeft)
                swipeLeft = true;
            else if(gesture == KinectGestures.Gestures.SwipeRight)
                swipeRight = true;
            else if(gesture == KinectGestures.Gestures.SwipeUp)
                swipeUp = true;
    
            return true;
        }
    
        /// <summary>
        /// Invoked if a gesture is cancelled.
        /// </summary>
        /// <returns>true</returns>
        /// <c>false</c>
        /// <param name="userId">User ID</param>
        /// <param name="userIndex">User index</param>
        /// <param name="gesture">Gesture type</param>
        /// <param name="joint">Joint type</param>
        public bool GestureCancelled (long userId, int userIndex, KinectGestures.Gestures gesture, 
                                      KinectInterop.JointType joint)
        {
            // the gestures are allowed for the primary user only
            if(userIndex != playerIndex)
                return false;
            
            if(progressDisplayed)
            {
                progressDisplayed = false;
                
                if(gestureInfo != null)
                {
                    gestureInfo.text = String.Empty;
                }
            }
            
            return true;
        }
    
        
        void Awake()
        {
            instance = this;
        }
    
        void Update()
        {
            if(progressDisplayed && ((Time.realtimeSinceStartup - progressGestureTime) > 2f))
            {
                progressDisplayed = false;
                gestureInfo.text = String.Empty;
    
                Debug.Log("Forced progress to end.");
            }
        }
    
    }

    调用方法:其他脚本获取该脚本的实例,然后通过IsSwipeLeft()等方法获取手势识别结果即可。

    PeopleGestureListener gestureListener = PeopleGestureListener.Instance;
    if (gestureListener.IsSwipeLeft())
    {
        // do something
    }

    坑点:该脚本需要被挂在Kienct Manager脚本所在的游戏物体身上!

    新手建议:如果自己写的GestureListener类 (实现KinectGestures.GestureListenerInterface接口)无论怎么测都不能识别出手势的话,可以复制KinectDemos/GestureDemo下面的例子场景(如KinectGesturesDemo1.unity),先实现能识别出手势了再根据自己的需求删改一下代码!


    参考:

  • 相关阅读:
    Linux数据备份
    eclipse 中使用等宽字体 inconsolata
    在ubuntu14.04 64位中使用jd-gui
    Fragment 常见问题
    ClassNotFoundException
    符号表的简单使用
    一个简单的词法分析器
    一个简单的语法分析器(后缀式转换)
    火狐无法显示图片
    ftp 匿名访问设置
  • 原文地址:https://www.cnblogs.com/guxin/p/unity-kinect-how-to-use-gesture.html
Copyright © 2020-2023  润新知