From e5cc957e378ede5b94be54716d9404be501da891 Mon Sep 17 00:00:00 2001 From: Tadas Baltrusaitis Date: Mon, 9 Jan 2017 16:11:19 -0500 Subject: [PATCH] Better UI visualization and scaling. --- gui/OpenFaceOffline/MainWindow.xaml.cs | 16 ++++++++++++-- .../UI_items/OverlayImage.xaml.cs | 21 +++++++++++++------ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/gui/OpenFaceOffline/MainWindow.xaml.cs b/gui/OpenFaceOffline/MainWindow.xaml.cs index c5f0349..409a259 100644 --- a/gui/OpenFaceOffline/MainWindow.xaml.cs +++ b/gui/OpenFaceOffline/MainWindow.xaml.cs @@ -156,6 +156,7 @@ namespace OpenFaceOffline // Camera calibration parameters public double fx = -1, fy = -1, cx = -1, cy = -1; + bool estimate_camera_parameters = true; public MainWindow() { @@ -374,7 +375,7 @@ namespace OpenFaceOffline face_analyser.Reset(); // If the camera calibration parameters are not set (indicated by -1), guesstimate them - if(fx == -1 || fy == -1 || cx == -1 || cy == -1) + if(estimate_camera_parameters || fx == -1 || fy == -1 || cx == -1 || cy == -1) { fx = 500.0 * (capture.width / 640.0); fy = 500.0 * (capture.height / 480.0); @@ -563,13 +564,15 @@ namespace OpenFaceOffline else if (confidence > 1) confidence = 1; + double scale = 0; + if (detectionSucceeding) { eye_landmarks = clnf_model.CalculateEyeLandmarks(); lines = clnf_model.CalculateBox((float)fx, (float)fy, (float)cx, (float)cy); - double scale = clnf_model.GetRigidParams()[0]; + scale = clnf_model.GetRigidParams()[0]; gaze_lines = face_analyser.CalculateGazeLines(scale, (float)fx, (float)fy, (float)cx, (float)cy); gaze_angle = face_analyser.GetGazeAngle(); @@ -634,6 +637,7 @@ namespace OpenFaceOffline video.Confidence = confidence; video.FPS = processing_fps.GetFPS(); video.Progress = progress; + video.FaceScale = scale; if (!detectionSucceeding) { @@ -1039,6 +1043,14 @@ namespace OpenFaceOffline fy = camera_params_entry_window.Fy; cx = camera_params_entry_window.Cx; cy = camera_params_entry_window.Cy; + if(fx == -1 || fy == -1 || cx == -1 || cy == -1) + { + estimate_camera_parameters = true; + } + else + { + estimate_camera_parameters = false; + } } } diff --git a/gui/OpenFaceOffline/UI_items/OverlayImage.xaml.cs b/gui/OpenFaceOffline/UI_items/OverlayImage.xaml.cs index e452a10..f4733e5 100644 --- a/gui/OpenFaceOffline/UI_items/OverlayImage.xaml.cs +++ b/gui/OpenFaceOffline/UI_items/OverlayImage.xaml.cs @@ -100,13 +100,20 @@ namespace OpenFaceOffline var width = ((WriteableBitmap)Source).PixelWidth; var height = ((WriteableBitmap)Source).PixelHeight; + // The point and line size should be proportional to the face size and the image scaling + double scaling_p = 0.88 * FaceScale * ActualWidth / width; + + // Don't let it get too small + if (scaling_p < 0.6) + scaling_p = 0.6; + foreach (var line in OverlayLines) { var p1 = new Point(ActualWidth * line.Item1.X / width, ActualHeight * line.Item1.Y / height); var p2 = new Point(ActualWidth * line.Item2.X / width, ActualHeight * line.Item2.Y / height); - - dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(100 + (155 * (1 - Confidence))), (byte)(100 + (155 * Confidence)), 100)), 2), p1, p2); + + dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(100 + (155 * (1 - Confidence))), (byte)(100 + (155 * Confidence)), 100)), 2.0 * scaling_p), p1, p2); } foreach (var line in GazeLines) @@ -115,7 +122,7 @@ namespace OpenFaceOffline var p1 = new Point(ActualWidth * line.Item1.X / width, ActualHeight * line.Item1.Y / height); var p2 = new Point(ActualWidth * line.Item2.X / width, ActualHeight * line.Item2.Y / height); - dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(240), (byte)(30), (byte)100)), 3), p1, p2); + dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(240), (byte)(30), (byte)100)), 3.0 * scaling_p), p1, p2); } @@ -124,7 +131,8 @@ namespace OpenFaceOffline var q = new Point(ActualWidth * p.X / width, ActualHeight * p.Y / height); - dc.DrawEllipse(new SolidColorBrush(Color.FromArgb((byte)(200 * Confidence), 255, 255, 100)), null, q, 1, 1); + dc.DrawEllipse(new SolidColorBrush(Color.FromArgb((byte)(230 * Confidence), 255, 50, 50)), null, q, 2.75 * scaling_p, 2.75 * scaling_p); + dc.DrawEllipse(new SolidColorBrush(Color.FromArgb((byte)(230 * Confidence), 255, 255, 100)), null, q, 1.75 * scaling_p, 1.75 * scaling_p); } for (int id = 0; id < OverlayEyePoints.Count; id++) @@ -146,11 +154,11 @@ namespace OpenFaceOffline if (id < 28 && (id < 8 || id > 19) || (id>=28 &&(id-28<8 || id-28 >19))) { - dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(240), (byte)(30), (byte)100)), 1), q1, q2); + dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(240), (byte)(30), (byte)100)), 1.5 * scaling_p), q1, q2); } else { - dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(100), (byte)(30), (byte)240)), 1), q1, q2); + dc.DrawLine(new Pen(new SolidColorBrush(Color.FromArgb(200, (byte)(100), (byte)(30), (byte)240)), 2.5 * scaling_p), q1, q2); } } @@ -190,6 +198,7 @@ namespace OpenFaceOffline public List OverlayEyePoints { get; set; } public double Confidence { get; set; } public double FPS { get; set; } + public double FaceScale { get; set; } // 0 to 1 indicates how much video has been processed so far public double Progress { get; set; }