diff --git a/gui/OpenFaceDemo/MainWindow.xaml b/gui/OpenFaceDemo/MainWindow.xaml index 939c2c4..f4848d3 100644 --- a/gui/OpenFaceDemo/MainWindow.xaml +++ b/gui/OpenFaceDemo/MainWindow.xaml @@ -6,7 +6,7 @@ xmlns:local="clr-namespace:OpenFaceDemo" xmlns:of="clr-namespace:OpenFaceOffline;assembly=OpenFaceOffline" mc:Ignorable="d" - Title="OpenFace Analyser" Height="800" Width="1300" MinWidth="700" MinHeight="450" Closing="Window_Closing" WindowStartupLocation="CenterScreen"> + Title="OpenFace Analyser" Height="800" Width="1300" MinWidth="700" MinHeight="450" Closing="Window_Closing" WindowStartupLocation="CenterScreen" KeyDown="Window_KeyDown"> @@ -27,8 +27,8 @@ - - + + diff --git a/gui/OpenFaceDemo/MainWindow.xaml.cs b/gui/OpenFaceDemo/MainWindow.xaml.cs index fe309f4..526565e 100644 --- a/gui/OpenFaceDemo/MainWindow.xaml.cs +++ b/gui/OpenFaceDemo/MainWindow.xaml.cs @@ -62,8 +62,10 @@ namespace OpenFaceDemo FpsTracker processing_fps = new FpsTracker(); + // Controlling the model reset volatile bool detectionSucceeding = false; volatile bool reset = false; + Point? resetPoint = null; // For selecting webcams CameraSelection cam_sec; @@ -73,6 +75,7 @@ namespace OpenFaceDemo CLNF clnf_model; FaceAnalyserManaged face_analyser; + public MainWindow() { InitializeComponent(); @@ -245,7 +248,7 @@ namespace OpenFaceDemo cx = grayFrame.Width / 2f; cy = grayFrame.Height / 2f; } - + bool detectionSucceeding = ProcessFrame(clnf_model, clnf_params, frame, grayFrame, fx, fy, cx, cy); double confidence = (-clnf_model.GetConfidence()) / 2.0 + 0.5; @@ -384,7 +387,16 @@ namespace OpenFaceDemo if (reset) { - clnf_model.Reset(); + if (resetPoint.HasValue) + { + clnf_model.Reset(resetPoint.Value.X, resetPoint.Value.Y); + resetPoint = null; + } + else + { + clnf_model.Reset(); + } + face_analyser.Reset(); reset = false; @@ -477,13 +489,32 @@ namespace OpenFaceDemo thread_running = false; processing_thread.Join(); - capture.Dispose(); + if (capture != null) + capture.Dispose(); + } - - face_analyser.Dispose(); - clnf_model.Dispose(); - this.Close(); + if (face_analyser != null) + face_analyser.Dispose(); + if(clnf_model != null) + clnf_model.Dispose(); + } + private void Window_KeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.R) + { + reset = true; + } + } + + private void video_MouseDown(object sender, MouseButtonEventArgs e) + { + var clickPos = e.GetPosition(video); + resetPoint = new Point(clickPos.X / video.ActualWidth, clickPos.Y / video.ActualHeight); + reset = true; + } + + } } diff --git a/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp b/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp index 6669584..88cc8a7 100644 --- a/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp +++ b/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp @@ -548,6 +548,9 @@ void CLNF::Read(string main_location) failures_in_a_row = -1; + preference_det.x = -1; + preference_det.y = -1; + } // Resetting the model (for a new video, or complet reinitialisation diff --git a/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp b/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp index caf366a..e074e7f 100644 --- a/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp +++ b/lib/local/LandmarkDetector/src/LandmarkDetectorUtils.cpp @@ -1452,9 +1452,11 @@ bool DetectSingleFaceHOG(cv::Rect_& o_region, const cv::Mat_& int // The tracker can return multiple faces vector > face_detections; vector confidences; - bool detect_success = LandmarkDetector::DetectFacesHOG(face_detections, intensity_img, detector, confidences); - + + // In case of multiple faces pick the biggest one + bool use_size = true; + if(detect_success) { @@ -1463,10 +1465,14 @@ bool DetectSingleFaceHOG(cv::Rect_& o_region, const cv::Mat_& int // keep the most confident one or the one closest to preference point if set double best_so_far; if(use_preferred) - { + { best_so_far = sqrt((preference.x - (face_detections[0].width/2 + face_detections[0].x)) * (preference.x - (face_detections[0].width/2 + face_detections[0].x)) + (preference.y - (face_detections[0].height/2 + face_detections[0].y)) * (preference.y - (face_detections[0].height/2 + face_detections[0].y))); } + else if (use_size) + { + best_so_far = (face_detections[0].width + face_detections[0].height) / 2.0; + } else { best_so_far = confidences[0]; @@ -1481,10 +1487,16 @@ bool DetectSingleFaceHOG(cv::Rect_& o_region, const cv::Mat_& int if(use_preferred) { - dist = sqrt((preference.x - (face_detections[0].width/2 + face_detections[0].x)) * (preference.x - (face_detections[0].width/2 + face_detections[0].x)) + - (preference.y - (face_detections[0].height/2 + face_detections[0].y)) * (preference.y - (face_detections[0].height/2 + face_detections[0].y))); + dist = sqrt((preference.x - (face_detections[i].width/2 + face_detections[i].x)) * (preference.x - (face_detections[i].width/2 + face_detections[i].x)) + + (preference.y - (face_detections[i].height/2 + face_detections[i].y)) * (preference.y - (face_detections[i].height/2 + face_detections[i].y))); + better = dist < best_so_far; } + else if (use_size) + { + dist = (face_detections[i].width + face_detections[i].height) / 2.0; + better = dist > best_so_far; + } else { dist = confidences[i];