示例#1
0
        /// <summary>
        /// Get the farthest hand along the camera up axis from a list of valids hands
        /// </summary>
        /// <param name="validHDs">The valid hands</param>
        /// <returns>The farthest hands or null if the list is empty</returns>
        public HandDetected GetFarthestHand(List <HandDetected> validHDs)
        {
            if (validHDs.Count == 0)
            {
                return(null);
            }

            Vector3 forward = Camera.main.transform.forward;

            forward = (new Vector3(forward.x, 0.0f, forward.z)).normalized;

            HandDetected hd   = validHDs[0];
            float        posZ = Vector3.Dot(forward, validHDs[0].Position - Camera.main.transform.position);

            for (int i = 1; i < validHDs.Count; i++)
            {
                float tempPosZ = Vector3.Dot(forward, validHDs[i].Position - Camera.main.transform.position);
                if (posZ < tempPosZ)
                {
                    posZ = tempPosZ;
                    hd   = validHDs[i];
                }
            }
            return(hd);
        }
示例#2
0
        /// <summary>
        /// Get the optimal hand given a list of valid hands
        /// </summary>
        /// <param name="validHDs">The list of valid Hands</param>
        /// <returns></returns>
        public HandDetected GetOptimalHand(List <HandDetected> validHDs)
        {
            if (validHDs.Count == 0)
            {
                return(null);
            }

            float optimalLimit = 0.25f;

            Vector3 forward = Camera.main.transform.forward;

            forward = (new Vector3(forward.x, 0.0f, forward.z)).normalized;

            HandDetected hd = validHDs[0];

            float maxPosZ = Vector3.Dot(forward, validHDs[0].Position - Camera.main.transform.position);
            float minPosZ = float.MaxValue;


            for (int i = 1; i < validHDs.Count; i++)
            {
                bool  computeMin = false;
                float tempPosZ   = Vector3.Dot(forward, validHDs[i].Position - Camera.main.transform.position);
                if (maxPosZ < tempPosZ)
                {
                    maxPosZ = tempPosZ;
                    if (tempPosZ < optimalLimit) //Take the farthest between a range of 0 and the optimal limit
                    {
                        hd = validHDs[i];
                    }
                    else
                    {
                        computeMin = true;
                    }
                }
                else
                {
                    computeMin = true;
                }

                if (computeMin)
                {
                    if (tempPosZ < minPosZ && tempPosZ >= optimalLimit)
                    {
                        minPosZ = tempPosZ;
                        hd      = validHDs[i];
                    }
                }
            }
            return(hd);
        }
示例#3
0
        public void OnHandUpdate(CameraParameter cameraParam, SpatialCoordinateSystem CoordinateSystem, IList <Hand> hands)
        {
            lock (this)
            {
                if (m_spatialCoordinateSystem != null)
                {
                    //Start a new frame
                    foreach (HandDetected hand in m_handsDetected)
                    {
                        hand.NewDetection = true;
                    }

                    //For each detected hand
                    foreach (Hand hand in hands)
                    {
                        //Get the needed transformation matrices to convert hand in image space to camera and world space
                        System.Numerics.Matrix4x4?cameraToWorld = CoordinateSystem.TryGetTransformTo(m_spatialCoordinateSystem).Value;
                        System.Numerics.Matrix4x4 viewToCamera;
                        System.Numerics.Matrix4x4.Invert(cameraParam.CameraViewTransform, out viewToCamera);
                        if (cameraToWorld == null)
                        {
                            cameraToWorld = System.Numerics.Matrix4x4.Identity;
                        }

                        //Hand in camera space
                        System.Numerics.Vector4 handVecCamera = System.Numerics.Vector4.Transform(new System.Numerics.Vector4(hand.PalmX, hand.PalmY, hand.PalmZ, 1.0f), viewToCamera);
                        Vector3 unityHandCamera = new Vector3(handVecCamera.X, handVecCamera.Y, handVecCamera.Z) / handVecCamera.W;

                        //Wrist in camera space
                        System.Numerics.Vector4 wristVecCamera = System.Numerics.Vector4.Transform(new System.Numerics.Vector4(hand.WristX, hand.WristY, hand.WristZ, 1.0f), viewToCamera);
                        Vector3 unityWristCamera = new Vector3(wristVecCamera.X, wristVecCamera.Y, wristVecCamera.Z) / wristVecCamera.W;

                        //Add offsets in the ROI
                        float[] roi = new float[4];
                        roi[0] = hand.WristROIMinX - 10;
                        roi[1] = hand.WristROIMinY - 10;
                        roi[2] = hand.WristROIMaxX + 10;
                        roi[3] = hand.WristROIMaxY + 10;

                        //check if we already know it
                        bool         created      = false;
                        HandDetected handDetected = null;
                        foreach (HandDetected hd in m_handsDetected)
                        {
                            if (!hd.IsDetected && hd.HandCollision(roi) && (hd.CameraSpacePosition - unityHandCamera).magnitude <= 0.10) //Test the ROI and the magnitude in the position (no more than 5 cm)
                            {
                                handDetected = hd;
                                break;
                            }
                        }

                        //If not, this is a new hand!
                        if (handDetected == null)
                        {
                            handDetected = new HandDetected();
                            handDetected.NewDetection = true;
                            m_handsDetected.Add(handDetected);
                            created = true;
                        }

                        float smoothness = m_smoothness;
                        if (created == true)
                        {
                            smoothness = 0.0f;
                        }

                        //Smooth the hand
                        Vector3 smoothPosCamera         = unityHandCamera * (1.0f - smoothness) + handDetected.CameraSpacePosition * smoothness; //Smooth the position
                        System.Numerics.Vector4 handVec = System.Numerics.Vector4.Transform(new System.Numerics.Vector4(smoothPosCamera.x, smoothPosCamera.y, smoothPosCamera.z, 1.0f), cameraToWorld.Value);
                        Vector3 unityHandVec            = new Vector3(handVec.X, handVec.Y, -handVec.Z) / handVec.W;

                        //Smooth the wrist
                        Vector3 smoothWristCamera        = unityWristCamera * (1.0f - smoothness) + handDetected.CameraSpaceWristPosition * smoothness; //Smooth the position
                        System.Numerics.Vector4 wristVec = System.Numerics.Vector4.Transform(new System.Numerics.Vector4(smoothWristCamera.x, smoothWristCamera.y, smoothWristCamera.z, 1.0f), cameraToWorld.Value);
                        Vector3 unityWristVec            = new Vector3(wristVec.X, wristVec.Y, -wristVec.Z) / wristVec.W;

                        handDetected.PushPosition(unityHandVec, unityWristVec, smoothPosCamera, smoothWristCamera, roi);

                        //Clear fingers information
                        handDetected.Fingers.Clear();
                        handDetected.UppestFinger = null;

                        FingerDetected formerFinger = handDetected.UppestFinger;

                        if (hand.Fingers.Count > 0)
                        {
                            //Conver each fingers detected
                            foreach (Finger f in hand.Fingers)
                            {
                                //Register the finger position
                                System.Numerics.Vector4 fingerVec = System.Numerics.Vector4.Transform(new System.Numerics.Vector4(f.TipX, f.TipY, f.TipZ, 1.0f), viewToCamera);
                                fingerVec = System.Numerics.Vector4.Transform(fingerVec, cameraToWorld.Value);
                                Vector3 unityFingerVec = new Vector3(fingerVec.X, fingerVec.Y, -fingerVec.Z) / fingerVec.W;
                                handDetected.Fingers.Add(new FingerDetected(unityFingerVec));
                            }

                            //Detect the uppest finger
                            float minFY = hand.Fingers[0].TipY;
                            handDetected.UppestFinger = handDetected.Fingers[0];

                            for (int j = 1; j < handDetected.Fingers.Count; j++)
                            {
                                if (minFY > hand.Fingers[0].TipY)
                                {
                                    minFY = hand.Fingers[0].TipY;
                                    handDetected.UppestFinger = handDetected.Fingers[j];
                                }
                            }
                        }
                    }
                }

                int i = 0;
                while (i < m_handsDetected.Count)
                {
                    HandDetected hd = m_handsDetected[i];
                    //Handle non detected hands
                    if (!hd.IsDetected)
                    {
                        hd.PushUndetection();

                        //Delete the non valid hands
                        if (!hd.IsValid)
                        {
                            m_handsDetected.RemoveAt(i);
                            continue;
                        }
                    }
                    i++;
                }
            }
        }