Permalink
Browse files

Clean and comment GestureRecognizer code

  • Loading branch information...
1 parent 6b58a8e commit 796b0675575c2d13fb9e47ee1226df230ca162ed @jstasiak jstasiak committed May 22, 2012
@@ -2,15 +2,25 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
-using DTW;
using UnityEngine;
+/// <summary>
+/// Represents single gesture (performed by user or predefined)
+/// </summary>
public class Gesture {
+
+ /// <summary>
+ /// Takes array of movements and stores them normalized.
+ /// </summary>
+ /// <param name="moves"></param>
public Gesture(Vector2[] moves) {
this.Moves = moves;
this.Normalize();
}
+ /// <summary>
+ /// Gets stored normalized movements.
+ /// </summary>
public Vector2[] Moves { get; private set; }
private readonly Dictionary<Vector2, int> directionMap = new Dictionary<Vector2, int> {
@@ -24,7 +34,9 @@ public class Gesture {
{new Vector2(-1, -1), HMMRecognizer.SOUTH_WEST},
};
-
+ /// <summary>
+ /// Returns array of Moves converted to HMM directions.
+ /// </summary>
public int[] HmmDirections {
get {
var result = new List<int>();
@@ -72,14 +84,19 @@ public class Gesture {
}
}
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="other">Another gestures</param>
+ /// <returns>Distance between gestures</returns>
public float DistanceToGesture(Gesture other) {
- // We calculate distance separately for x and y and then combine them
- float xdistance = SimpleDTW.get(this.Moves.Select(e => e.x).ToArray(), other.Moves.Select(e => e.x).ToArray());
- float ymatch = SimpleDTW.get(this.Moves.Select(e => e.y).ToArray(), other.Moves.Select(e => e.y).ToArray());
- return Mathf.Sqrt(xdistance*xdistance + ymatch*ymatch);
+ throw new NotImplementedException();
}
}
+/// <summary>
+/// Represents gesture with a name
+/// </summary>
public class NamedGesture : Gesture {
public readonly string Name;
@@ -92,91 +109,15 @@ public class NamedGesture : Gesture {
}
}
+/// <summary>
+/// Represents match between gesture being tested and another gesture.
+/// Contains Distance value. The lower Distance is, the better the match.
+/// </summary>
public struct GestureMatch {
public float Distance;
public NamedGesture Gesture;
}
-public class GestureRecognizer {
- private static GestureRecognizer sharedInstance;
- private readonly List<NamedGesture> data = new List<NamedGesture>();
-
- public GestureRecognizer() {
- this.InitializeGesturesDatabase();
- this.EliminateDuplicates();
- }
-
- private void InitializeGesturesDatabase() {
- this.AddGesture(new[] {new Vector2(-1, 0)}, "hline");
- this.AddGesture(new[] {new Vector2(1, 0)}, "hline");
-
- this.AddGesture(new[] {new Vector2(0, -1)}, "vline");
- this.AddGesture(new[] {new Vector2(0, 1)}, "vline");
-
- this.AddGesture(new[] {new Vector2(1, 0), new Vector2(-1, -1), new Vector2(1, 0)}, "zet");
-
- for (float x = 0.5f; x <= 2.0f; x += 0.25f) {
- for (float y = 0.5f; y <= 2.0f; y += 0.25f) {
- this.AddGesture(new[] {new Vector2(x, y), new Vector2(x, -y)}, "vup");
- this.AddGesture(new[] {new Vector2(x, -y), new Vector2(x, y)}, "vdown");
- }
- }
- }
-
- private void EliminateDuplicates() {
- var toDelete = new List<NamedGesture>();
-
- for (int i = 0; i < this.data.Count; ++i) {
- for (int j = i + 1; j < this.data.Count; ++j) {
- if (Math.Abs(this.data[i].DistanceToGesture(this.data[j]) - 0.0f) < 0.001f) {
- toDelete.Add(this.data[j]);
- }
- }
- }
- foreach(var duplicate in toDelete) {
- this.data.Remove(duplicate);
- }
- }
-
- public void AddGesture(Vector2[] moves, string name) {
- this.AddGesture(new NamedGesture(moves, name));
- }
-
- public void AddGesture(NamedGesture gesture) {
- this.data.Add(gesture);
- }
-
- public NamedGesture RecognizeGesture(Gesture gesture) {
- var matches = this.GetSortedMatchesForGesture(gesture);
-
- // if two gestures have Distance greater than threshold, we say "no match"
- float threshold = 3f;
-
- if (matches.Count() == 0 || matches.First().Distance > threshold) {
- throw new GestureNotFoundException();
- }
-
- GestureMatch fm = matches.First();
- Debug.Log(string.Format("Successfully matched gesture: {0} (Distance: {1})", fm.Gesture.Name, fm.Distance));
- return fm.Gesture;
- }
-
- public IOrderedEnumerable<GestureMatch> GetSortedMatchesForGesture(Gesture gesture) {
- IOrderedEnumerable<GestureMatch> matches = this.data
- .Select(g => new GestureMatch {Gesture = g, Distance = g.DistanceToGesture(gesture)})
- .OrderBy(match => match.Distance);
- return matches;
- }
-
- public static GestureRecognizer GetSharedInstance() {
- if (sharedInstance == null) {
- sharedInstance = new GestureRecognizer();
- }
-
- return sharedInstance;
- }
-}
-
public class WiiGestures {
public Gesture GetGestureFromPoints(Vector2[] points) {
var list = new List<Vector2>();
@@ -1,126 +0,0 @@
-//http://data-matters.blogspot.com/2008/07/simple-implementation-of-dtwdynamic.html
-
-using System;
-using System.Collections;
-using System.Linq;
-
-namespace DTW
-{
- internal class SimpleDTW {
- private double[] x;
- private double[] y;
- private double[,] distance;
- private double[,] f;
- private ArrayList pathX;
- private ArrayList pathY;
- private ArrayList distanceList;
- private double sum;
-
- public SimpleDTW(double[] _x, double[] _y) {
- x = _x;
- y = _y;
- distance = new double[x.Length,y.Length];
- f = new double[x.Length + 1,y.Length + 1];
-
- for (int i = 0; i < x.Length; ++i) {
- for (int j = 0; j < y.Length; ++j) {
- distance[i, j] = Math.Abs(x[i] - y[j]);
- }
- }
-
- for (int i = 0; i <= x.Length; ++i) {
- for (int j = 0; j <= y.Length; ++j) {
- f[i, j] = -1.0;
- }
- }
-
- for (int i = 1; i <= x.Length; ++i) {
- f[i, 0] = double.PositiveInfinity;
- }
- for (int j = 1; j <= y.Length; ++j) {
- f[0, j] = double.PositiveInfinity;
- }
-
- f[0, 0] = 0.0;
- sum = 0.0;
-
- pathX = new ArrayList();
- pathY = new ArrayList();
- distanceList = new ArrayList();
- }
-
- public ArrayList getPathX() {
- return pathX;
- }
-
- public ArrayList getPathY() {
- return pathY;
- }
-
- public double getSum() {
- return sum;
- }
-
- public double[,] getFMatrix() {
- return f;
- }
-
- public ArrayList getDistanceList() {
- return distanceList;
- }
-
- public void computeDTW() {
- sum = computeFBackward(x.Length, y.Length);
- //sum = computeFForward();
- }
-
- public double computeFForward() {
- for (int i = 1; i <= x.Length; ++i) {
- for (int j = 1; j <= y.Length; ++j) {
- if (f[i - 1, j] <= f[i - 1, j - 1] && f[i - 1, j] <= f[i, j - 1]) {
- f[i, j] = distance[i - 1, j - 1] + f[i - 1, j];
- }
- else if (f[i, j - 1] <= f[i - 1, j - 1] && f[i, j - 1] <= f[i - 1, j]) {
- f[i, j] = distance[i - 1, j - 1] + f[i, j - 1];
- }
- else if (f[i - 1, j - 1] <= f[i, j - 1] && f[i - 1, j - 1] <= f[i - 1, j]) {
- f[i, j] = distance[i - 1, j - 1] + f[i - 1, j - 1];
- }
- }
- }
- return f[x.Length, y.Length];
- }
-
- public double computeFBackward(int i, int j) {
- if (!(f[i, j] < 0.0)) {
- return f[i, j];
- }
- else {
- if (computeFBackward(i - 1, j) <= computeFBackward(i, j - 1) &&
- computeFBackward(i - 1, j) <= computeFBackward(i - 1, j - 1)
- && computeFBackward(i - 1, j) < double.PositiveInfinity) {
- f[i, j] = distance[i - 1, j - 1] + computeFBackward(i - 1, j);
- }
- else if (computeFBackward(i, j - 1) <= computeFBackward(i - 1, j) &&
- computeFBackward(i, j - 1) <= computeFBackward(i - 1, j - 1)
- && computeFBackward(i, j - 1) < double.PositiveInfinity) {
- f[i, j] = distance[i - 1, j - 1] + computeFBackward(i, j - 1);
- }
- else if (computeFBackward(i - 1, j - 1) <= computeFBackward(i - 1, j) &&
- computeFBackward(i - 1, j - 1) <= computeFBackward(i, j - 1)
- && computeFBackward(i - 1, j - 1) < double.PositiveInfinity) {
- f[i, j] = distance[i - 1, j - 1] + computeFBackward(i - 1, j - 1);
- }
- }
- return f[i, j];
- }
-
-
-
- public static float get(float[] a, float[] b) {
- var o = new SimpleDTW(a.Select(el => (double) el).ToArray(), b.Select(el => (double) el).ToArray());
- o.computeDTW();
- return (float) o.sum;
- }
- }
-}

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

0 comments on commit 796b067

Please sign in to comment.