float DistanceAtBestAngle(List <Point> points, Unistroke T, float a, float b, float threshold) { float x1 = Phi * a + (1.0f - Phi) * b; float f1 = DistanceAtAngle(points, T, x1); float x2 = (1.0f - Phi) * a + Phi * b; float f2 = DistanceAtAngle(points, T, x2); while (Mathf.Abs(b - a) > threshold) { if (f1 < f2) { b = x2; x2 = x1; f2 = f1; x1 = Phi * a + (1.0f - Phi) * b; f1 = DistanceAtAngle(points, T, x1); } else { a = x1; x1 = x2; f1 = f2; x2 = (1.0f - Phi) * a + Phi * b; f2 = DistanceAtAngle(points, T, x2); } } return(Mathf.Min(f1, f2)); }
public Result(string name, string variant, string test, float score, float time, Unistroke unistroke) { _name = name; _variant = variant; _test = test; _score = score; _elapsedTime = time; _unistroke = unistroke; }
public void StopRecording() { // has a recorded training set if (points.Count > 0) { var repeated = trainingSetAsset.allPatterns.Find(g => g.name == targetGestureName); if (repeated != null) { trainingSetAsset.allPatterns.Remove(repeated); } var temp = new Unistroke(targetGestureName, points); trainingSetAsset.allPatterns.Add(temp); } onFinishedRecording?.Invoke(); isRecording = false; }
//Loads gestures into GestureSet public static void loadGestures(ref GestureSet<double> gestures) { gestures = new GestureSet<double>(); XmlDocument doc = new XmlDocument(); doc.Load("gestures.xml"); XmlNodeList nl = doc.GetElementsByTagName("gesture"); foreach(XmlNode n in nl){ XmlAttributeCollection collection = n.Attributes; Gesture<double> g = new Gesture<double>(collection[0].InnerText); gestures.gestures.Add(g); Unistroke<double> u = new Unistroke<double>(); foreach(XmlNode k in n.ChildNodes){ XmlAttributeCollection points = k.Attributes; u.trace.Add(new Unistroke<double>.Point3<double>(Double.Parse(points[0].InnerText), Double.Parse(points[1].InnerText), Double.Parse(points[2].InnerText))); } g.unistrokes.Add(u); } }
public Unistroke SavePattern(string name, IEnumerable <Vector2> points) { Unistroke stroke = new Unistroke(name, points); int index = _library.Count; _library.Add(stroke); List <int> examples = null; if (_libraryIndex.ContainsKey(stroke.Name)) { examples = _libraryIndex[stroke.Name]; } if (examples == null) { examples = new List <int>(); _libraryIndex[stroke.Name] = examples; } stroke.ExampleIndex = examples.Count; examples.Add(index); return(stroke); }
protected static float distanceAtAngle(Vector2[] points, Unistroke test, float angle) { Vector2[] rotated = new Vector2[points.Length]; rotateBy(rotated, angle); return(pathDistance(rotated, test.Points)); }
public Result(Unistroke match, float score, float angle) { Match = match; Score = score; Angle = angle; }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void RotationGraph_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "Gestures (*.xml)|*.xml"; dlg.Title = "Load Gesture Pairs"; dlg.Multiselect = true; dlg.RestoreDirectory = false; if (dlg.ShowDialog(this) == DialogResult.OK) { if (dlg.FileNames.Length % 2 != 0) { MessageBox.Show(this, "Pairs of two gestures must be selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { FolderBrowserDialog fld = new FolderBrowserDialog(); fld.Description = "Select a folder where the results file will be written."; fld.SelectedPath = dlg.FileName.Substring(0, dlg.FileName.LastIndexOf('\\')); if (fld.ShowDialog() == DialogResult.OK) { string[] filenames = new string[dlg.FileNames.Length]; Array.Copy(dlg.FileNames, filenames, dlg.FileNames.Length); Array.Sort(filenames); // sorts alphabetically if (!_similar) // doing rotation graphs for dissimilar gestures { bool dissimilar = false; while (!dissimilar) { for (int j = 0; j < filenames.Length * 2; j++) // random shuffle { int pos1 = RandomEx.Integer(0, filenames.Length - 1); int pos2 = RandomEx.Integer(0, filenames.Length - 1); string tmp = filenames[pos1]; filenames[pos1] = filenames[pos2]; filenames[pos2] = tmp; } for (int j = 0; j < filenames.Length; j += 2) // ensure no pairs are same category { string cat1 = Category.ParseName(Unistroke.ParseName(filenames[j + 1])); string cat2 = Category.ParseName(Unistroke.ParseName(filenames[j])); dissimilar = (cat1 != cat2); // set the flag if (!dissimilar) { break; } } } } // now do the rotating and declare victory bool failed = false; for (int i = 0; i < filenames.Length; i += 2) { if (!_rec.CreateRotationGraph(filenames[i + 1], filenames[i], fld.SelectedPath, _similar)) { MessageBox.Show(this, "There was an error reading or writing files.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); failed = true; } } if (!failed) { MessageBox.Show(this, "Finished rotations of gesture pair(s).", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } } }
/// <summary> /// Thread function called in 50 ms intervals to collect data from Chronos watch /// </summary> /// <param name="stateInfo">Unsed parameter - general Object instance</param> public static void Tick(Object stateInfo) { uint data; watch.GetData(out data); sbyte x_data, y_data, z_data; double x_axis, y_axis, z_axis; x_data = (sbyte)((data >> 8) & (UInt32)255); y_data = (sbyte)((data >> 16) & (UInt32)255); z_data = (sbyte)((data >> 24) & (UInt32)255); x_axis = (double) (x_data*18*0.5 + prev_x*0.5 - x_offset); y_axis = (double) (y_data*18*0.5 + prev_y*0.5 - y_offset); z_axis = (double) (z_data*18*0.5 + prev_z*0.5 - z_offset); //x_axis = (double) (x_data*18*0.5 + prev_x*0.5); //y_axis = (double) (y_data*18*0.5 + prev_y*0.5); //z_axis = (double) (z_data*18*0.5 + prev_z*0.5); if (x_axis == 0 && y_axis == 0 && z_axis == 0) return; if (count == 1) { x_offset = prev_x; y_offset = prev_y; z_offset = prev_z; } if (count != 0 && count > 5) { double x_difference=0, y_difference=0, z_difference=0; x_difference = prev_x - x_axis; y_difference = prev_y - y_axis; z_difference = prev_z - z_axis; double sum =Math.Pow(x_difference, 2) + Math.Pow(y_difference, 2) + Math.Pow(z_difference, 2); if (sum > 1100 && current_state == States.IDLE) { unistroke = new Unistroke<double>(); current_state = States.GESTURE_PRECALL; } else if (sum < 300 && current_state == States.GESTURE_PRECALL && buffered_count < 10) { buffered_count = 0; current_state = States.IDLE; } else if (sum > 300 && current_state == States.GESTURE_PRECALL && buffered_count < 10) { buffered_count++; //Console.WriteLine("Add buffered sample"); //Console.WriteLine("{0}, {1}, {2}", x_axis, y_axis, z_axis); unistroke.trace.Add(new Unistroke<double>.Point3<double>((double) x_axis, (double) y_axis, (double) z_axis)); } else if (buffered_count >= 10 && current_state == States.GESTURE_PRECALL) { unistroke.trace.Add(new Unistroke<double>.Point3<double>((double) x_axis, (double) y_axis, (double) z_axis)); //Console.WriteLine("Gesture Recording"); current_state = States.GESTURE_RECORDING; buffered_count = 0; } else if (sum < 300 && (current_state == States.GESTURE_RECORDING) ) { //Console.WriteLine("Gesture Preexit"); current_state = States.PREEXIT; unistroke.trace.Add(new Unistroke<double>.Point3<double>((double) x_axis, (double) y_axis, (double) z_axis)); } else if (sum < 300 && current_state == States.PREEXIT) { current_state = States.IDLE; Console.WriteLine("Gesture EXIT"); //PreProcessing.saveGesture(ref unistroke, "RECTANGLE"); int res; uwave.classify(unistroke, out res); //dollar.classify(unistroke, out res); Console.WriteLine("Recognized gesture: "+gestures.gestures[res].gestureName); } else if (current_state == States.GESTURE_RECORDING) { //Console.WriteLine("Recording gesture"); unistroke.trace.Add(new Unistroke<double>.Point3<double>((double)x_axis, (double)y_axis, (double)z_axis)); } //Console.WriteLine(sum); } prev_x = x_axis; prev_y = y_axis; prev_z = z_axis; //Console.WriteLine("{0}, {1}, {2}", x_axis, y_axis, z_axis); if (x_axis != 0 && y_axis != 0 && z_axis != 0) count++; //if (count > 300) { timer.Dispose(autoResetEvent); } }
float DistanceAtAngle(List<Vector2> points, Unistroke T, float radians) { List<Vector2> newpoints = RotateBy(points, radians); return PathDistance(newpoints, T.points); }
float DistanceAtBestAngle(List<Vector2> points, Unistroke T, float a, float b, float threshold) { float x1 = Phi * a + (1.0f - Phi) * b; float f1 = DistanceAtAngle(points, T, x1); float x2 = (1.0f - Phi) * a + Phi * b; float f2 = DistanceAtAngle(points, T, x2); while (Mathf.Abs(b - a) > threshold) { if (f1 < f2) { b = x2; x2 = x1; f2 = f1; x1 = Phi * a + (1.0f - Phi) * b; f1 = DistanceAtAngle(points, T, x1); } else { a = x1; x1 = x2; f1 = f2; x2 = (1.0f - Phi) * a + Phi * b; f2 = DistanceAtAngle(points, T, x2); } } return Mathf.Min(f1, f2); }
float DistanceAtAngle(List <Point> points, Unistroke T, float radians) { List <Point> newpoints = RotateBy(points, radians); return(PathDistance(newpoints, T.Points)); }