zoukankan      html  css  js  c++  java
  • kinect笔记 三、识别手型(手部位置和手势)

    在unity中获取手的位置

    创建一个空物体,命名为KinectManager,给该物体绑定上KinectManager 和 InteractionManager脚本

    其中InteractionManager脚本上有三个纹理,Grip Hand Texture 是握拳,Release Hand Texture是手摊开的状态,Normal Hand Texture理论上应该是手呈半握状态并且其中的个别手指摊开,但是我从没有触发过

    再新建一个空物体,命名为InteractionListener,新建一个脚本MyInteractionListener,这个脚本需要跟摄像机和InteractionManager相关联,但是InteractionManager可以用kinect的属性获取,所以只需要将摄像机拖拽到脚本上关联即可

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MyInteractionListener : MonoBehaviour ,InteractionListenerInterface{
    
        [Tooltip("Camera used for screen ray-casting. This is usually the main camera.  用于屏幕光线投射的照相机。这通常是主相机。")]
        public Camera screenCamera;
        
        //[Tooltip("Interaction manager instance, used to detect hand interactions. If left empty, it will be the first interaction manager found in the scene.")]
        [Tooltip("交互管理器实例,用于检测手交互。如果为空,它将是场景中发现的第一个交互管理器")]
        public InteractionManager interactionManager;
        
        // hand interaction variables   手的交互变量
        private InteractionManager.HandEventType lastHandEvent = InteractionManager.HandEventType.None;
    
        // normalized and pixel position of the cursor  鼠标光标的统一化和位置
        private Vector3 screenNormalPos = Vector3.zero;
        private Vector3 screenPixelPos = Vector3.zero;
        private Vector3 newObjectPos = Vector3.zero;
    
    
        /*[Tooltip("Minimum Z-position of the dragged object, when moving forward and back.")]
        public float minZ = 0f;
    
        [Tooltip("Maximum Z-position of the dragged object, when moving forward and back.")]
        public float maxZ = 5f;*/
    
    
        /// <summary>
        /// UDP客户端
        /// </summary>
        public UDPClient udpClient;
    
        // Use this for initialization
        void Start () {
            //默认情况下,将主相机设置为屏幕摄像机
            if (screenCamera == null)
            {
                screenCamera = Camera.main;
            }
            // 获取交互管理器实例
            if (interactionManager == null)
            {
                interactionManager = InteractionManager.Instance;
            }
        }
    
        // Update is called once per frame
        void Update () {
            //如果交互管理器不为空,并且已经初始化
            if (interactionManager != null && interactionManager.IsInteractionInited())
            {
    
                // check if there is an underlying object to be selected    检查是否存在要选择的基础对象
                if (lastHandEvent == InteractionManager.HandEventType.Grip && screenNormalPos != Vector3.zero)
                {
                    // convert the normalized screen pos to pixel pos   将标准化屏幕POS转换为像素POS
                    screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();
    
                    screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
                    screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
                    Ray ray = screenCamera ? screenCamera.ScreenPointToRay(screenPixelPos) : new Ray();
    
                    // check if there is an underlying objects  检查是否存在底层对象
                    RaycastHit hit;
    
                    Debug.Log("握拳");
                    Debug.Log(screenPixelPos);
                    //udpClient.SocketSend(screenPixelPos.x + "," + screenPixelPos.y);
                    //udpClient.SocketSend(screenNormalPos.x + "," + screenNormalPos.y);
                    //udpClient.SocketSend(screenNormalPos.x.ToString("f2") + "," + screenNormalPos.y.ToString("f2"));//f2保留两位小数
                    //udpClient.SocketSend("anXia");
                    if (Physics.Raycast(ray, out hit))
                    {
                        Debug.Log("位置");
                        Debug.Log(hit.point);
                        /*foreach (GameObject obj in draggableObjects)
                        {
                            if (hit.collider.gameObject == obj)
                            {
                                // an object was hit by the ray. select it and start drgging
                                draggedObject = obj;
                                draggedObjectOffset = hit.point - draggedObject.transform.position;
                                draggedObjectOffset.z = 0; // don't change z-pos
    
                                draggedNormalZ = (minZ + screenNormalPos.z * (maxZ - minZ)) -
                                    draggedObject.transform.position.z; // start from the initial hand-z
    
                                // set selection material
                                draggedObjectMaterial = draggedObject.GetComponent<Renderer>().material;
                                draggedObject.GetComponent<Renderer>().material = selectedObjectMaterial;
    
                                // stop using gravity while dragging object
                                draggedObject.GetComponent<Rigidbody>().useGravity = false;
                                break;
                            }
                        }*/
                    }
                }
                else
                {
    
                    // continue dragging the object 继续拖动对象
                    screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();
    
                    // convert the normalized screen pos to 3D-world pos    将标准化的屏幕POS转换为3D世界POS
                    screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
                    screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
                    /*//screenPixelPos.z = screenNormalPos.z + draggedObjectDepth;
                    screenPixelPos.z = (minZ + screenNormalPos.z * (maxZ - minZ)) - draggedNormalZ -
                        (screenCamera ? screenCamera.transform.position.z : 0f);*/
    
    
                    //Debug.Log("手掌");
                    //Debug.Log(screenPixelPos);
                    //udpClient.SocketSend(screenPixelPos.x + "," + screenPixelPos.y);
                    //udpClient.SocketSend(screenNormalPos.x + "," + screenNormalPos.y);
                    //udpClient.SocketSend(screenNormalPos.x.ToString("f2") + "," + screenNormalPos.y.ToString("f2"));
                    //udpClient.SocketSend("taiQi");
                    //newObjectPos = screenCamera.ScreenToWorldPoint(screenPixelPos) - draggedObjectOffset;
    
                    // check if the object (hand grip) was released
                    /*bool isReleased = lastHandEvent == InteractionManager.HandEventType.Release;
    
                    if (isReleased)
                    {
                        // restore the object's material and stop dragging the object
                        draggedObject.GetComponent<Renderer>().material = draggedObjectMaterial;
    
                        if (useGravity)
                        {
                            // add gravity to the object
                            draggedObject.GetComponent<Rigidbody>().useGravity = true;
                        }
    
                        draggedObject = null;
                    }*/
                }
            }
    
        }
        public void HandGripDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
        {
            if (!isHandInteracting || !interactionManager)
                return;
            if (userId != interactionManager.GetUserID())
                return;
    
            lastHandEvent = InteractionManager.HandEventType.Grip;
            //isLeftHandDrag = !isRightHand;
            screenNormalPos = handScreenPos;
        }
    
        public void HandReleaseDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
        {
            if (!isHandInteracting || !interactionManager)
                return;
            if (userId != interactionManager.GetUserID())
                return;
    
            lastHandEvent = InteractionManager.HandEventType.Release;
            //isLeftHandDrag = !isRightHand;
            screenNormalPos = handScreenPos;
        }
        public bool HandClickDetected(long userId, int userIndex, bool isRightHand, Vector3 handScreenPos)
        {
            return true;
        }
    }

    需要注意的是,获取到的手的坐标是屏幕坐标,就是0---1的范围,如果想要应用,还需要转换成世界坐标,另外注意unity中的坐标轴,跟其他程序或软件的坐标轴可能会不同

  • 相关阅读:
    Java程序:从命令行接收多个数字,求和并输出结果
    大道至简读后感
    大道至简第一章读后感Java伪代码
    Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
    声明式验证超时问题
    Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
    Upgrading or Redeploying SharePoint 2010 Workflows
    Upgrade custom workflow in SharePoint
    SharePoint 2013中Office Web Apps的一次排错
    How to upgrade workflow assembly in MOSS 2007
  • 原文地址:https://www.cnblogs.com/lingLuoChengMi/p/9667872.html
Copyright © 2011-2022 走看看