zoukankan      html  css  js  c++  java
  • 利用RealSense检测到的手指关节信息自定义简单动态手势

    英特尔的RealSense深度摄像头可以检测到手的骨骼信息,给出各个关节的相对位置。这里我自己定义了一些简单的动态手势,例如上下左右移动和左右旋转等等。如果有需要,程序可以继续进行扩展,加入更多的手势。

    注意,程序基于Unity3D平台实现,在运行中需要读取指尖和手掌中心的模型名称。如果官方的SDK对此有修改,需要在代码中更新。

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class test : MonoBehaviour {
    
        // Use this for initialization
        List<GameObject> objs = new List<GameObject>();
        GameObject handCenter;
        Vector3[] Tips;
       // public GUIText gesStateText;
        public GUIText gesCommandText;
        enum GestureCommand {
            moveLeft ,
            moveRight ,
            moveForward ,
            moveBack ,
            rotationRight,
            rotationLeft,
                none
        }
        enum HandMotion {
            up,
            down,
            left,
            right,
            forward,
            back,
            empty
            
        }
        enum GestureState {
            palm,
            pinch,
            empty
        }
        GestureState currentGestureState= GestureState.empty;
        HandMotion currentHandMotion = HandMotion.empty;
        GestureCommand currentGestureCommand = GestureCommand.none;
        float threshold = 120;
        int frameCountX = 0;
        int frameCountY = 0;
        int frameCountZ = 0;
        int frameCountStay = 0;
        int countThreshold = 5;
        public float stayFlag = 0.1f;
        Vector3 origin = Vector3.zero;
        Vector3 destination = Vector3.zero;
    
    
        void Start () {
            Tips = new Vector3[5];
           // gesStateText.text = currentGestureState.ToString();
           // gesStateText.fontSize = 40;
    
            gesCommandText.text = currentGestureCommand.ToString();
            gesCommandText.fontSize = 50;
    
    
        }
    	
    	// Update is called once per frame
    	void Update () {
    
    
            if (handCenter = GameObject.Find("PalmCenter(Clone)"))
            {
            
    
                objs.Clear();
                foreach (GameObject go in GameObject.FindObjectsOfType(typeof(GameObject)))
                {
                    if (go.name == "Tip(Clone)")
                    {
                        objs.Add(go);
                    }
                }
                for (int i = 0; i < objs.Count && i < Tips.Length; i++)
                {
                    Tips[i] = objs[i].transform.position;
                }
                //Debug.Log("NUM:"+ objs.Count);
    
                //float temp = MeanDistanceOfFive(Tips);
                float temp2 = SumOfFiveTipsToOthers(Tips);
    
                if (temp2 < threshold)
                {
                    currentGestureState = GestureState.pinch;
                }
                else
                {
                    currentGestureState = GestureState.palm;
                }
               
    
    
                //================
                destination = handCenter.transform.position;
                int direction = DetectMotionDirection(origin, destination);
                //when accumulate to the threshold, change the HandMotin state
                switch (direction)
                {
                    case 0:
                        frameCountStay++;
                        if (frameCountStay > countThreshold)
                        {
                            ClearFrameCount();
                            currentHandMotion =  HandMotion.empty ;
    
                        }
                        Debug.Log("empty");
                        break;
                    case 1:
                        frameCountX++;
                        if (frameCountX > countThreshold)
                        {
                            ClearFrameCount();
                            currentHandMotion = destination.x - origin.x > 0 ? HandMotion.left : HandMotion.right;
    
                        }
                        Debug.Log("X");
                        break;
                    case 2:
                        frameCountY++;
                        if (frameCountY > countThreshold)
                        {
                            ClearFrameCount();
                            currentHandMotion = destination.y - origin.y > 0 ? HandMotion.up : HandMotion.down;
    
                        }
                        Debug.Log("Y");
                        break;
                    case 3:
                        frameCountZ++;
                        if (frameCountZ > countThreshold)
                        {
                            ClearFrameCount();
                            currentHandMotion = destination.z - origin.z > 0 ? HandMotion.forward : HandMotion.back;
    
                        }
                        Debug.Log("Z");
                        break;
                }
               
            }
            else
            {
                currentGestureState = GestureState.empty;
                
            }
    
            //according to  the current HandMotion state, compute the speed in the direction
            Vector3 speed = destination - origin;
            GetFinalCommand(currentGestureState, currentHandMotion, ref currentGestureCommand);
    
            origin = destination; //prepare data for the next cycle
    
            //gesStateText.text = currentGestureState.ToString();
            gesCommandText.text = currentGestureCommand.ToString();
        }
    
        void OnGUI()
        {        
        }
    
        void GetFinalCommand(GestureState gs, HandMotion hm, ref GestureCommand gc)
        {
            switch (gs)
            {
                case GestureState.palm:
                    switch (hm)
                    {
                        case HandMotion.left:
                            gc = GestureCommand.moveLeft;
                            break;
                        case HandMotion.right:
                            gc = GestureCommand.moveRight;
                            break;
                        case HandMotion.forward:
                            gc = GestureCommand.moveForward;
                            break;
                        case HandMotion.back:
                            gc = GestureCommand.moveBack;
                            break;
                        case HandMotion.up:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.down:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.empty:
                            gc = GestureCommand.none;
                            break;
                    }
                    break;
                case GestureState.pinch:
                    switch (hm)
                    {
                        case HandMotion.left:
                            gc = GestureCommand.rotationLeft;
                            break;
                        case HandMotion.right:
                            gc = GestureCommand.rotationRight;
                            break;
                        case HandMotion.forward:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.back:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.up:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.down:
                            gc = GestureCommand.none;
                            break;
                        case HandMotion.empty:
                            gc = GestureCommand.none;
                            break;
                    }
                    break;
                case GestureState.empty:
                    gc = GestureCommand.none;
                    break;
    
            }
            
        }
        void ClearFrameCount()
        {
            frameCountX = 0;
            frameCountY = 0;
            frameCountZ = 0;
            frameCountStay = 0;
    
        }
        //此处的函数不必要,可用Vector3.Distance()代替
        float TipsDistance(Vector3 a, Vector3 b)
        {
            float dis = 0;
            dis = Mathf.Sqrt(Mathf.Pow(a.x-b.x,2)+ Mathf.Pow(a.y - b.y, 2)+Mathf.Pow(a.z - b.z, 2));
    
            return dis;
        }
        float MeanDistanceOfFive( Vector3[] v)
        {
            float dis =0;
            Vector3 v_sum = Vector3.zero;
            for (int i = 0; i < v.Length; i++)
            {
                v_sum = v_sum + v[i];
            }
            Vector3 v_mean = v_sum / v.Length;
            for (int i = 0; i < v.Length; i++)
            {
                dis = dis + TipsDistance(v_mean,v[i]);
            }
    
    
            return dis/v.Length;
        }
    
        float SumOfFiveTipsToOthers(Vector3[] v)
        {
            float sumDis = 0;
            for (int i = 0; i < v.Length; i++)
            {
                for (int j = 0; j < v.Length; j++)
                {
                    sumDis += TipsDistance(v[i],v[j]);
                }
                
            }
            return sumDis;
        }
    
        int DetectMotionDirection(Vector3 origin, Vector3 destination)
        {
            Vector3 s = destination - origin;
            Vector3 t = new Vector3(Mathf.Abs(s.x), Mathf.Abs(s.y), Mathf.Abs(s.z));
            if (t.x + t.y + t.z < stayFlag) return 0; // not more than the stayflag, we consider it in a static state
    
            if (t.x >= t.y && t.x >= t.z)
            {
                return 1;
            }
            else if (t.y >= t.x && t.y >= t.z)
            {
                return 2;
            }
            else if (t.z >= t.x && t.z >= t.y)
            {
                return 3;
            }
            else
            {
                return 0;
            }
        }
    
        
    }
    


  • 相关阅读:
    20145310《网络对抗》Exp2 后门原理与实践
    20145310《网络对抗》逆向及Bof基础
    20144303《网络对抗》免考项目——恶意代码分析以及检测
    20144303石宇森《网络对抗》Web安全基础实践
    20144303石宇森 《网络对抗》 WEB基础实践
    20144303石宇森 《网络对抗技术》 网络欺诈技术防范
    20144303 石宇森《网络对抗》信息收集和漏洞扫描技术
    20144303石宇森《网络对抗》MSF基础应用
    20144303石宇森 《网络对抗技术》 恶意代码分析
    20144303 石宇森 《网络对抗技术》免杀原理与实践
  • 原文地址:https://www.cnblogs.com/yanhuiqingkong/p/7770046.html
Copyright © 2011-2022 走看看