Пример #1
0
        private GestureData NormalizeClosedLines(GestureData data)
        {
            var result = new GestureData();

            foreach (var line in data.lines)
            {
                var resultLine = new GestureLine()
                {
                    points     = line.points.ToList(),
                    closedLine = line.closedLine
                };
                if (line.closedLine)
                {
                    resultLine.points.Add(Vector2.Lerp(resultLine.points.Last(), resultLine.points[0], 0.99f));
                }
                result.lines.Add(resultLine);
            }
            return(result);
        }
Пример #2
0
        private RecognitionResult findPattern(GestureData queryData)
        {
            var bestGesture = default(GesturePattern);
            var bestScore   = Score.MaxDistance;

            var indexes = Enumerable.Range(0, queryData.lines.Count).ToList();
            List <List <int> > permutIndexes = GenPermutations(indexes);

            var permutations = permutIndexes.Select(e => makePermutation(e, queryData)).ToList();

            for (int i = 0; i < patterns.Count; i++)
            {
                var gestureAsset = patterns [i];
                var assetData    = NormalizeData(gestureAsset.gesture);

                if (assetData.lines.Count != queryData.lines.Count)
                {
                    //ignore wrong sizes
                    continue;
                }

                foreach (var data in permutations)
                {
                    var permutScore = CalcScore(assetData, data);

                    float pd = permutScore.positionDistance;
                    float cd = permutScore.curvatureDistance;
                    float ad = permutScore.angleDistance;

                    if (permutScore > bestScore)
                    {
                        bestScore   = permutScore;
                        bestGesture = gestureAsset;
                    }
                }
            }

            return(new RecognitionResult()
            {
                gesture = bestGesture, score = bestScore
            });
        }
Пример #3
0
        private Score CalcScore(GestureData data1, GestureData data2, bool useLinesDirections)
        {
            if (data1.lines.Count == data2.lines.Count)
            {
                var lineScores = new List <Score> ();

                for (int i = 0; i < data1.lines.Count; i++)
                {
                    var line1 = data1.lines [i].points;

                    var line2Fwd = data2.lines [i].points;                    //forward
                    var scoreFwd = CalcListScore(line1, line2Fwd, data2.lines[i].closedLine);

                    if (useLinesDirections)
                    {
                        lineScores.Add(scoreFwd);
                    }
                    else
                    {
                        var line2Bwd = line2Fwd.AsEnumerable().Reverse().ToList();                           //backwards
                        var scoreBwd = CalcListScore(line1, line2Bwd, data2.lines[i].closedLine);

                        //gets best score between forward and backwards
                        var score = scoreFwd > scoreBwd ? scoreFwd : scoreBwd;
                        lineScores.Add(score);
                    }
                }

                //mean score from lines
                return(new Score()
                {
                    positionDistance = lineScores.Select(e => e.positionDistance).Sum() / lineScores.Count,
                    angleDistance = lineScores.Select(e => e.angleDistance).Sum() / lineScores.Count,
                    curvatureDistance = lineScores.Select(e => e.curvatureDistance).Sum() / lineScores.Count
                });
            }
            else
            {
                return(Score.MaxDistance);
            }
        }
Пример #4
0
        IEnumerator RecognizeCoroutine(GestureData data, System.Action <RecognitionResult> callback, bool normalizeScale)
        {
            RecognitionResult result = null;

            //runs recocnition in another thread to avoid framerate drop

            var thread = new System.Threading.Thread(() => {
                var normData = NormalizeData(data, normalizeScale);
                var found    = findPattern(normData, normalizeScale);
                result       = found;
            });

            thread.Start();

            while (thread.IsAlive)
            {
                yield return(null);
            }

            callback.Invoke(result);
        }
Пример #5
0
        RecognitionResult SearchThroughPatterns(int beginIndex, int endIndex, GestureData queryData, bool normalizeScale, List <GestureData> permutations, List <GestureData> singlePermutation)
        {
            var bestGesture = default(GesturePattern);
            var bestScore   = Score.MaxDistance;

            for (int i = beginIndex; i <= endIndex; i++)
            {
                var gestureAsset = patterns[i];
                var assetData    = NormalizeData(gestureAsset.gesture, normalizeScale);

                if (assetData.lines.Count != queryData.lines.Count)
                {
                    //ignore wrong sizes
                    continue;
                }

                //if useLinesOrder, dont calc permutations
                var permutationsToLook = gestureAsset.useLinesOrder ? singlePermutation : permutations;

                foreach (var data in permutationsToLook)
                {
                    var permutScore = CalcScore(data, assetData, gestureAsset.useLinesDirections);

                    float pd = permutScore.positionDistance;
                    float cd = permutScore.curvatureDistance;
                    float ad = permutScore.angleDistance;

                    if (permutScore > bestScore)
                    {
                        bestScore   = permutScore;
                        bestGesture = gestureAsset;
                    }
                }
            }

            return(new RecognitionResult()
            {
                gesture = bestGesture, score = bestScore
            });
        }
Пример #6
0
        public void OnEndDrag(PointerEventData eventData)
        {
            data.LastLine.points.Add(FixedPosition(eventData.position));
            UpdateLines();

            for (int size = data.lines.Count; size >= 1 && size >= minLines; size--)
            {
                //last [size] lines
                var sizedData = new GestureData()
                {
                    lines = data.lines.GetRange(data.lines.Count - size, size)
                };

                RecognitionResult result = recognizer.Recognize(sizedData);
                result.gestureData = sizedData;

                if (result.gesture != null && result.score.score >= scoreToAccept)
                {
                    OnRecognize.Invoke(result);
                    if (clearNotRecognizedLines)
                    {
                        data = sizedData;
                        UpdateLines();
                    }
                    break;
                }
                else
                {
                    OnRecognize.Invoke(RecognitionResult.Empty);
                }
            }

            //Added: Stijn
            if (clearImmediatly)
            {
                data.lines.Clear();
                UpdateLines();
            }
        }
        IEnumerator OnEndDragCoroutine(PointerEventData eventData)
        {
            if (!in3D)
            {
                var fixedPos = FixedPosition(eventData.position);

                if (fixedPos.x != -999f && fixedPos.y != -999f)
                {
                    data.LastLine.points.Add(fixedPos);
                }
                UpdateLines();
            }
            else
            {
                var fixedPos = FixedPosition3D(eventData.position);

                if (fixedPos.x != -999f && fixedPos.y != -999f)
                {
                    data.LastLine.points3D.Add(fixedPos);
                    if (player.transform.forward == Vector3.right || player.transform.forward == -Vector3.right)
                    {
                        data.LastLine.points.Add(new Vector2(fixedPos.z, fixedPos.y));
                    }
                    else
                    {
                        data.LastLine.points.Add(new Vector2(fixedPos.x, fixedPos.y));
                    }
                }

                UpdateLines();
            }



            for (int size = data.lines.Count; size >= 1 && size >= minLines; size--)
            {
                //last [size] lines
                var sizedData = new GestureData()
                {
                    lines = data.lines.GetRange(data.lines.Count - size, size)
                };

                var sizedNormalizedData = sizedData;


                //Fixed Area is never going to be used, so that line below is commented out as it throws an unnecessary error
                if (fixedArea)
                {
                    var rect = this.rectTransform.rect;
                    sizedNormalizedData = new GestureData()
                    {
                        lines = sizedData.lines.Select(line => new GestureLine()
                        {
                            closedLine = line.closedLine,
                            //points = line.points.Select(p => Rect.PointToNormalized(rect, this.rectTransform.InverseTransformPoint(p))).ToList()
                        }).ToList()
                    };
                }

                RecognitionResult result = null;

                //run in another thread

                var thread = new System.Threading.Thread(() =>
                {
                    result = recognizer.Recognize(sizedNormalizedData, normalizeScale: !fixedArea);
                });

                thread.Start();

                while (thread.IsAlive)
                {
                    yield return(null);
                }

                if (result.gesture != null && result.score.score >= scoreToAccept)
                {
                    OnRecognize.Invoke(result, this);
                    if (clearNotRecognizedLines)
                    {
                        data = sizedData;
                        UpdateLines();
                    }
                    break;
                }
                else
                {
                    if (data.lines.Count > 1)
                    {
                        OnRecognize.Invoke(RecognitionResult.Empty, this);
                    }
                }
            }

            yield return(null);
        }
Пример #8
0
 public void RecognizeAsync(GestureData data, System.Action <RecognitionResult> callback, bool normalizeScale = true)
 {
     StartCoroutine(RecognizeCoroutine(data, callback, normalizeScale));
 }
Пример #9
0
        private RecognitionResult findPattern(GestureData queryData, bool normalizeScale)
        {
            //UnityEngine.Profiling.Profiler.BeginSample ("Recognize.FindPattern.1");

            var bestGesture = default(GesturePattern);
            var bestScore   = Score.MaxDistance;

            var indexes = Enumerable.Range(0, queryData.lines.Count).ToList();
            List <List <int> > permutIndexes = GenPermutations(indexes);

            var permutations      = permutIndexes.Select(e => makePermutation(e, queryData)).ToList();
            var singlePermutation = permutations.GetRange(0, 1);

            //UnityEngine.Profiling.Profiler.EndSample ();
            //UnityEngine.Profiling.Profiler.BeginSample ("Recognize.FindPattern.2");

            for (int i = 0; i < patterns.Count; i++)
            {
                //UnityEngine.Profiling.Profiler.BeginSample ("Recognize.FindPattern.2.1");

                var gestureAsset = patterns [i];
                var assetData    = NormalizeData(gestureAsset.gesture, normalizeScale);

                //UnityEngine.Profiling.Profiler.EndSample ();
                //UnityEngine.Profiling.Profiler.BeginSample ("Recognize.FindPattern.2.2");

                if (assetData.lines.Count != queryData.lines.Count)
                {
                    //ignore wrong sizes
                    continue;
                }

                //if useLinesOrder, dont calc permutations
                var permutationsToLook = gestureAsset.useLinesOrder ? singlePermutation : permutations;

                foreach (var data in permutationsToLook)
                {
                    //UnityEngine.Profiling.Profiler.BeginSample ("Recognize.FindPattern.2.2.1");

                    var permutScore = CalcScore(data, assetData, gestureAsset.useLinesDirections);

                    //UnityEngine.Profiling.Profiler.EndSample ();

                    float pd = permutScore.positionDistance;
                    float cd = permutScore.curvatureDistance;
                    float ad = permutScore.angleDistance;

                    if (permutScore > bestScore)
                    {
                        bestScore   = permutScore;
                        bestGesture = gestureAsset;
                    }
                }

                //UnityEngine.Profiling.Profiler.EndSample ();
            }

            //UnityEngine.Profiling.Profiler.EndSample ();

            return(new RecognitionResult()
            {
                gesture = bestGesture, score = bestScore
            });
        }
Пример #10
0
        IEnumerator OnEndDragCoroutine(List <PointerEventData> eventData)
        {
            //Debug.Log("OnEndDragRoutine");

            // zeichnet eine letzte linie an der mausposition
            // deaktiviert da erkennung verzögert wird
            //data.LastLine.points.Add(FixedPosition(eventData.position));
            //UpdateLines();

            for (int size = data.lines.Count; size >= 1 && size >= minLines; size--)
            {
                //last [size] lines
                var sizedData = new GestureData()
                {
                    lines = data.lines.GetRange(data.lines.Count - size, size)
                };

                var sizedNormalizedData = sizedData;

                if (fixedArea)
                {
                    var rect = this.rectTransform.rect;
                    sizedNormalizedData = new GestureData()
                    {
                        lines = sizedData.lines.Select(line => new GestureLine()
                        {
                            closedLine = line.closedLine,
                            points     = line.points.Select(p => Rect.PointToNormalized(rect, this.rectTransform.InverseTransformPoint(p))).ToList()
                        }).ToList()
                    };
                }

                RecognitionResult result = null;
                //run in another thread

                var thread = new System.Threading.Thread(() =>
                {
                    result = recognizer.Recognize(sizedNormalizedData, normalizeScale: !fixedArea);
                });
                thread.Start();
                while (thread.IsAlive)
                {
                    yield return(null);
                }

                if (result.gesture != null && result.score.score >= scoreToAccept)
                {
                    recognized   = true;
                    clearCounter = 0;
                    OnRecognize.Invoke(result, sizedNormalizedData);
                    if (clearNotRecognizedLines)
                    {
                        data = sizedData;
                        UpdateLines();
                    }
                    break;
                }
                else
                {
                    OnRecognize.Invoke(RecognitionResult.Empty, null);
                }
            }
            yield return(null);
        }
Пример #11
0
 private GestureData NormalizeData(GestureData data)
 {
     return(NormalizeDistribution(NormalizeScale(data), Detail));
 }
Пример #12
0
        IEnumerator OnEndDragCoroutine(PointerEventData eventData)
        {
            data.LastLine.points.Add(FixedPosition(eventData.position));
            UpdateLines();

            for (int size = data.lines.Count; size >= 1 && size >= minLines; size--)
            {
                //last [size] lines
                var sizedData = new GestureData()
                {
                    lines = data.lines.GetRange(data.lines.Count - size, size)
                };

                var sizedNormalizedData = sizedData;

                if (fixedArea)
                {
                    var rect = this.rectTransform.rect;
                    sizedNormalizedData = new GestureData()
                    {
                        lines = sizedData.lines.Select(line => new GestureLine()
                        {
                            closedLine = line.closedLine,
                            points     = line.points.Select(p => Rect.PointToNormalized(rect, this.rectTransform.InverseTransformPoint(p))).ToList()
                        }).ToList()
                    };
                }

                RecognitionResult result = null;

                //run in another thread

                var thread = new System.Threading.Thread(() => {
                    result = recognizer.Recognize(sizedNormalizedData, normalizeScale: !fixedArea);
                });
                thread.Start();
                while (thread.IsAlive)
                {
                    yield return(null);
                }

                //USE THIS TO SNATCH THE SCORE to turn on boolean thing that allowws to go to next page!!! omg
                if (result.gesture != null && result.score.score >= scoreToAccept)
                {
                    OnRecognize.Invoke(result);
                    puzzleSolved = true;

                    // pm.canTurnPage[pm.page] = true;


                    if (clearNotRecognizedLines)
                    {
                        data = sizedData;
                        UpdateLines();
                    }
                    break;
                }
                else
                {
                    OnRecognize.Invoke(RecognitionResult.Empty);
                }
            }

            yield return(null);
        }
Пример #13
0
        private RecognitionResult findPattern(GestureData queryData, bool normalizeScale)
        {
            var bestGesture = default(GesturePattern);
            var bestScore   = Score.MaxDistance;

            var indexes = Enumerable.Range(0, queryData.lines.Count).ToList();
            List <List <int> > permutIndexes = GenPermutations(indexes);

            var permutations      = permutIndexes.Select(e => makePermutation(e, queryData)).ToList();
            var singlePermutation = permutations.GetRange(0, 1);

            int n_threads = Mathf.Min(this.numberOfThreads, patterns.Count);

            var threads = new List <Thread>();

            for (int threadIndex = 0; threadIndex < n_threads; threadIndex++)
            {
                int beginIndex = threadIndex * patterns.Count / n_threads;
                int endIndex   = (threadIndex + 1) * patterns.Count / n_threads - 1;

                threads.Add(new Thread(() =>
                {
                    var result = SearchThroughPatterns(beginIndex, endIndex, queryData, normalizeScale, permutations, singlePermutation);

                    lock (this)
                    {
                        if (result.score > bestScore)
                        {
                            bestScore   = result.score;
                            bestGesture = result.gesture;
                        }
                    }
                }));
            }

            for (int i = 0; i < threads.Count; i++)
            {
                threads[i].Start();
            }

            for (int i = 0; i < threads.Count; i++)
            {
                threads[i].Join();
            }


            // for (int i = 0; i < patterns.Count; i++)
            // {

            //     var gestureAsset = patterns[i];
            //     var assetData = NormalizeData(gestureAsset.gesture, normalizeScale);

            //     if (assetData.lines.Count != queryData.lines.Count)
            //     {
            //         //ignore wrong sizes
            //         continue;
            //     }

            //     //if useLinesOrder, dont calc permutations
            //     var permutationsToLook = gestureAsset.useLinesOrder ? singlePermutation : permutations;

            //     foreach (var data in permutationsToLook)
            //     {

            //         var permutScore = CalcScore(data, assetData, gestureAsset.useLinesDirections);

            //         float pd = permutScore.positionDistance;
            //         float cd = permutScore.curvatureDistance;
            //         float ad = permutScore.angleDistance;

            //         if (permutScore > bestScore)
            //         {
            //             bestScore = permutScore;
            //             bestGesture = gestureAsset;
            //         }
            //     }

            // }

            return(new RecognitionResult()
            {
                gesture = bestGesture, score = bestScore
            });
        }