Пример #1
0
 public bool Detect(Frame frame, HandFeatures hf)
 {
     // 檢查 time out
     if (IsTimeOut(frame))
     {
         Reset();
     }
     // 檢查 key frame
     if (hf.StateCode == _currentHF.StateCode)
     {
         float sim = HandFeatures.CosSimilarity(hf, _currentHF);
         if (sim < MotionMatching.T2 * T1)
         {
             Debug.WriteLine(String.Format("[{0}] [{1}] 第{2}個 key frame 完成", Class, Name, _step));
             _timeStamp = frame.Timestamp;
             _step++;
             if (_step == _keys.Count)
             {
                 return(true);
             }
             else
             {
                 _currentHF = _keyHFs[_step];
             }
         }
     }
     return(false);
 }
        public static float T2 = (15f).DegreeToRadian(); // 餘弦相似度閥值

        public static List <int> ExtractKeyFrame(List <Frame> frames, out List <HandFeatures> keyFrameHFs)
        {
            keyFrameHFs = new List <HandFeatures>();
            List <int>   keys = new List <int>();
            int          lastKey;
            Hand         currentHand;
            Hand         lastKeyHand;
            HandFeatures currentHF;
            HandFeatures lastKeyHF;

            if (frames.Count < 1)
            {
                return(keys);
            }
            // 第一張一定是key frame
            lastKey     = 0;
            lastKeyHF   = HandFeatures.ExtractFeatures(frames[lastKey]);
            lastKeyHand = frames[lastKey].Hands[0];
            keys.Add(lastKey);
            keyFrameHFs.Add(lastKeyHF);
            //
            for (int i = 1; i < frames.Count; i++)
            {
                currentHand = frames[i].Hands[0];
                currentHF   = HandFeatures.ExtractFeatures(frames[i]);

                //// 檢查手指數目 (state code)
                //if (lastKeyHF.StateCode != currentHF.StateCode)
                //{
                //    // 往後檢查
                //    int count = 0;
                //    for (int j = i; j < i + T1 && j < frames.Count; j++)
                //    {
                //        HandFeatures hf = HandFeatures.ExtractFeatures(frames[j]);
                //        if (currentHF.StateCode != hf.StateCode)
                //            break;
                //        count++;
                //    }
                //    if (count == T1)
                //    {
                //        // 確定是 key frame
                //        lastKey = i;
                //        lastKeyHF = currentHF;
                //        lastKeyHand = currentHand;
                //        keys.Add(lastKey);
                //        keyFrameHFs.Add(lastKeyHF);
                //        continue;
                //    }
                //}

                // 檢查變異量
                // ↓↓↓↓↓↓↓↓ S和T其中一邊有伸直手指就比較變異輛的方法
                float sim = HandFeatures.CosSimilarity(currentHF, lastKeyHF);
                if (sim > T2)
                {
                    Console.WriteLine("差異度 " + sim.RadianToDegree());
                    lastKey     = i;
                    lastKeyHF   = currentHF;
                    lastKeyHand = currentHand;
                    keys.Add(lastKey);
                    keyFrameHFs.Add(lastKeyHF);
                    continue;
                }
                //// 檢查變異量
                //// ↓↓↓↓↓↓↓↓ 伸直手指的變異量方法
                //if (currentHF.StateCode == lastKeyHF.StateCode)
                //{
                //    //float sim = HandFeatures.CosSimilarity(currentHand, lastKeyHand, currentHF.StateCode);
                //    float sim = HandFeatures.CosSimilarity(currentHand, lastKeyHand);
                //    if (sim > T2)
                //    {
                //        Console.WriteLine("差異度 " + sim.RadianToDegree());
                //        lastKey = i;
                //        lastKeyHF = currentHF;
                //        lastKeyHand = currentHand;
                //        keys.Add(lastKey);
                //        keyFrameHFs.Add(lastKeyHF);
                //        continue;
                //    }
                //}
                // ↓↓↓↓↓↓↓↓ 全部手指的變異量方法
                //if (currentFHF.CosSimilarity(lastKFHF) > T2)
                //{
                //    lastKeyFrame = i;
                //    lastKFHF = currentFHF;
                //    keyFrames.Add(lastKeyFrame);
                //    continue;
                //}
            }
            return(keys);
        }
        public static List <int> ExtractKeyFrame_B(List <Frame> frames, out List <HandFeatures> keyFrameHFs)
        {
            keyFrameHFs = new List <HandFeatures>();
            List <int>   keys = new List <int>();
            int          lastKey;
            Hand         currentHand;
            Hand         lastKeyHand;
            HandFeatures currentHF;
            HandFeatures lastKeyHF;

            if (frames.Count < 1)
            {
                return(keys);
            }
            // 第一張一定是key frame
            lastKey     = 0;
            lastKeyHF   = HandFeatures.ExtractFeatures(frames[lastKey]);
            lastKeyHand = frames[lastKey].Hands[0];
            keys.Add(lastKey);
            keyFrameHFs.Add(lastKeyHF);
            //
            for (int i = 1; i < frames.Count; i++)
            {
                currentHand = frames[i].Hands[0];
                currentHF   = HandFeatures.ExtractFeatures(frames[i]);

                // 檢查手指數目 (state code)
                if (lastKeyHF.StateCode != currentHF.StateCode)
                {
                    // 往後檢查
                    int count = 0;
                    for (int j = i; j < i + T1 && j < frames.Count; j++)
                    {
                        HandFeatures hf = HandFeatures.ExtractFeatures(frames[j]);
                        if (currentHF.StateCode != hf.StateCode)
                        {
                            break;
                        }
                        count++;
                    }
                    if (count == T1)
                    {
                        // 確定是 key frame
                        lastKey     = i;
                        lastKeyHF   = currentHF;
                        lastKeyHand = currentHand;
                        keys.Add(lastKey);
                        keyFrameHFs.Add(lastKeyHF);
                        continue;
                    }
                }

                // 檢查變異量
                // ↓↓↓↓↓↓↓↓ 伸直手指的變異量方法
                if (currentHF.StateCode == lastKeyHF.StateCode)
                {
                    float sim = HandFeatures.CosSimilarity(currentHand, lastKeyHand, currentHF.StateCode);
                    if (sim > T2)
                    {
                        Console.WriteLine("差異度 " + sim.RadianToDegree());
                        lastKey     = i;
                        lastKeyHF   = currentHF;
                        lastKeyHand = currentHand;
                        keys.Add(lastKey);
                        keyFrameHFs.Add(lastKeyHF);
                        continue;
                    }
                }
            }
            return(keys);
        }