diff --git a/OpenFace.sln b/OpenFace.sln index 73c1f0b..5895f19 100644 --- a/OpenFace.sln +++ b/OpenFace.sln @@ -125,8 +125,8 @@ Global {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|Win32.Build.0 = Debug|x86 {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|x64.ActiveCfg = Debug|Any CPU {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|x64.Build.0 = Debug|Any CPU - {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|Win32.ActiveCfg = Release|Any CPU - {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|Win32.Build.0 = Release|Any CPU + {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|Win32.ActiveCfg = Release|x86 + {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|Win32.Build.0 = Release|x86 {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|x64.ActiveCfg = Release|Any CPU {A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection diff --git a/gui/OpenFace-offline/App.config b/gui/OpenFace-offline/App.config deleted file mode 100644 index 88fa402..0000000 --- a/gui/OpenFace-offline/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/gui/OpenFace-offline/App.xaml b/gui/OpenFace-offline/App.xaml deleted file mode 100644 index a7c9cab..0000000 --- a/gui/OpenFace-offline/App.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/gui/OpenFace-offline/App.xaml.cs b/gui/OpenFace-offline/App.xaml.cs deleted file mode 100644 index 21fd742..0000000 --- a/gui/OpenFace-offline/App.xaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application - { - } -} diff --git a/gui/OpenFace-offline/FpsTracker.cs b/gui/OpenFace-offline/FpsTracker.cs deleted file mode 100644 index a7f2ee7..0000000 --- a/gui/OpenFace-offline/FpsTracker.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace OpenFaceOffline -{ - public class FpsTracker - { - public TimeSpan HistoryLength { get; set; } - public FpsTracker() - { - HistoryLength = TimeSpan.FromSeconds(2); - } - - private Queue frameTimes = new Queue(); - - private void DiscardOldFrames() - { - while (frameTimes.Count > 0 && (MainWindow.CurrentTime - frameTimes.Peek()) > HistoryLength) - frameTimes.Dequeue(); - } - - public void AddFrame() - { - frameTimes.Enqueue(MainWindow.CurrentTime); - DiscardOldFrames(); - } - - public double GetFPS() - { - DiscardOldFrames(); - - if (frameTimes.Count == 0) - return 0; - - return frameTimes.Count / (MainWindow.CurrentTime - frameTimes.Peek()).TotalSeconds; - } - } -} diff --git a/gui/OpenFace-offline/MainWindow.xaml b/gui/OpenFace-offline/MainWindow.xaml deleted file mode 100644 index ea38aad..0000000 --- a/gui/OpenFace-offline/MainWindow.xaml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Appearance features - - - - - - - - - - - - - - - - - - - - - Geometry features - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Action Units - - - - - Classification - - - - - - - Regression - - - - - - - - - - - - - - - diff --git a/gui/OpenFace-offline/MainWindow.xaml.cs b/gui/OpenFace-offline/MainWindow.xaml.cs deleted file mode 100644 index 2417eb0..0000000 --- a/gui/OpenFace-offline/MainWindow.xaml.cs +++ /dev/null @@ -1,1249 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; -using Microsoft.Win32; - -using OpenCVWrappers; -using CppInterop; -using CppInterop.LandmarkDetector; -using CameraInterop; -using FaceAnalyser_Interop; -using System.Windows.Threading; -using System.IO; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : Window - { - - // Timing for measuring FPS - #region High-Resolution Timing - static DateTime startTime; - static Stopwatch sw = new Stopwatch(); - - static MainWindow() - { - startTime = DateTime.Now; - sw.Start(); - } - - public static DateTime CurrentTime - { - get { return startTime + sw.Elapsed; } - } - #endregion - - Thread processing_thread; - - // Some members for displaying the results - private Capture capture; - private WriteableBitmap latest_img; - private WriteableBitmap latest_aligned_face; - private WriteableBitmap latest_HOG_descriptor; - - // Managing the running of the analysis system - private volatile bool thread_running; - private volatile bool thread_paused = false; - // Allows for going forward in time step by step - // Useful for visualising things - private volatile int skip_frames = 0; - - FpsTracker processing_fps = new FpsTracker(); - - volatile bool detectionSucceeding = false; - - volatile bool reset = false; - - // For tracking - FaceModelParameters clnf_params; - CLNF clnf_model; - FaceAnalyserManaged face_analyser; - - // Recording parameters (default values) - bool record_aus = false; // Recording Action Units - bool record_pose = false; // head location and orientation - bool record_params = false; // rigid and non-rigid shape parameters - bool record_2D_landmarks = false; // 2D landmark location - bool record_3D_landmarks = false; // 3D landmark locations in world coordinates - bool record_HOG = false; // HOG features extracted from face images - bool record_gaze = false; // Gaze recording - bool record_aligned = false; // aligned face images - bool record_tracked_vid = false; - - // Visualisation options - bool show_tracked_video = true; - bool show_appearance = true; - bool show_geometry = true; - bool show_aus = true; - - // TODO classifiers converted to regressors - - // TODO indication that track is done - - // The recording managers - StreamWriter output_head_pose_file; - StreamWriter output_clnf_params_file; - StreamWriter output_2D_landmarks_file; - StreamWriter output_3D_landmarks_file; - StreamWriter output_au_class; - StreamWriter output_au_reg; - StreamWriter output_gaze; - - // Where the recording is done (by default in a record directory, from where the application executed) - String record_root = "./record"; - - // For AU visualisation and output - List au_class_names; - List au_reg_names; - - // For AU prediction - bool dynamic_AU_shift = true; - bool dynamic_AU_scale = false; - bool use_dynamic_models = true; - - private volatile bool mirror_image = false; - - public MainWindow() - { - InitializeComponent(); - - // Set the icon - Uri iconUri = new Uri("logo1.ico", UriKind.RelativeOrAbsolute); - this.Icon = BitmapFrame.Create(iconUri); - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 2000), (Action)(() => - { - RecordAUCheckBox.IsChecked = record_aus; - RecordAlignedCheckBox.IsChecked = record_aligned; - RecordTrackedVidCheckBox.IsChecked = record_tracked_vid; - RecordHOGCheckBox.IsChecked = record_HOG; - RecordGazeCheckBox.IsChecked = record_gaze; - RecordLandmarks2DCheckBox.IsChecked = record_2D_landmarks; - RecordLandmarks3DCheckBox.IsChecked = record_3D_landmarks; - RecordParamsCheckBox.IsChecked = record_params; - RecordPoseCheckBox.IsChecked = record_pose; - - UseDynamicModelsCheckBox.IsChecked = use_dynamic_models; - UseDynamicScalingCheckBox.IsChecked = dynamic_AU_scale; - UseDynamicShiftingCheckBox.IsChecked = dynamic_AU_shift; - })); - - String root = AppDomain.CurrentDomain.BaseDirectory; - - clnf_params = new FaceModelParameters(root); - clnf_model = new CLNF(clnf_params); - face_analyser = new FaceAnalyserManaged(root, use_dynamic_models); - - } - - private bool ProcessFrame(CLNF clnf_model, FaceModelParameters clnf_params, RawImage frame, RawImage grayscale_frame, double fx, double fy, double cx, double cy) - { - detectionSucceeding = clnf_model.DetectLandmarksInVideo(grayscale_frame, clnf_params); - return detectionSucceeding; - - } - - private List>> ProcessImage(CLNF clnf_model, FaceModelParameters clnf_params, RawImage frame, RawImage grayscale_frame) - { - List>> landmark_detections = clnf_model.DetectMultiFaceLandmarksInImage(grayscale_frame, clnf_params); - return landmark_detections; - - } - - private void SetupRecording(String root, String filename, int width, int height) - { - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - RecordingMenu.IsEnabled = false; - UseDynamicModelsCheckBox.IsEnabled = false; - })); - - if (!System.IO.Directory.Exists(root)) - { - System.IO.Directory.CreateDirectory(root); - } - - if (record_pose) - { - String filename_poses = root + "/" + filename + ".pose"; - output_head_pose_file = new StreamWriter(filename_poses); - output_head_pose_file.WriteLine("frame,success,confidence,pose_X(mm),pose_Y(mm),pose_Z(mm),pitch(rad),yaw(rad),roll(rad)"); - } - - if (record_params) - { - String filename_params = root + "/" + filename + ".params"; - output_clnf_params_file = new StreamWriter(filename_params); - - output_clnf_params_file.Write("frame,success,confidence,scale,rot_x,rot_y,rot_z,tx,ty"); - for (int i = 0; i < clnf_model.GetNumModes(); ++i) - { - output_clnf_params_file.Write(",p" + i); - } - output_clnf_params_file.WriteLine(); - } - - if (record_2D_landmarks) - { - String filename_2d_landmarks = root + "/" + filename + ".landmarks_2d"; - output_2D_landmarks_file = new StreamWriter(filename_2d_landmarks); - - output_2D_landmarks_file.Write("frame,success,confidence"); - for (int i = 0; i < clnf_model.GetNumPoints(); ++i) - { - output_2D_landmarks_file.Write(",x" + i); - } - for (int i = 0; i < clnf_model.GetNumPoints(); ++i) - { - output_2D_landmarks_file.Write(",y" + i); - } - output_2D_landmarks_file.WriteLine(); - } - - if (record_aus) - { - String filename_au_class = root + "/" + filename + ".au_class"; - output_au_class = new StreamWriter(filename_au_class); - - output_au_class.Write("frame,success,confidence"); - au_class_names = face_analyser.GetClassActionUnitsNames(); - au_class_names.Sort(); - foreach (var name in au_class_names) - { - output_au_class.Write("," + name); - } - output_au_class.WriteLine(); - - String filename_au_reg = root + "/" + filename + ".au_reg"; - output_au_reg = new StreamWriter(filename_au_reg); - - output_au_reg.Write("frame,success,confidence"); - au_reg_names = face_analyser.GetRegActionUnitsNames(); - au_reg_names.Sort(); - foreach (var name in au_reg_names) - { - output_au_reg.Write("," + name); - } - output_au_reg.WriteLine(); - - } - - if (record_gaze) - { - String filename_gaze = root + "/" + filename + ".gaze"; - output_gaze = new StreamWriter(filename_gaze); - - output_gaze.Write("frame, success, confidence, x_0, y_0, z_0, x_1, y_1, z_1, x_h0, y_h0, z_h0, x_h1, y_h1, z_h1"); - } - - if (record_3D_landmarks) - { - String filename_3d_landmarks = root + "/" + filename + ".landmarks_3d"; - output_3D_landmarks_file = new StreamWriter(filename_3d_landmarks); - - output_3D_landmarks_file.Write("frame,success,confidence"); - for (int i = 0; i < clnf_model.GetNumPoints(); ++i) - { - output_3D_landmarks_file.Write(",X" + i); - } - for (int i = 0; i < clnf_model.GetNumPoints(); ++i) - { - output_3D_landmarks_file.Write(",Y" + i); - } - for (int i = 0; i < clnf_model.GetNumPoints(); ++i) - { - output_3D_landmarks_file.Write(",Z" + i); - } - output_3D_landmarks_file.WriteLine(); - } - - if (record_aligned) - { - String aligned_root = root + "/" + filename + "_aligned/"; - System.IO.Directory.CreateDirectory(aligned_root); - face_analyser.SetupAlignedImageRecording(aligned_root); - } - - if (record_tracked_vid) - { - String vid_loc = root + "/" + filename + ".avi"; - System.IO.Directory.CreateDirectory(root); - face_analyser.SetupTrackingRecording(vid_loc, width, height, 30); - } - - if (record_HOG) - { - String filename_HOG = root + "/" + filename + ".hog"; - face_analyser.SetupHOGRecording(filename_HOG); - } - - } - - private void StopRecording() - { - if (record_pose && output_head_pose_file != null) - output_head_pose_file.Close(); - - if (record_params && output_clnf_params_file != null) - output_clnf_params_file.Close(); - - if (record_2D_landmarks && output_2D_landmarks_file != null) - output_2D_landmarks_file.Close(); - - if (record_3D_landmarks && output_3D_landmarks_file != null) - output_3D_landmarks_file.Close(); - - if (record_gaze && output_gaze != null) - output_gaze.Close(); - - if (record_HOG) - face_analyser.StopHOGRecording(); - - if (record_tracked_vid) - face_analyser.StopTrackingRecording(); - - if (record_aus && output_au_class != null && output_au_reg != null) - { - output_au_class.Close(); - output_au_reg.Close(); - } - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - RecordingMenu.IsEnabled = true; - UseDynamicModelsCheckBox.IsEnabled = true; - - })); - - } - - // Recording the relevant objects - private void RecordFrame(CLNF clnf_model, bool success_b, int frame_ind, RawImage frame, RawImage grayscale_frame, double fx, double fy, double cx, double cy) - { - double confidence = (-clnf_model.GetConfidence()) / 2.0 + 0.5; - - List pose = new List(); - clnf_model.GetCorrectedPoseWorld(pose, fx, fy, cx, cy); - - int success = 0; - if (success_b) - success = 1; - - if (record_pose) - { - String pose_string = String.Format("{0},{1},{2:F3},{3:F3},{4:F3},{5:F3},{6:F3},{7:F3},{8:F3}", frame_ind, success, confidence, pose[0], pose[1], pose[2], pose[3], pose[4], pose[5]); - output_head_pose_file.WriteLine(pose_string); - } - - if (record_params) - { - output_clnf_params_file.Write(String.Format("{0},{1},{2,0:F3}", frame_ind, success, confidence)); - - List all_params = clnf_model.GetParams(); - - for (int i = 0; i < all_params.Count; ++i) - { - String param = String.Format("{0,0:F5}", all_params[i]); - output_clnf_params_file.Write("," + param); - } - output_clnf_params_file.WriteLine(); - } - - if (record_2D_landmarks) - { - List> landmarks_2d = clnf_model.CalculateLandmarks(); - - output_2D_landmarks_file.Write(String.Format("{0},{1},{2:F3}", frame_ind, success, confidence)); - - for (int i = 0; i < landmarks_2d.Count; ++i) - { - output_2D_landmarks_file.Write(",{0:F2}", landmarks_2d[i].Item1); - } - for (int i = 0; i < landmarks_2d.Count; ++i) - { - output_2D_landmarks_file.Write(",{0:F2}", landmarks_2d[i].Item2); - } - output_2D_landmarks_file.WriteLine(); - } - - if (record_3D_landmarks) - { - List landmarks_3d = clnf_model.Calculate3DLandmarks(fx, fy, cx, cy); - - output_3D_landmarks_file.Write(String.Format("{0},{1},{2:F3}", frame_ind, success, confidence)); - - for (int i = 0; i < landmarks_3d.Count; ++i) - { - output_3D_landmarks_file.Write(",{0:F2}", landmarks_3d[i].X); - } - for (int i = 0; i < landmarks_3d.Count; ++i) - { - output_3D_landmarks_file.Write(",{0:F2}", landmarks_3d[i].Y); - } - for (int i = 0; i < landmarks_3d.Count; ++i) - { - output_3D_landmarks_file.Write(",{0:F2}", landmarks_3d[i].Z); - } - output_3D_landmarks_file.WriteLine(); - } - - if (record_aus) - { - var au_classes = face_analyser.GetCurrentAUsClass(); - var au_regs = face_analyser.GetCurrentAUsReg(); - - output_au_class.Write(String.Format("{0},{1},{2:F3}", frame_ind, success, confidence)); - - foreach (var name_class in au_class_names) - { - output_au_class.Write(",{0:F0}", au_classes[name_class]); - } - output_au_class.WriteLine(); - - output_au_reg.Write(String.Format("{0},{1},{2:F3}", frame_ind, success, confidence)); - - foreach (var name_reg in au_reg_names) - { - output_au_reg.Write(",{0:F2}", au_regs[name_reg]); - } - output_au_reg.WriteLine(); - - } - - if (record_gaze) - { - - var gaze_cam = face_analyser.GetGazeCamera(); - - output_gaze.Write(String.Format("{0},{1},{2:F3}", frame_ind, success, confidence)); - - output_gaze.Write(String.Format(",{0:F3},{1:F3},{2:F3},{3:F3},{4:F3},{5:F3}", gaze_cam.Item1.Item1, gaze_cam.Item1.Item2, gaze_cam.Item1.Item3, - gaze_cam.Item2.Item1, gaze_cam.Item2.Item2, gaze_cam.Item2.Item3)); - - output_gaze.WriteLine(); - - } - - if (record_aligned) - { - face_analyser.RecordAlignedFrame(frame_ind); - } - - if (record_HOG) - { - face_analyser.RecordHOGFrame(); - } - - if (record_tracked_vid) - { - face_analyser.RecordTrackedFace(); - } - } - - // The main function call for processing images, video files or webcam feed - private void ProcessingLoop(String[] filenames, int cam_id = -1, int width = -1, int height = -1, bool multi_face = false) - { - - thread_running = true; - - mirror_image = false; - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - ResetButton.IsEnabled = true; - PauseButton.IsEnabled = true; - StopButton.IsEnabled = true; - })); - - // Create the video capture and call the VideoLoop - if (filenames != null) - { - clnf_params.optimiseForVideo(); - if (cam_id == -2) - { - List image_files_all = new List(); - foreach (string image_name in filenames) - image_files_all.Add(image_name); - - // Loading an image sequence that represents a video - capture = new Capture(image_files_all); - - if (capture.isOpened()) - { - // Prepare recording if any based on the directory - String file_no_ext = System.IO.Path.GetDirectoryName(filenames[0]); - file_no_ext = System.IO.Path.GetFileName(file_no_ext); - SetupRecording(record_root, file_no_ext, capture.width, capture.height); - - // Start the actual processing - VideoLoop(); - - // Clear up the recording - StopRecording(); - - } - else - { - string messageBoxText = "Failed to open an image"; - string caption = "Not valid file"; - MessageBoxButton button = MessageBoxButton.OK; - MessageBoxImage icon = MessageBoxImage.Warning; - - // Display message box - MessageBox.Show(messageBoxText, caption, button, icon); - } - } - else if (cam_id == -3) - { - SetupImageMode(); - clnf_params.optimiseForImages(); - // Loading an image file (or a number of them) - foreach (string filename in filenames) - { - if (!thread_running) - { - continue; - } - - capture = new Capture(filename); - - if (capture.isOpened()) - { - // Start the actual processing - ProcessImage(); - - } - else - { - string messageBoxText = "File is not an image or the decoder is not supported."; - string caption = "Not valid file"; - MessageBoxButton button = MessageBoxButton.OK; - MessageBoxImage icon = MessageBoxImage.Warning; - - // Display message box - MessageBox.Show(messageBoxText, caption, button, icon); - } - } - } - else - { - clnf_params.optimiseForVideo(); - // Loading a video file (or a number of them) - foreach (string filename in filenames) - { - if (!thread_running) - { - continue; - } - - capture = new Capture(filename); - - if (capture.isOpened()) - { - // Prepare recording if any - String file_no_ext = System.IO.Path.GetFileNameWithoutExtension(filename); - - SetupRecording(record_root, file_no_ext, capture.width, capture.height); - - // Start the actual processing - VideoLoop(); - - // Clear up the recording - StopRecording(); - } - else - { - string messageBoxText = "File is not a video or the codec is not supported."; - string caption = "Not valid file"; - MessageBoxButton button = MessageBoxButton.OK; - MessageBoxImage icon = MessageBoxImage.Warning; - - // Display message box - MessageBox.Show(messageBoxText, caption, button, icon); - } - } - } - } - else - { - capture = new Capture(cam_id, width, height); - mirror_image = true; - - if (capture.isOpened()) - { - // Prepare recording if any - String dir_out = DateTime.Now.ToString("yyyy-MMM-dd--HH-mm"); - - SetupRecording(record_root + "/" + dir_out, "webcam", width, height); - - // Start the actual processing - VideoLoop(); - - StopRecording(); - } - else - { - - string messageBoxText = "Failed to open a webcam"; - string caption = "Webcam failure"; - MessageBoxButton button = MessageBoxButton.OK; - MessageBoxImage icon = MessageBoxImage.Warning; - - // Display message box - MessageBox.Show(messageBoxText, caption, button, icon); - } - } - - // TODO this should be up a level - // Some GUI clean up - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - Console.WriteLine("Cleaning up after processing is done"); - PauseButton.IsEnabled = false; - StopButton.IsEnabled = false; - ResetButton.IsEnabled = false; - NextFiveFramesButton.IsEnabled = false; - NextFrameButton.IsEnabled = false; - })); - - } - - // Capturing and processing the video frame by frame - private void ProcessImage() - { - Thread.CurrentThread.IsBackground = true; - - clnf_model.Reset(); - face_analyser.Reset(); - - - ////////////////////////////////////////////// - // CAPTURE FRAME AND DETECT LANDMARKS FOLLOWED BY THE REQUIRED IMAGE PROCESSING - ////////////////////////////////////////////// - RawImage frame = null; - double progress = -1; - - frame = new RawImage(capture.GetNextFrame(mirror_image)); - progress = capture.GetProgress(); - - if (frame.Width == 0) - { - // This indicates that we reached the end of the video file - return; - } - - var grayFrame = new RawImage(capture.GetCurrentFrameGray()); - - if (grayFrame == null) - { - Console.WriteLine("Gray is empty"); - return; - } - - List>> landmark_detections = ProcessImage(clnf_model, clnf_params, frame, grayFrame); - - List landmark_points = new List(); - - for (int i = 0; i < landmark_detections.Count; ++i) - { - - List> landmarks = landmark_detections[i]; - foreach (var p in landmarks) - { - landmark_points.Add(new Point(p.Item1, p.Item2)); - } - } - - // Visualisation - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - if (show_tracked_video) - { - if (latest_img == null) - { - latest_img = frame.CreateWriteableBitmap(); - } - - frame.UpdateWriteableBitmap(latest_img); - - video.Source = latest_img; - video.Confidence = 1; - video.FPS = processing_fps.GetFPS(); - video.Progress = progress; - - video.OverlayLines = new List>(); - - video.OverlayPoints = landmark_points; - } - - })); - - latest_img = null; - } - - - // Capturing and processing the video frame by frame - private void VideoLoop() - { - Thread.CurrentThread.IsBackground = true; - - DateTime? startTime = CurrentTime; - - var lastFrameTime = CurrentTime; - - clnf_model.Reset(); - face_analyser.Reset(); - - // TODO add an ability to change these through a calibration procedure or setting menu - double fx, fy, cx, cy; - fx = 500.0; - fy = 500.0; - cx = cy = -1; - - int frame_id = 0; - - while (thread_running) - { - ////////////////////////////////////////////// - // CAPTURE FRAME AND DETECT LANDMARKS FOLLOWED BY THE REQUIRED IMAGE PROCESSING - ////////////////////////////////////////////// - RawImage frame = null; - double progress = -1; - - frame = new RawImage(capture.GetNextFrame(mirror_image)); - progress = capture.GetProgress(); - - if (frame.Width == 0) - { - // This indicates that we reached the end of the video file - break; - } - - // TODO stop button actually clears the video - - lastFrameTime = CurrentTime; - processing_fps.AddFrame(); - - var grayFrame = new RawImage(capture.GetCurrentFrameGray()); - - if (grayFrame == null) - { - Console.WriteLine("Gray is empty"); - continue; - } - - // This is more ore less guess work, but seems to work well enough - if (cx == -1) - { - fx = fx * (grayFrame.Width / 640.0); - fy = fy * (grayFrame.Height / 480.0); - - fx = (fx + fy) / 2.0; - fy = fx; - - 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; - - if (confidence < 0) - confidence = 0; - else if (confidence > 1) - confidence = 1; - - List pose = new List(); - clnf_model.GetCorrectedPoseWorld(pose, fx, fy, cx, cy); - List non_rigid_params = clnf_model.GetNonRigidParams(); - - // The face analysis step (only done if recording AUs, HOGs or video) - if (record_aus || record_HOG || record_aligned || show_aus || show_appearance || record_tracked_vid || record_gaze) - { - face_analyser.AddNextFrame(frame, clnf_model, fx, fy, cx, cy, false, show_appearance, record_tracked_vid); - } - - List> lines = null; - List> landmarks = null; - List> gaze_lines = null; - - if (detectionSucceeding) - { - landmarks = clnf_model.CalculateLandmarks(); - lines = clnf_model.CalculateBox((float)fx, (float)fy, (float)cx, (float)cy); - gaze_lines = face_analyser.CalculateGazeLines((float)fx, (float)fy, (float)cx, (float)cy); - - } - - // Visualisation - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - if (show_aus) - { - var au_classes = face_analyser.GetCurrentAUsClass(); - var au_regs = face_analyser.GetCurrentAUsReg(); - - auClassGraph.Update(au_classes); - - var au_regs_scaled = new Dictionary(); - foreach (var au_reg in au_regs) - { - au_regs_scaled[au_reg.Key] = au_reg.Value / 5.0; - if (au_regs_scaled[au_reg.Key] < 0) - au_regs_scaled[au_reg.Key] = 0; - - if (au_regs_scaled[au_reg.Key] > 1) - au_regs_scaled[au_reg.Key] = 1; - } - auRegGraph.Update(au_regs_scaled); - } - - if (show_geometry) - { - int yaw = (int)(pose[4] * 180 / Math.PI + 0.5); - int roll = (int)(pose[5] * 180 / Math.PI + 0.5); - int pitch = (int)(pose[3] * 180 / Math.PI + 0.5); - - YawLabel.Content = yaw + "°"; - RollLabel.Content = roll + "°"; - PitchLabel.Content = pitch + "°"; - - XPoseLabel.Content = (int)pose[0] + " mm"; - YPoseLabel.Content = (int)pose[1] + " mm"; - ZPoseLabel.Content = (int)pose[2] + " mm"; - - nonRigidGraph.Update(non_rigid_params); - - // Update eye gaze - var gaze_both = face_analyser.GetGazeCamera(); - double x = (gaze_both.Item1.Item1 + gaze_both.Item2.Item1) / 2.0; - double y = (gaze_both.Item1.Item2 + gaze_both.Item2.Item2) / 2.0; - - // Tweak it to a more presentable value - x = (int)(x * 35); - y = (int)(y * 70); - - if (x < -10) - x = -10; - if (x > 10) - x = 10; - if (y < -10) - y = -10; - if (y > 10) - y = 10; - - GazeXLabel.Content = x / 10.0; - GazeYLabel.Content = y / 10.0; - - - } - - if (show_tracked_video) - { - if (latest_img == null) - { - latest_img = frame.CreateWriteableBitmap(); - } - - frame.UpdateWriteableBitmap(latest_img); - - video.Source = latest_img; - video.Confidence = confidence; - video.FPS = processing_fps.GetFPS(); - video.Progress = progress; - - if (!detectionSucceeding) - { - video.OverlayLines.Clear(); - video.OverlayPoints.Clear(); - video.GazeLines.Clear(); - } - else - { - video.OverlayLines = lines; - - List landmark_points = new List(); - foreach (var p in landmarks) - { - landmark_points.Add(new Point(p.Item1, p.Item2)); - } - - video.OverlayPoints = landmark_points; - - video.GazeLines = gaze_lines; - } - } - - if (show_appearance) - { - RawImage aligned_face = face_analyser.GetLatestAlignedFace(); - RawImage hog_face = face_analyser.GetLatestHOGDescriptorVisualisation(); - - if (latest_aligned_face == null) - { - latest_aligned_face = aligned_face.CreateWriteableBitmap(); - latest_HOG_descriptor = hog_face.CreateWriteableBitmap(); - } - - aligned_face.UpdateWriteableBitmap(latest_aligned_face); - hog_face.UpdateWriteableBitmap(latest_HOG_descriptor); - - AlignedFace.Source = latest_aligned_face; - AlignedHOG.Source = latest_HOG_descriptor; - } - })); - - // Recording the tracked model - RecordFrame(clnf_model, detectionSucceeding, frame_id, frame, grayFrame, fx, fy, cx, cy); - - if (reset) - { - clnf_model.Reset(); - face_analyser.Reset(); - reset = false; - } - - while (thread_running & thread_paused && skip_frames == 0) - { - Thread.Sleep(10); - } - - frame_id++; - - if (skip_frames > 0) - skip_frames--; - - } - - latest_img = null; - skip_frames = 0; - - // Unpause if it's paused - if (thread_paused) - { - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() => - { - PauseButton_Click(null, null); - })); - } - } - - private void StopTracking() - { - // First complete the running of the thread - if (processing_thread != null) - { - // Tell the other thread to finish - thread_running = false; - processing_thread.Join(); - } - } - - private void imageFileOpenClick(object sender, RoutedEventArgs e) - { - new Thread(() => imageOpen()).Start(); - } - - private void imageOpen() - { - StopTracking(); - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 2, 0), (Action)(() => - { - var d = new OpenFileDialog(); - d.Multiselect = true; - d.Filter = "Image files|*.jpg;*.jpeg;*.bmp;*.png;*.gif"; - - if (d.ShowDialog(this) == true) - { - - string[] image_files = d.FileNames; - - processing_thread = new Thread(() => ProcessingLoop(image_files, -3)); - processing_thread.Start(); - - } - })); - } - - private void videoFileOpenClick(object sender, RoutedEventArgs e) - { - new Thread(() => openVideoFile()).Start(); - } - - private void openVideoFile() - { - StopTracking(); - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 2, 0), (Action)(() => - { - var d = new OpenFileDialog(); - d.Multiselect = true; - d.Filter = "Video files|*.avi;*.wmv;*.mov;*.mpg;*.mpeg;*.mp4"; - - if (d.ShowDialog(this) == true) - { - - string[] video_files = d.FileNames; - - processing_thread = new Thread(() => ProcessingLoop(video_files)); - processing_thread.Start(); - - } - })); - } - - private void imageSequenceFileOpenClick(object sender, RoutedEventArgs e) - { - new Thread(() => imageSequenceOpen()).Start(); - } - - private void imageSequenceOpen() - { - StopTracking(); - - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 2, 0), (Action)(() => - { - var d = new OpenFileDialog(); - d.Multiselect = true; - d.Filter = "Image files|*.jpg;*.jpeg;*.bmp;*.png;*.gif"; - - if (d.ShowDialog(this) == true) - { - - string[] image_files = d.FileNames; - - processing_thread = new Thread(() => ProcessingLoop(image_files, -2)); - processing_thread.Start(); - - } - })); - } - - private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) - { - if (processing_thread != null) - { - // Stop capture and tracking - thread_running = false; - processing_thread.Join(); - - capture.Dispose(); - } - face_analyser.Dispose(); - } - - // Stopping the tracking - private void StopButton_Click(object sender, RoutedEventArgs e) - { - if (processing_thread != null) - { - // Stop capture and tracking - thread_paused = false; - thread_running = false; - processing_thread.Join(); - - PauseButton.IsEnabled = false; - NextFrameButton.IsEnabled = false; - NextFiveFramesButton.IsEnabled = false; - StopButton.IsEnabled = false; - ResetButton.IsEnabled = false; - RecordingMenu.IsEnabled = true; - - UseDynamicModelsCheckBox.IsEnabled = true; - } - } - - // Stopping the tracking - private void ResetButton_Click(object sender, RoutedEventArgs e) - { - if (processing_thread != null) - { - // Stop capture and tracking - reset = true; - } - } - - // Stopping the tracking - private void PauseButton_Click(object sender, RoutedEventArgs e) - { - if (processing_thread != null) - { - // Stop capture and tracking - thread_paused = !thread_paused; - - ResetButton.IsEnabled = !thread_paused; - - NextFrameButton.IsEnabled = thread_paused; - NextFiveFramesButton.IsEnabled = thread_paused; - - if (thread_paused) - { - PauseButton.Content = "Resume"; - } - else - { - PauseButton.Content = "Pause"; - } - } - } - - private void SkipButton_Click(object sender, RoutedEventArgs e) - { - if (sender.Equals(NextFrameButton)) - { - skip_frames += 1; - } - else if (sender.Equals(NextFiveFramesButton)) - { - skip_frames += 5; - } - } - - private void VisualisationCheckBox_Click(object sender, RoutedEventArgs e) - { - show_tracked_video = ShowVideoCheckBox.IsChecked; - show_appearance = ShowAppearanceFeaturesCheckBox.IsChecked; - show_geometry = ShowGeometryFeaturesCheckBox.IsChecked; - show_aus = ShowAUsCheckBox.IsChecked; - - // Collapsing or restoring the windows here - if (!show_tracked_video) - { - VideoBorder.Visibility = System.Windows.Visibility.Collapsed; - MainGrid.ColumnDefinitions[0].Width = new GridLength(0, GridUnitType.Star); - } - else - { - VideoBorder.Visibility = System.Windows.Visibility.Visible; - MainGrid.ColumnDefinitions[0].Width = new GridLength(2.1, GridUnitType.Star); - } - - if (!show_appearance) - { - AppearanceBorder.Visibility = System.Windows.Visibility.Collapsed; - MainGrid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Star); - } - else - { - AppearanceBorder.Visibility = System.Windows.Visibility.Visible; - MainGrid.ColumnDefinitions[1].Width = new GridLength(0.8, GridUnitType.Star); - } - - // Collapsing or restoring the windows here - if (!show_geometry) - { - GeometryBorder.Visibility = System.Windows.Visibility.Collapsed; - MainGrid.ColumnDefinitions[2].Width = new GridLength(0, GridUnitType.Star); - } - else - { - GeometryBorder.Visibility = System.Windows.Visibility.Visible; - MainGrid.ColumnDefinitions[2].Width = new GridLength(1.0, GridUnitType.Star); - } - - // Collapsing or restoring the windows here - if (!show_aus) - { - ActionUnitBorder.Visibility = System.Windows.Visibility.Collapsed; - MainGrid.ColumnDefinitions[3].Width = new GridLength(0, GridUnitType.Star); - } - else - { - ActionUnitBorder.Visibility = System.Windows.Visibility.Visible; - MainGrid.ColumnDefinitions[3].Width = new GridLength(1.6, GridUnitType.Star); - } - - } - - private void SetupImageMode() - { - // Turn off recording - record_aus = false; - record_aligned = false; - record_HOG = false; - record_gaze = false; - record_tracked_vid = false; - record_2D_landmarks = false; - record_3D_landmarks = false; - record_params = false; - record_pose = false; - - // Turn off unneeded visualisations - show_tracked_video = true; - show_appearance = false; - show_geometry = false; - show_aus = false; - - // Actually update the GUI accordingly - Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 2000), (Action)(() => - { - RecordAUCheckBox.IsChecked = record_aus; - RecordAlignedCheckBox.IsChecked = record_aligned; - RecordTrackedVidCheckBox.IsChecked = record_tracked_vid; - RecordHOGCheckBox.IsChecked = record_HOG; - RecordGazeCheckBox.IsChecked = record_gaze; - RecordLandmarks2DCheckBox.IsChecked = record_2D_landmarks; - RecordLandmarks3DCheckBox.IsChecked = record_3D_landmarks; - RecordParamsCheckBox.IsChecked = record_params; - RecordPoseCheckBox.IsChecked = record_pose; - - ShowVideoCheckBox.IsChecked = true; - ShowAppearanceFeaturesCheckBox.IsChecked = false; - ShowGeometryFeaturesCheckBox.IsChecked = false; - ShowAUsCheckBox.IsChecked = false; - - VisualisationCheckBox_Click(null, null); - })); - - // TODO change what next and back buttons do? - } - - private void recordCheckBox_click(object sender, RoutedEventArgs e) - { - record_aus = RecordAUCheckBox.IsChecked; - record_aligned = RecordAlignedCheckBox.IsChecked; - record_HOG = RecordHOGCheckBox.IsChecked; - record_gaze = RecordGazeCheckBox.IsChecked; - record_tracked_vid = RecordTrackedVidCheckBox.IsChecked; - record_2D_landmarks = RecordLandmarks2DCheckBox.IsChecked; - record_3D_landmarks = RecordLandmarks3DCheckBox.IsChecked; - record_params = RecordParamsCheckBox.IsChecked; - record_pose = RecordPoseCheckBox.IsChecked; - } - - private void UseDynamicModelsCheckBox_Click(object sender, RoutedEventArgs e) - { - dynamic_AU_shift = UseDynamicShiftingCheckBox.IsChecked; - dynamic_AU_scale = UseDynamicScalingCheckBox.IsChecked; - - if (use_dynamic_models != UseDynamicModelsCheckBox.IsChecked) - { - // Change the face analyser, this should be safe as the model is only allowed to change when not running - String root = AppDomain.CurrentDomain.BaseDirectory; - face_analyser = new FaceAnalyserManaged(root, UseDynamicModelsCheckBox.IsChecked); - } - use_dynamic_models = UseDynamicModelsCheckBox.IsChecked; - } - - } -} diff --git a/gui/OpenFace-offline/OpenFaceOffline.csproj b/gui/OpenFace-offline/OpenFaceOffline.csproj deleted file mode 100644 index 71f59c2..0000000 --- a/gui/OpenFace-offline/OpenFaceOffline.csproj +++ /dev/null @@ -1,178 +0,0 @@ - - - - - Debug - AnyCPU - {9661BE5C-2EE5-495E-BA64-6588602F411B} - WinExe - Properties - OpenFaceOffline - OpenFaceOffline - v4.5.2 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - - - - - - - true - ..\..\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - true - - - ..\..\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - - - true - ..\..\x64\Debug\ - DEBUG;TRACE - full - AnyCPU - prompt - MinimumRecommendedRules.ruleset - true - - - ..\..\x64\Release\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - BarGraph.xaml - - - - BarGraphHorizontal.xaml - - - MultiBarGraph.xaml - - - MultiBarGraphHorz.xaml - - - SimpleImage.xaml - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - OverlayImage.xaml - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - {78196985-ee54-411f-822b-5a23edf80642} - CppInerop - - - - - \ No newline at end of file diff --git a/gui/OpenFace-offline/Properties/AssemblyInfo.cs b/gui/OpenFace-offline/Properties/AssemblyInfo.cs deleted file mode 100644 index 75449e4..0000000 --- a/gui/OpenFace-offline/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("OpenFaceOffline")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("OpenFaceOffline")] -[assembly: AssemblyCopyright("Copyright © Cambridge 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/gui/OpenFace-offline/Properties/Resources.Designer.cs b/gui/OpenFace-offline/Properties/Resources.Designer.cs deleted file mode 100644 index a359eea..0000000 --- a/gui/OpenFace-offline/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace OpenFaceOffline.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenFaceOffline.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/gui/OpenFace-offline/Properties/Resources.resx b/gui/OpenFace-offline/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/gui/OpenFace-offline/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/gui/OpenFace-offline/Properties/Settings.Designer.cs b/gui/OpenFace-offline/Properties/Settings.Designer.cs deleted file mode 100644 index f31bb9d..0000000 --- a/gui/OpenFace-offline/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace OpenFaceOffline.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/gui/OpenFace-offline/Properties/Settings.settings b/gui/OpenFace-offline/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/gui/OpenFace-offline/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/gui/OpenFace-offline/UI_items/BarGraph.xaml b/gui/OpenFace-offline/UI_items/BarGraph.xaml deleted file mode 100644 index 2101d74..0000000 --- a/gui/OpenFace-offline/UI_items/BarGraph.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/gui/OpenFace-offline/UI_items/BarGraph.xaml.cs b/gui/OpenFace-offline/UI_items/BarGraph.xaml.cs deleted file mode 100644 index 0a089c7..0000000 --- a/gui/OpenFace-offline/UI_items/BarGraph.xaml.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Windows.Controls; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for BarGraph.xaml - /// - public partial class BarGraph : UserControl - { - private double targetValue = 0; - - public BarGraph() - { - InitializeComponent(); - } - - public void SetValue(double value) - { - targetValue = 1.5 * value; - if (targetValue > 0) - { - if (targetValue > barContainerPos.ActualHeight) - targetValue = barContainerPos.ActualHeight; - - barPos.Height = targetValue; - barNeg.Height = 0; - } - if (targetValue < 0) - { - if (-targetValue > barContainerNeg.ActualHeight) - targetValue = -barContainerNeg.ActualHeight; - - barPos.Height = 0; - barNeg.Height = -targetValue; - } - } - - } -} diff --git a/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml b/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml deleted file mode 100644 index f5ccbe5..0000000 --- a/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml.cs b/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml.cs deleted file mode 100644 index 8c18d4a..0000000 --- a/gui/OpenFace-offline/UI_items/BarGraphHorizontal.xaml.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for BarGraphHorizontal.xaml - /// - public partial class BarGraphHorizontal : UserControl - { - double targetValue = 0; - - public BarGraphHorizontal(String label) - { - InitializeComponent(); - Label.Content = label; - } - - public void SetValue(double value) - { - targetValue = value; - barPos.Width = targetValue * barContainerPos.ActualWidth; - } - - public double GetTarget() - { - return targetValue; - } - } -} diff --git a/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml b/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml deleted file mode 100644 index 836c974..0000000 --- a/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml.cs b/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml.cs deleted file mode 100644 index c101941..0000000 --- a/gui/OpenFace-offline/UI_items/MultiBarGraph.xaml.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for MultiBarGraph.xaml - /// - public partial class MultiBarGraph : UserControl - { - - int num_bars = 0; - List graphs; - - public MultiBarGraph() - { - InitializeComponent(); - - graphs = new List(); - } - - public void Update(List data) - { - // Create new bars if necessary - if (num_bars != data.Count) - { - num_bars = data.Count; - barGrid.Children.Clear(); - foreach (var value in data) - { - BarGraph newBar = new BarGraph(); - graphs.Add(newBar); - barGrid.ColumnDefinitions.Add(new ColumnDefinition()); - Grid.SetColumn(newBar, graphs.Count); - barGrid.Children.Add(newBar); - - } - } - - // Update the bars - for (int i = 0; i < data.Count; ++i) - { - graphs[i].SetValue(data[i]); - } - } - } -} diff --git a/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml b/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml deleted file mode 100644 index db5728f..0000000 --- a/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml.cs b/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml.cs deleted file mode 100644 index f960b71..0000000 --- a/gui/OpenFace-offline/UI_items/MultiBarGraphHorz.xaml.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for MultiBarGraphHorz.xaml - /// - public partial class MultiBarGraphHorz : UserControl - { - int num_bars = 0; - Dictionary graphs; - - // Name mapping - Dictionary mapping; - - public MultiBarGraphHorz() - { - InitializeComponent(); - - graphs = new Dictionary(); - - mapping = new Dictionary(); - mapping["AU01"] = "Inner Brow raiser"; - mapping["AU02"] = "Outer Brow raiser"; - mapping["AU04"] = "Brow lowerer"; - mapping["AU05"] = "Upper lid raiser"; - mapping["AU06"] = "Cheek raiser"; - mapping["AU07"] = "Lid tightener"; - mapping["AU09"] = "Nose wrinkler"; - mapping["AU10"] = "Upper lip raiser"; - mapping["AU12"] = "Lip corner puller (smile)"; - mapping["AU14"] = "Dimpler"; - mapping["AU15"] = "Lip corner depressor"; - mapping["AU17"] = "Chin Raiser"; - mapping["AU20"] = "Lip Stretcher"; - mapping["AU23"] = "Lip tightener"; - mapping["AU25"] = "Lips part"; - mapping["AU26"] = "Jaw drop"; - mapping["AU28"] = "Lip suck"; - mapping["AU45"] = "Blink"; - - - - } - - public void Update(Dictionary data) - { - // Create new bars if necessary - if (num_bars != data.Count) - { - num_bars = data.Count; - barGrid.Children.Clear(); - - // Make sure AUs are sorted - var data_labels = data.Keys.ToList(); - data_labels.Sort(); - - foreach (var label in data_labels) - { - BarGraphHorizontal newBar = new BarGraphHorizontal(label + " - " + mapping[label]); - barGrid.RowDefinitions.Add(new RowDefinition()); - Grid.SetRow(newBar, graphs.Count); - graphs.Add(label, newBar); - barGrid.Children.Add(newBar); - } - } - - // Update the bars - foreach (var value in data) - { - double old_value = graphs[value.Key].GetTarget(); - // some smoothing as well - graphs[value.Key].SetValue(old_value * 0.15 + 0.85 * value.Value); - } - } - } -} diff --git a/gui/OpenFace-offline/UI_items/OverlayImage.xaml b/gui/OpenFace-offline/UI_items/OverlayImage.xaml deleted file mode 100644 index 8dcdaea..0000000 --- a/gui/OpenFace-offline/UI_items/OverlayImage.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - \ No newline at end of file diff --git a/gui/OpenFace-offline/UI_items/OverlayImage.xaml.cs b/gui/OpenFace-offline/UI_items/OverlayImage.xaml.cs deleted file mode 100644 index 4546fec..0000000 --- a/gui/OpenFace-offline/UI_items/OverlayImage.xaml.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for OverlayImage.xaml - /// - public partial class OverlayImage : Image - { - public OverlayImage() - { - InitializeComponent(); - OverlayLines = new List>(); - OverlayPoints = new List(); - GazeLines = new List>(); - - Progress = -1; - } - - protected override void OnRender(DrawingContext dc) - { - base.OnRender(dc); - - if (OverlayLines == null) - OverlayLines = new List>(); - - if (OverlayPoints == null) - OverlayPoints = new List(); - - if (Source == null || !(Source is WriteableBitmap)) - return; - - var width = ((WriteableBitmap)Source).PixelWidth; - var height = ((WriteableBitmap)Source).PixelHeight; - - 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); - } - - foreach (var line in GazeLines) - { - - 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); - - } - - foreach (var p in OverlayPoints) - { - - 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, 2, 2); - } - - double scaling = ActualWidth / 400.0; - - int confidence_width = (int)(107.0 * scaling); - int confidence_height = (int)(18.0 * scaling); - - Brush conf_brush = new SolidColorBrush(Color.FromRgb((byte)((1 - Confidence) * 255), (byte)(Confidence * 255), (byte)40)); - dc.DrawRoundedRectangle(conf_brush, new Pen(Brushes.Black, 0.5 * scaling), new Rect(ActualWidth - confidence_width - 1, 0, confidence_width, confidence_height), 3.0 * scaling, 3.0 * scaling); - - FormattedText txt = new FormattedText("Confidence: " + (int)(100 * Confidence) + "%", System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface("Verdana"), 12.0 * scaling, Brushes.Black); - dc.DrawText(txt, new Point(ActualWidth - confidence_width + 2, 2)); - - int fps_width = (int)(52.0 * scaling); - int fps_height = (int)(18.0 * scaling); - - dc.DrawRoundedRectangle(Brushes.WhiteSmoke, new Pen(Brushes.Black, 0.5 * scaling), new Rect(0, 0, fps_width, fps_height), 3.0 * scaling, 3.0 * scaling); - FormattedText fps_txt = new FormattedText("FPS: " + (int)FPS, System.Globalization.CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface("Verdana"), 12.0 * scaling, Brushes.Black); - dc.DrawText(fps_txt, new Point(2.0 * scaling, 0)); - - old_width = width; - old_height = height; - - // Drawing a progress bar at the bottom of the image - if (Progress > 0) - { - int progress_bar_height = (int)(6.0 * scaling); - dc.DrawRectangle(Brushes.GreenYellow, new Pen(Brushes.Black, 0.5 * scaling), new Rect(0, ActualHeight - progress_bar_height, Progress * ActualWidth, progress_bar_height)); - } - - } - - public List> OverlayLines { get; set; } - public List> GazeLines { get; set; } - public List OverlayPoints { get; set; } - public double Confidence { get; set; } - public double FPS { get; set; } - - // 0 to 1 indicates how much video has been processed so far - public double Progress { get; set; } - - int old_width; - int old_height; - } -} diff --git a/gui/OpenFace-offline/UI_items/SimpleImage.xaml b/gui/OpenFace-offline/UI_items/SimpleImage.xaml deleted file mode 100644 index 9cf612d..0000000 --- a/gui/OpenFace-offline/UI_items/SimpleImage.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - \ No newline at end of file diff --git a/gui/OpenFace-offline/UI_items/SimpleImage.xaml.cs b/gui/OpenFace-offline/UI_items/SimpleImage.xaml.cs deleted file mode 100644 index 7ef9830..0000000 --- a/gui/OpenFace-offline/UI_items/SimpleImage.xaml.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace OpenFaceOffline -{ - /// - /// Interaction logic for OverlayImage.xaml - /// - public partial class SimpleImage : Image - { - public SimpleImage() - { - InitializeComponent(); - } - - protected override void OnRender(DrawingContext dc) - { - base.OnRender(dc); - - if (Source == null || !(Source is WriteableBitmap)) - return; - } - } -} diff --git a/gui/OpenFaceOffline/MainWindow.xaml.cs b/gui/OpenFaceOffline/MainWindow.xaml.cs index 295d740..b13660a 100644 --- a/gui/OpenFaceOffline/MainWindow.xaml.cs +++ b/gui/OpenFaceOffline/MainWindow.xaml.cs @@ -129,11 +129,18 @@ namespace OpenFaceOffline FaceAnalyserManaged face_analyser; // Recording parameters (default values) - // TODO these should only be initialized when starting the recording, might not need to have them as members (also all should be on by default) bool record_HOG = false; // HOG features extracted from face images bool record_aligned = false; // aligned face images bool record_tracked_vid = false; + // Check wich things need to be recorded + bool record_2D_landmarks = false; + bool record_3D_landmarks = false; + bool record_model_params = false; + bool record_pose = false; + bool record_AUs = false; + bool record_gaze = false; + // Visualisation options bool show_tracked_video = true; bool show_appearance = true; @@ -169,9 +176,15 @@ namespace OpenFaceOffline Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 2000), (Action)(() => { + RecordAUCheckBox.IsChecked = record_AUs; RecordAlignedCheckBox.IsChecked = record_aligned; RecordTrackedVidCheckBox.IsChecked = record_tracked_vid; RecordHOGCheckBox.IsChecked = record_HOG; + RecordGazeCheckBox.IsChecked = record_gaze; + RecordLandmarks2DCheckBox.IsChecked = record_2D_landmarks; + RecordLandmarks3DCheckBox.IsChecked = record_3D_landmarks; + RecordParamsCheckBox.IsChecked = record_model_params; + RecordPoseCheckBox.IsChecked = record_pose; UseDynamicModelsCheckBox.IsChecked = use_dynamic_models; UseDynamicScalingCheckBox.IsChecked = dynamic_AU_scale; @@ -220,7 +233,8 @@ namespace OpenFaceOffline // Prepare recording if any based on the directory String file_no_ext = System.IO.Path.GetDirectoryName(filenames[0]); file_no_ext = System.IO.Path.GetFileName(file_no_ext); - SetupRecording(record_root, file_no_ext, capture.width, capture.height); + + SetupRecording(record_root, file_no_ext, capture.width, capture.height, record_2D_landmarks, record_2D_landmarks, record_model_params, record_pose, record_AUs, record_gaze); // Start the actual processing VideoLoop(); @@ -289,8 +303,8 @@ namespace OpenFaceOffline { // Prepare recording if any String file_no_ext = System.IO.Path.GetFileNameWithoutExtension(filename); - - SetupRecording(record_root, file_no_ext, capture.width, capture.height); + + SetupRecording(record_root, file_no_ext, capture.width, capture.height, record_2D_landmarks, record_3D_landmarks, record_model_params, record_pose, record_AUs, record_gaze); // Start the actual processing VideoLoop(); @@ -423,14 +437,6 @@ namespace OpenFaceOffline double fps = capture.GetFPS(); if (fps <= 0) fps = 30; - // Check wich things need to be recorded - bool output_2D_landmarks = RecordLandmarks2DCheckBox.IsChecked; - bool output_3D_landmarks = RecordLandmarks3DCheckBox.IsChecked; - bool output_model_params = RecordParamsCheckBox.IsChecked; - bool output_pose = RecordPoseCheckBox.IsChecked; - bool output_AUs = RecordAUCheckBox.IsChecked; - bool output_gaze = RecordGazeCheckBox.IsChecked; - while (thread_running) { ////////////////////////////////////////////// @@ -487,7 +493,7 @@ namespace OpenFaceOffline List non_rigid_params = clnf_model.GetNonRigidParams(); // The face analysis step (only done if recording AUs, HOGs or video) - if (output_AUs || record_HOG || record_aligned || show_aus || show_appearance || record_tracked_vid || output_gaze) + if (record_AUs || record_HOG || record_aligned || show_aus || show_appearance || record_tracked_vid || record_gaze) { face_analyser.AddNextFrame(frame, clnf_model, fx, fy, cx, cy, false, show_appearance, record_tracked_vid); } @@ -624,7 +630,7 @@ namespace OpenFaceOffline // Recording the tracked model RecordFrame(clnf_model, detectionSucceeding, frame_id, frame, grayFrame, (fps * (double)frame_id)/1000.0, - output_2D_landmarks, output_2D_landmarks, output_model_params, output_pose, output_AUs, output_gaze, fx, fy, cx, cy); + record_2D_landmarks, record_2D_landmarks, record_model_params, record_pose, record_AUs, record_gaze, fx, fy, cx, cy); if (reset) { @@ -925,9 +931,15 @@ namespace OpenFaceOffline // Actually update the GUI accordingly Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 2000), (Action)(() => { + RecordAUCheckBox.IsChecked = record_AUs; RecordAlignedCheckBox.IsChecked = record_aligned; RecordTrackedVidCheckBox.IsChecked = record_tracked_vid; RecordHOGCheckBox.IsChecked = record_HOG; + RecordGazeCheckBox.IsChecked = record_gaze; + RecordLandmarks2DCheckBox.IsChecked = record_2D_landmarks; + RecordLandmarks3DCheckBox.IsChecked = record_3D_landmarks; + RecordParamsCheckBox.IsChecked = record_model_params; + RecordPoseCheckBox.IsChecked = record_pose; ShowVideoCheckBox.IsChecked = true; ShowAppearanceFeaturesCheckBox.IsChecked = false; @@ -1171,9 +1183,15 @@ namespace OpenFaceOffline private void recordCheckBox_click(object sender, RoutedEventArgs e) { + record_AUs = RecordAUCheckBox.IsChecked; record_aligned = RecordAlignedCheckBox.IsChecked; record_HOG = RecordHOGCheckBox.IsChecked; + record_gaze = RecordGazeCheckBox.IsChecked; record_tracked_vid = RecordTrackedVidCheckBox.IsChecked; + record_2D_landmarks = RecordLandmarks2DCheckBox.IsChecked; + record_3D_landmarks = RecordLandmarks3DCheckBox.IsChecked; + record_model_params = RecordParamsCheckBox.IsChecked; + record_pose = RecordPoseCheckBox.IsChecked; } private void UseDynamicModelsCheckBox_Click(object sender, RoutedEventArgs e)