Пример #1
0
        public OnBodyInputRealtimeExperiments()
        {
            InitializeComponent();

            Location = Properties.Settings.Default.MainLocation;
            Size     = Properties.Settings.Default.MainSize;

            captureSound = new SoundPlayer("sounds\\camera_capture.wav");
            tickSound    = new SoundPlayer("sounds\\tick.wav");
            beepSound    = new SoundPlayer("sounds\\camera_beep.wav");
            phoneSound   = new SoundPlayer("sounds\\phone.wav");
            speech.Rate  = 2;

            captureSound.LoadAsync();
            tickSound.LoadAsync();
            beepSound.LoadAsync();

            timer.Elapsed         += Timer_Elapsed;
            CountdownLabel.Parent  = Display;
            numLocationPredictions = Properties.Settings.Default.PredictionSmoothing;

            Text = "Connecting to Camera and Sensors...";

            // set up the gestures and menus
            GestureActionMap.LoadMacros(File.ReadAllText("defaults/macros.txt"));
            GestureActionMap.LoadMenus(File.ReadAllText("defaults/menus.txt"));
            GestureActionMap.LoadActions(File.ReadAllText("defaults/actions.txt"));

            // needs to be initialized after the GestureActionMap
            testingForm = new TestingForm();

            testingForm.TaskStarted += (string task) =>
            {
                speech.SpeakAsyncCancelAll();
                speech.SelectVoice(TestingVoice);
                speech.SpeakAsync("Begin");
            };

            testingForm.TaskFinished += (string task) =>
            {
                speech.SpeakAsyncCancelAll();
                speech.SelectVoice(TestingVoice);
                speech.SpeakAsync("Task Completed");
            };

            //trainingForm.TrainingDataUpdated += () => { UpdateTrainingLabel(); };
            trainingForm.RecordLocation += (string coarseLocation, string fineLocation) =>
            {
                Logging.LogTrainingEvent("prepare_to_capture_location");
                coarseLocationToTrain = coarseLocation;
                fineLocationToTrain   = fineLocation;

                // change the countdown timer setting if you don't want to capture the sample immediately (useful if you're training on yourself, for example)
                countdown = Properties.Settings.Default.CountdownTimer;
                if (countdown > 0)
                {
                    tickSound.Play();
                    CountdownLabel.Text    = countdown.ToString();
                    CountdownLabel.Visible = true;
                    timer.Start();
                }
                else
                {
                    if (Properties.Settings.Default.EnableSoundEffects)
                    {
                        captureSound.Play();
                    }
                    ImageTemplate newTemplate = AddTemplate();
                    Logging.LogTrainingEvent("Added template: " + newTemplate["coarse"] + " " + newTemplate["fine"]);
                    //trainingForm.UpdateLocationList();
                }
            };
            trainingForm.RecordGesture += (string gesture) =>
            {
                Logging.LogTrainingEvent("start_recording_gesture");
                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    beepSound.Play();
                }
                gestureToTrain   = gesture;
                recordingGesture = true;
            };
            trainingForm.AutoCaptureGesture += (string gesture) =>
            {
                Logging.LogTrainingEvent("start_autocapture_gesture");
                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    beepSound.Play();
                }
                gestureToTrain   = gesture;
                autoTrainGesture = true;
            };
            trainingForm.StopAutoCapturingGestures += () =>
            {
                Logging.LogTrainingEvent("stop_autocapture_gesture");
                autoTrainGesture = false;
                GestureRecognition.Train();
                trainingForm.UpdateGestureList();
            };
            trainingForm.AutoCaptureLocation += (string coarseLocation, string fineLocation) =>
            {
                coarseLocationToTrain = coarseLocation;
                fineLocationToTrain   = fineLocation;

                Logging.LogTrainingEvent("start_autocapture_location");

                countdown = Properties.Settings.Default.CountdownTimer;
                if (countdown > 0)
                {
                    prepareToAutoTrainLocation = true;
                    tickSound.Play();
                    CountdownLabel.Text    = countdown.ToString();
                    CountdownLabel.Visible = true;
                    timer.Start();
                }
                else
                {
                    if (Properties.Settings.Default.EnableSoundEffects)
                    {
                        beepSound.Play();
                    }
                    autoTrainLocation = true;
                }
            };
            trainingForm.StopAutoCapturingLocation += () =>
            {
                autoTrainLocation = false;
                Logging.LogTrainingEvent("stop_autocapture_location");
            };

            TouchSegmentation.TouchDownEvent += () =>
            {
                touchDown                   = true;
                hovering                    = false;
                hoverCoarseLocation         = null;
                hoverFineLocation           = null;
                touchStart                  = DateTime.Now;
                Sensors.Instance.Brightness = ledMaxBrightness;

                Logging.LogOtherEvent("touch_down");

                // reset the location predictions
                if (!recentTouchUp)
                {
                    while (coarseLocationProbabilities.Count > 0)
                    {
                        coarseLocationProbabilities.Take();
                    }
                    while (fineLocationProbabilities.Count > 0)
                    {
                        fineLocationProbabilities.Take();
                    }
                    while (gestureCoarseLocationProbabilities.Count > 0)
                    {
                        gestureCoarseLocationProbabilities.Take();
                    }
                    while (gestureFineLocationProbabilities.Count > 0)
                    {
                        gestureFineLocationProbabilities.Take();
                    }
                    while (coarseLocationPredictions.Count > 0)
                    {
                        coarseLocationPredictions.Take();
                    }
                    while (gestureCoarseLocationPredictions.Count > 0)
                    {
                        gestureCoarseLocationPredictions.Take();
                    }
                    while (gestureFocusWeights.Count > 0)
                    {
                        gestureFocusWeights.Take();
                    }
                    while (gestureSensorReadings.Count > 0)
                    {
                        gestureSensorReadings.Take();
                    }
                    foreach (Sensors.Reading reading in sensorReadingHistory)
                    {
                        gestureSensorReadings.Add(reading);
                    }
                    Logging.LogOtherEvent("smoothing_reset");
                }

                Invoke(new MethodInvoker(delegate { TouchStatusLabel.Text = "Touch Down"; }));
            };
            TouchSegmentation.TouchUpEvent += () =>
            {
                touchDown     = false;
                recentTouchUp = true;
                Invoke(new MethodInvoker(delegate { TouchStatusLabel.Text = "Touch Up"; }));
                Logging.LogOtherEvent("touch_up");

                // trigger an event after a short delay to prevent false positives and allow for the double-tap gesture
                // it is cancelled if the user touches down again within that time
                Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(touchUpDelay);
                    recentTouchUp = false;
                    if (!touchDown)
                    {
                        Logging.LogOtherEvent("touch_up_timeout");
                        Sensors.Instance.Brightness = 0;

                        if (autoTrainLocation)
                        {
                            autoTrainLocation = false;
                            trainingForm.StopAutoCapture();
                        }

                        if ((hovering && !recordingGesture && !autoTrainGesture) || trainingForm.Training)
                        {
                            return;
                        }

                        // process the gesture

                        Gesture gesture = new Gesture(gestureSensorReadings.ToArray());
                        if (gestureSensorReadings.Count > 60)
                        {
                            GestureRecognition.PreprocessGesture(gesture);

                            if (recordingGesture || autoTrainGesture)
                            {
                                //Monitor.Enter(recognitionLock);

                                recordingGesture = false;

                                if (Properties.Settings.Default.EnableSoundEffects)
                                {
                                    captureSound.Play(); Logging.LogAudioEvent("capture", false);
                                }

                                DateTime start    = DateTime.Now;
                                gesture.ClassName = gestureToTrain;
                                GestureRecognition.AddTrainingExample(gesture, gestureToTrain);
                                Logging.LogTrainingEvent("Add gesture: " + gestureToTrain);
                                if (!autoTrainGesture)
                                {
                                    GestureRecognition.Train();
                                    Debug.WriteLine("Training: " + (DateTime.Now - start).TotalMilliseconds + " ms");
                                }

                                start = DateTime.Now;
                                if (!autoTrainGesture)
                                {
                                    //trainingForm.UpdateGestureList();
                                    trainingForm.AddGesture(gesture);
                                    Debug.WriteLine("Updating List: " + (DateTime.Now - start).TotalMilliseconds + " ms");
                                }

                                //Monitor.Exit(recognitionLock);
                            }
                            else
                            {
                                gesture.ClassName = GestureRecognition.PredictGesture(gesture);
                            }
                        }

                        Monitor.Enter(recognitionLock);

                        // predict the most likely location over the coarse of the gesture, weighted by voting and image focus
                        Dictionary <string, float>[] tempCoarseProbabilities = gestureCoarseLocationProbabilities.ToArray();
                        Dictionary <string, float>[] tempFineProbabilities   = gestureFineLocationProbabilities.ToArray();
                        string[] tempCoarsePredictions = gestureCoarseLocationPredictions.ToArray();
                        float[] tempFocusWeights       = gestureFocusWeights.ToArray();

                        // sum up the probabilities
                        Dictionary <string, float> totalProbabilities = new Dictionary <string, float>();
                        //foreach (Dictionary<string, float> probabilities in gestureCoarseLocationProbabilities)
                        for (int i = 0; i < tempCoarseProbabilities.Length; i++)
                        {
                            Dictionary <string, float> probabilities = tempCoarseProbabilities[i];
                            float weight = Math.Max(tempFocusWeights.Length > i ? tempFocusWeights[i] : 0.01f, 0.01f);
                            foreach (string key in probabilities.Keys)
                            {
                                if (!totalProbabilities.ContainsKey(key))
                                {
                                    totalProbabilities[key] = 0;
                                }
                                totalProbabilities[key] += weight * probabilities[key] / numLocationPredictions;
                            }
                        }

                        float maxProb           = 0;
                        string coarseLocation   = "";
                        float coarseProbability = 0;
                        foreach (string key in totalProbabilities.Keys)
                        {
                            if (totalProbabilities[key] > maxProb)
                            {
                                maxProb           = totalProbabilities[key];
                                coarseLocation    = key;
                                coarseProbability = maxProb;
                            }
                        }

                        // sum up the probabilities
                        totalProbabilities = new Dictionary <string, float>();
                        //foreach (Dictionary<string, float> probabilities in gestureFineLocationProbabilities)
                        for (int i = 0; i < tempFineProbabilities.Length; i++)
                        {
                            if (i < tempCoarsePredictions.Length && tempCoarsePredictions[i] == coarseLocation)
                            {
                                Dictionary <string, float> probabilities = tempFineProbabilities[i];
                                float weight = Math.Max(tempFocusWeights.Length > i ? tempFocusWeights[i] : 0.01f, 0.01f);
                                foreach (string key in probabilities.Keys)
                                {
                                    if (!totalProbabilities.ContainsKey(key))
                                    {
                                        totalProbabilities[key] = 0;
                                    }
                                    totalProbabilities[key] += weight * probabilities[key] / numLocationPredictions;
                                }
                            }
                        }

                        maxProb               = 0;
                        string fineLocation   = "";
                        float fineProbability = 0;
                        foreach (string key in totalProbabilities.Keys)
                        {
                            if (totalProbabilities[key] > maxProb)
                            {
                                maxProb         = totalProbabilities[key];
                                fineLocation    = key;
                                fineProbability = maxProb;
                            }
                        }

                        Logging.LogGestureEvent(gesture.ClassName, coarseLocation + " " + fineLocation, gesture);

                        Monitor.Exit(recognitionLock);

                        if (fineLocation == "")
                        {
                            Debug.WriteLine("Error");
                        }

                        Invoke(new MethodInvoker(delegate
                        {
                            CoarsePredictionLabel.Text  = "= " + coarseLocation;
                            CoarseProbabilityLabel.Text = " (response = " + (coarseProbability * 100).ToString("0.0") + ")";
                            FinePredictionLabel.Text    = "= " + fineLocation;
                            FineProbabilityLabel.Text   = " (response = " + (fineProbability * 100).ToString("0.0") + ")";
                            GesturePredictionLabel.Text = gesture.ClassName;
                            if (Properties.Settings.Default.EnableSpeechOutput)
                            {
                                if (Properties.Settings.Default.EnableApplicationDemos)
                                {
                                    string actionResult = GestureActionMap.PerformAction(gesture.ClassName, coarseLocation, fineLocation, Properties.Settings.Default.GestureMode, Properties.Settings.Default.FixedApplicationResponses, lockToCurrentTask: Properties.Settings.Default.LockToCurrentTask);
                                    if (actionResult != null && actionResult.Length > 0)
                                    {
                                        speech.SpeakAsyncCancelAll();
                                        speech.SelectVoice(MenuVoice);
                                        //speech.SpeakAsync(gesture.ClassName + " " + coarseLocation + " " + fineLocation);
                                        speech.SpeakAsync(actionResult);
                                        Logging.LogAudioEvent(actionResult);
                                    }
                                }
                                else
                                {
                                    speech.SpeakAsyncCancelAll();
                                    speech.SelectVoice(MenuVoice);
                                    speech.SpeakAsync(gesture.ClassName + " " + coarseLocation + " " + fineLocation);
                                    Logging.LogAudioEvent(gesture.ClassName + " " + coarseLocation + " " + fineLocation);
                                }
                            }
                        }));
                    }
                });
            };

            // Initialize the camera and other sensors in a background thread to avoid hanging the UI
            Task.Factory.StartNew(() =>
            {
                Camera.Instance.FrameAvailable += Camera_FrameAvailable;
                Camera.Instance.Error          += (string error) =>
                {
                    Debug.WriteLine(error);
                    Invoke(new MethodInvoker(delegate { Text = "Error: could not connect to camera"; }));
                };
                Camera.Instance.Brightness = Properties.Settings.Default.CameraBrightness;

                Sensors.Instance.ReadingAvailable += Sensors_ReadingAvailable;

                Camera.Instance.Connect(); Logging.LogOtherEvent("camera_connected");
                Sensors.Instance.Connect(Properties.Settings.Default.SensorPort); Logging.LogOtherEvent("sensors_connected");

                Sensors.Instance.NumSensors = Properties.Settings.Default.SingleIMU ? 1 : 2;

                Invoke(new MethodInvoker(delegate
                {
                    if (Properties.Settings.Default.TrainingVisible)
                    {
                        trainingToolStripMenuItem.PerformClick();
                    }
                    if (Properties.Settings.Default.SettingsVisible)
                    {
                        settingsToolStripMenuItem.PerformClick();
                    }
                    if (Properties.Settings.Default.TestingVisible)
                    {
                        testingToolStripMenuItem.PerformClick();
                    }
                }));
            });
        }
Пример #2
0
        public LocationAndGestureDataCollectionTool()
        {
            InitializeComponent();

            Location = Properties.Settings.Default.MainLocation;
            Size     = Properties.Settings.Default.MainSize;

            captureSound = new SoundPlayer("sounds\\camera_capture.wav");
            beepSound    = new SoundPlayer("sounds\\camera_beep.wav");
            chimeSound   = new SoundPlayer("sounds\\endTask.wav");
            speech.Rate  = 2;

            captureSound.LoadAsync();
            beepSound.LoadAsync();
            chimeSound.LoadAsync();

            Text = "Connecting to Camera and Sensors...";

            trainingForm.RecordLocation += (string coarseLocation, string fineLocation) =>
            {
                Logging.LogTrainingEvent("prepare_to_capture_location");
                coarseLocationToTrain = coarseLocation;
                fineLocationToTrain   = fineLocation;

                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    captureSound.Play();
                }
                ImageTemplate newTemplate = AddTemplate();
                Logging.LogTrainingEvent("Added template: " + newTemplate["coarse"] + " " + newTemplate["fine"]);
            };
            trainingForm.RecordGesture += (string gesture) =>
            {
                Logging.LogTrainingEvent("start_recording_gesture");
                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    beepSound.Play();
                }
                gestureToTrain   = gesture;
                recordingGesture = true;
            };
            trainingForm.AutoCaptureGesture += (string gesture) =>
            {
                Logging.LogTrainingEvent("start_autocapture_gesture");
                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    beepSound.Play();
                }
                gestureToTrain         = gesture;
                numAutoSamplesGathered = 0;
                autoTrainGesture       = true;
            };
            trainingForm.StopAutoCapturingGestures += () =>
            {
                Logging.LogTrainingEvent("stop_autocapture_gesture");
                autoTrainGesture = false;
                GestureRecognition.Train();
                trainingForm.UpdateGestureList();
            };
            trainingForm.AutoCaptureLocation += (string coarseLocation, string fineLocation) =>
            {
                coarseLocationToTrain = coarseLocation;
                fineLocationToTrain   = fineLocation;

                Logging.LogTrainingEvent("start_autocapture_location");

                if (Properties.Settings.Default.EnableSoundEffects)
                {
                    beepSound.Play();
                }
                autoTrainLocation = true;
            };
            trainingForm.StopAutoCapturingLocation += () =>
            {
                autoTrainLocation = false;
                Logging.LogTrainingEvent("stop_autocapture_location");
            };

            TouchSegmentation.TouchDownEvent += () =>
            {
                touchDown  = true;
                touchStart = DateTime.Now;
                Sensors.Instance.Brightness = 1;

                Logging.LogTouchEvent("touch_down");

                // reset the location predictions
                if (!recentTouchUp)
                {
                    while (gestureSensorReadings.Count > 0)
                    {
                        gestureSensorReadings.Take();
                    }
                    foreach (Sensors.Reading reading in sensorReadingHistory)
                    {
                        gestureSensorReadings.Add(reading);
                    }
                    Logging.LogOtherEvent("smoothing_reset");
                }

                Invoke(new MethodInvoker(delegate { TouchStatusLabel.Text = "Touch Down"; }));
            };
            TouchSegmentation.TouchUpEvent += () =>
            {
                touchDown     = false;
                recentTouchUp = true;
                Invoke(new MethodInvoker(delegate { TouchStatusLabel.Text = "Touch Up"; }));
                Logging.LogTouchEvent("touch_up");

                Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(touchUpDelay);
                    recentTouchUp = false;
                    if (!touchDown)
                    {
                        Logging.LogOtherEvent("touch_up_timeout");
                        Sensors.Instance.Brightness = 0;

                        if (autoTrainLocation)
                        {
                            autoTrainLocation = false;
                            trainingForm.StopAutoCapture();
                        }

                        if (trainingForm.Training)
                        {
                            return;
                        }

                        // process the gesture

                        Gesture gesture = new Gesture(gestureSensorReadings.ToArray());
                        if (gestureSensorReadings.Count > 60)
                        {
                            GestureRecognition.PreprocessGesture(gesture);

                            if (recordingGesture || autoTrainGesture)
                            {
                                //Monitor.Enter(recognitionLock);

                                if (recordingGesture)
                                {
                                    Logging.LogTrainingEvent("stop_recording_gesture");
                                }

                                recordingGesture = false;

                                if (Properties.Settings.Default.EnableSoundEffects)
                                {
                                    captureSound.Play(); Logging.LogAudioEvent("capture", false);
                                }

                                DateTime start         = DateTime.Now;
                                gesture.ClassName      = gestureToTrain;
                                gesture.IsTrainingData = true;
                                GestureRecognition.AddTrainingExample(gesture, gestureToTrain);

                                // autosave the gesture in the background
                                Task.Factory.StartNew(() =>
                                {
                                    if (!Directory.Exists(Path.Combine("savedProfiles", "autosave")))
                                    {
                                        Directory.CreateDirectory(Path.Combine("savedProfiles", "autosave"));
                                    }
                                    int index = 1;
                                    while (File.Exists(Path.Combine("savedProfiles", "autosave", gestureToTrain + "_" + index + ".png")))
                                    {
                                        index++;
                                    }
                                    gesture.Path = Path.Combine("savedProfiles", "autosave", gestureToTrain + "_" + index + ".png");
                                    string json  = JsonConvert.SerializeObject(gesture);
                                    Invoke(new MethodInvoker(delegate { File.WriteAllText(gesture.Path, json); }));
                                });

                                Logging.LogTrainingEvent("Add gesture: " + gestureToTrain + ", path = " + gesture.Path);

                                if (autoTrainGesture)
                                {
                                    numAutoSamplesGathered++;
                                    if (numAutoSamplesGathered >= Properties.Settings.Default.NumAutoGestureSamples)
                                    {
                                        if (Properties.Settings.Default.EnableSoundEffects)
                                        {
                                            chimeSound.Play(); Logging.LogAudioEvent("chime", false);
                                        }
                                        Logging.LogTrainingEvent("stop_autocapture_gesture");
                                        autoTrainGesture = false;
                                    }
                                }

                                start = DateTime.Now;
                                if (!autoTrainGesture)
                                {
                                    trainingForm.AddGesture(gesture);
                                    trainingForm.IsSaved = false;
                                    Debug.WriteLine("Updating List: " + (DateTime.Now - start).TotalMilliseconds + " ms");
                                }
                            }
                        }
                    }
                });
            };

            Task.Factory.StartNew(() =>
            {
                Camera.Instance.FrameAvailable += Camera_FrameAvailable;
                Camera.Instance.Error          += (string error) =>
                {
                    Debug.WriteLine(error);
                    Invoke(new MethodInvoker(delegate { Text = "Error: could not connect to camera"; }));
                };
                Camera.Instance.Brightness = Properties.Settings.Default.CameraBrightness;

                Sensors.Instance.ReadingAvailable += Sensors_ReadingAvailable;

                Camera.Instance.Connect(); Logging.LogOtherEvent("camera_connected");
                Sensors.Instance.Connect(Properties.Settings.Default.SensorPort); Logging.LogOtherEvent("sensors_connected");

                Sensors.Instance.NumSensors = Properties.Settings.Default.SingleIMU ? 1 : 2;

                Invoke(new MethodInvoker(delegate
                {
                    if (Properties.Settings.Default.TrainingVisible)
                    {
                        trainingToolStripMenuItem.PerformClick();
                    }
                    if (Properties.Settings.Default.SettingsVisible)
                    {
                        settingsToolStripMenuItem.PerformClick();
                    }
                }));
            });
        }
Пример #3
0
        private void RemoveButton_Click(object sender, EventArgs e)
        {
            if (TrainingDataViewer.SelectedIndex == 0) // location tab is showing
            {
                foreach (ListViewItem removeItem in LocationView.SelectedItems)
                {
                    int           imageIndex = removeItem.ImageIndex;
                    ImageTemplate template   = (ImageTemplate)removeItem.Tag;
                    Localization.Instance.RemoveTrainingExample(template);
                    Logging.LogOtherEvent("Removed location example: " + (string)template["path"]);
                    LocationView.LargeImageList.Images.RemoveAt(imageIndex);
                    foreach (ListViewItem updateItem in LocationView.Items)
                    {
                        if (updateItem.ImageIndex > imageIndex)
                        {
                            updateItem.ImageIndex--;
                        }
                    }

                    if (removeItem.Group.Items.Count == 0)
                    {
                        LocationView.Groups.Remove(removeItem.Group);
                    }
                    LocationView.Items.Remove(removeItem);
                }

                training = true;
                Localization.Instance.Train();
                UpdateLocationCount();
                training = false;
                OnTrainingDataUpdated();
            }
            else // gesture tab is showing
            {
                foreach (ListViewItem removeItem in GestureView.SelectedItems)
                {
                    int     imageIndex = removeItem.ImageIndex;
                    Gesture template   = (Gesture)removeItem.Tag;
                    Logging.LogOtherEvent("Removed gesture example: " + template.Path);
                    GestureRecognition.RemoveTrainingExample(template);

                    GestureView.LargeImageList.Images.RemoveAt(imageIndex);
                    foreach (ListViewItem updateItem in GestureView.Items)
                    {
                        if (updateItem.ImageIndex > imageIndex)
                        {
                            updateItem.ImageIndex--;
                        }
                    }

                    if (removeItem.Group.Items.Count == 0)
                    {
                        GestureView.Groups.Remove(removeItem.Group);
                    }
                    GestureView.Items.Remove(removeItem);
                }

                training = true;
                GestureRecognition.Train();
                UpdateGestureCount();
                training = false;
                OnTrainingDataUpdated();
            }
        }