/// <summary> /// Compute the min DTW distance between seq2 and all possible endings of seq1. /// </summary> /// <param name="seq1">The master array of sequences to compare</param> /// <param name="seq2">The learner array of sequences to compare</param> /// <returns>The best match</returns> public double DtwComputation(ArrayList seq1, ArrayList seq2, ArrayList learnerframe, ArrayList learnercolorframe, string path, double anglethreshold) { // Init var seq1R = new ArrayList(seq1); //seq1R.Reverse(); var seq2R = new ArrayList(seq2); var learnerf = new ArrayList(); var learnerc = new ArrayList(); //seq2R.Reverse(); var tab = new double[seq1R.Count, seq2R.Count]; for (int i = 0; i < seq1R.Count; i++) { for (int j = 0; j < seq2R.Count; j++) { //tab[i, j] = Double.PositiveInfinity; tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold); } } tab[0, 0] = 0; if (_learnerskeletonstream != null) _learnerskeletonstream.Close(); while (FileDelete(@path + "LearnerSelected")) ; _learnerskeletonstream = File.Create(@path + "LearnerSelected"); _lrecorder = new KinectRecorder(KinectRecordOptions.Skeletons, _learnerskeletonstream); if (_learnercolorstream != null) _learnercolorstream.Close(); while (FileDelete(@path + "LearnerSelectedColor")) ; _learnercolorstream = File.Create(@path + "LearnerSelectedColor"); _lcolorrecorder = new BinaryWriter( _learnercolorstream); int []max_slope = new int [3]; // Dynamic computation of the DTW matrix. for (int i = 1; i < seq1R.Count; i++) { for (int j = 1; j < seq2R.Count; j++) { switch (min(tab[i, j - 1], tab[i - 1, j - 1], tab[i - 1, j])) { case 1: if(max_slope[0]++ %6 != 0) tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i, j - 1]; else tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1]; max_slope[1] = 0; max_slope[2] = 0; break; case 2: tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1]; max_slope[0] = 0; max_slope[2] = 0; break; case 3: if (max_slope[2]++ % 6 != 0) tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1]; else tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j]; max_slope[0] = 0; max_slope[1] = 0; break; default: tab[i, j] = double.PositiveInfinity; break; } } } int totalframe = 0; int correctframe = 0; bool chosen = false; //Reconstruct the best matched path //int currentI = bestMatchI; //int currentJ = bestMatchI; int currentI = seq1R.Count - 1; int currentJ = seq2R.Count - 1; while (currentI != 0 && currentJ != 0) { //Console.WriteLine(target.I + " " + target.J); switch (min(tab[currentI, currentJ - 1], tab[currentI - 1, currentJ - 1], tab[currentI - 1, currentJ])) { case 1: currentJ--; chosen = false; break; case 2: currentI--; currentJ--; learnerf.Add((SkeletonFrame)learnerframe[currentJ]); if (currentJ < learnercolorframe.Count) learnerc.Add((int)learnercolorframe[currentJ]); correctframe++; chosen = false; break; case 3: currentI--; learnerf.Add((SkeletonFrame)learnerframe[currentJ]); if(currentJ < learnercolorframe.Count) learnerc.Add((int)learnercolorframe[currentJ]);// sometimes the color image frame number is smaller if(!chosen) correctframe++; chosen = true; break; default: currentJ--; chosen = false; break; } totalframe++; } while (learnerf.Count != 0) { _lrecorder.Record((SkeletonFrame)learnerf[learnerf.Count - 1]); learnerf.RemoveAt(learnerf.Count - 1); } using (FileStream fs = File.OpenRead(".\\colorStream")) { using (BinaryReader reader = new BinaryReader(fs)) { int temp = reader.ReadInt32(); _lcolorrecorder.Write(temp); CreateFromReader(reader); while (learnerc.Count != 0) { if (FrameNumber == (int)learnerc[learnerc.Count - 1]) { Record(_lcolorrecorder); learnerc.RemoveAt(learnerc.Count - 1); } else { CreateFromReader(reader); } } } } _learnerskeletonstream.Close(); _lrecorder.Stop(); _learnercolorstream.Close(); _lcolorrecorder.Close(); return (Double)correctframe / (Double)totalframe * 100; }
/// <summary> /// Stores our gesture to the DTW sequences list /// </summary> /// <param name="sender">The sender object</param> /// <param name="e">Routed Event Args</param> private void tcStoreClick(object sender, RoutedEventArgs e) { // Set the buttons enabled state //dtwRead.IsEnabled = false; tcCapture.IsEnabled = true; tcStore.IsEnabled = false; tcReplay.IsEnabled = true; tcStartLearning.IsEnabled = true; tcPlayBack.IsEnabled = true; tcPlaybackMaster.IsEnabled = true; // Set the capturing? flag _learning = false; _capturing = false; _recorder = null; _colorrecorder = null; paragraph.Inlines.Clear(); /* const string message = "Are you sure that you would like to store the TaiChi motion?"; const string caption = "Confirmation"; var result = System.Windows.Forms.MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question); // If the no button was pressed ... if (result == System.Windows.Forms.DialogResult.Yes) {*/ status.Text = "Remembering " + gestureList.Text + ", please stay there until the saving process finished :)"; string path = ".\\Records\\" + gestureList.Text + "\\"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } if (_recordcolorstream != null) _recordcolorstream.Close(); if (_recordskeletonstream != null) _recordskeletonstream.Close(); if (File.Exists(@path + "skeleton")) while (FileDelete(@path + "skeleton")) ; if (File.Exists(@path + "colorStream")) while (FileDelete(@path + "colorStream")) ; if (File.Exists(@path + "frame_number")) while (FileDelete(@path + "frame_number")) ; File.Copy(@_temppath + "skeleton", @path + "skeleton"); File.Copy(@_temppath + "colorStream", @path + "colorStream"); /* while (IsFileClosed(@_temppath + "colorStream") && IsFileClosed(@path + "colorStream")) { Thread.Sleep(1000); } * */ using (FileStream fs = File.Create(@path + "frame_number")) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(_finalframeno); } } status.Text = gestureList.Text + " added"; // } // else // { // _recordskeletonstream.Close(); // _recordcolorstream.Close(); // return; // } }
/// <summary> /// Capture mode. Sets our control variables and button enabled states /// </summary> private void StartCapture() { _capturing = true; paragraph.Inlines.Clear(); paragraph.Inlines.Add("Start ..."); // Clear the _video buffer and start from the beginning //test _video = new ArrayList(); if (File.Exists(@_temppath + "skeleton")) while (FileDelete(@_temppath + "skeleton")) ; if (File.Exists(@_temppath + "colorStream")) while (FileDelete(@_temppath + "colorStream")) ; if (_learning) { if (_learnercolorstream != null) _learnercolorstream.Close(); if (_learnerskeletonstream != null) _learnerskeletonstream.Close(); _learnerskeletonstream = File.Create(@_temppath + "skeleton"); _learnercolorstream = File.Create(@_temppath + "colorStream"); _recorder = new KinectRecorder(KinectRecordOptions.Skeletons, _learnerskeletonstream); _colorrecorder = new KinectRecorder(KinectRecordOptions.Color, _learnercolorstream); } else { tcStore.IsEnabled = true; // Set the capturing? flag status.Text = "Recording motion " + gestureList.Text; if (_recordcolorstream != null) _recordcolorstream.Close(); if (_recordskeletonstream != null) _recordskeletonstream.Close(); _recordskeletonstream = File.Create(@_temppath + "skeleton"); _recordcolorstream = File.Create(@_temppath + "colorStream"); _recorder = new KinectRecorder(KinectRecordOptions.Skeletons, _recordskeletonstream); _colorrecorder = new KinectRecorder(KinectRecordOptions.Color, _recordcolorstream); } }
/// <summary> /// Event handler for the stop learning click /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tcStopLearningClick(object sender, RoutedEventArgs e) { status.Text = "Stopped learning, waiting for process complete."; tcCapture.IsEnabled = true; tcStopReplay.IsEnabled = false; tcStartLearning.IsEnabled = true; tcStopLearning.IsEnabled = false; tcReplay.IsEnabled = true; tcPlayBack.IsEnabled = true; tcPlaybackMaster.IsEnabled = true; _learning = false; _capturing = false; _replay.Stop(); _colorreplay.Stop(); MasterSkeletonCanvas.Children.Clear(); RealTimeSkeletonCanvas.Children.Clear(); TempReplayImage.Source = ReplayImage.Source; ReplayImage.Source = null; _recorder = null; _colorrecorder = null; /* const string message = "Are you satisfied with your performance this time, save or not?"; const string caption = "Confirmation"; var result = System.Windows.Forms.MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question); // If the no button was pressed ... if (result == System.Windows.Forms.DialogResult.Yes) {*/ paragraph.Inlines.Clear(); status.Text = "Remembering " + gestureList.Text + ", please stay there until the saving process finished :)"; string path = ".\\Learnings\\" + gestureList.Text + "\\"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } if (_learnercolorstream != null) _learnercolorstream.Close(); if (_learnerskeletonstream != null) _learnerskeletonstream.Close(); if (File.Exists(@path + "skeleton")) while (FileDelete(@path + "skeleton")) ; if (File.Exists(@path + "colorStream")) while (FileDelete(@path + "colorStream")) ; using (FileStream fs = File.Create(@path + "frame_number")) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(_finalframeno2); } } if (_learnerseqFrame.Count > 0) { _dTWresult = _dtw.DtwComputation(_masterseq, _learnerseq, _learnerseqFrame, _learnercolorFrame, path, threshold); if (_dTWresult > 80.0) { paragraph.Inlines.Add("Excellent, your learning score is " + (int)_dTWresult); } else if (_dTWresult > 60.0) { paragraph.Inlines.Add("Good, your learning score is " + (int)_dTWresult); } else if (_dTWresult > 40.0) { paragraph.Inlines.Add("Please work harder, your learning score is " + (int)_dTWresult); } else { paragraph.Inlines.Add("Too bad, your learning score is " + (int)_dTWresult); } } File.Copy(@_temppath + "skeleton", @path + "skeleton"); File.Copy(@_temppath + "colorStream", @path + "colorStream"); status.Text = gestureList.Text + " added"; // } //else // { // _learnerskeletonstream.Close(); // _learnercolorstream.Close(); // } }