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); }
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 }); }
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); } }
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); }
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 }); }
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); }
public void RecognizeAsync(GestureData data, System.Action <RecognitionResult> callback, bool normalizeScale = true) { StartCoroutine(RecognizeCoroutine(data, callback, normalizeScale)); }
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 }); }
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); }
private GestureData NormalizeData(GestureData data) { return(NormalizeDistribution(NormalizeScale(data), Detail)); }
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); }
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 }); }