open source pkg v1
This commit is contained in:
6
pkg/OpenFace/gui/OpenFaceDemo/App.config
Normal file
6
pkg/OpenFace/gui/OpenFaceDemo/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
9
pkg/OpenFace/gui/OpenFaceDemo/App.xaml
Normal file
9
pkg/OpenFace/gui/OpenFaceDemo/App.xaml
Normal file
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="OpenFaceDemo.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:OpenFaceDemo"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
pkg/OpenFace/gui/OpenFaceDemo/App.xaml.cs
Normal file
17
pkg/OpenFace/gui/OpenFaceDemo/App.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace OpenFaceDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
51
pkg/OpenFace/gui/OpenFaceDemo/MainWindow.xaml
Normal file
51
pkg/OpenFace/gui/OpenFaceDemo/MainWindow.xaml
Normal file
@@ -0,0 +1,51 @@
|
||||
<Window x:Class="OpenFaceDemo.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
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" KeyDown="Window_KeyDown">
|
||||
<Grid Name="MainGrid" Margin="-1,1,1.333,-1.333">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1.8*"/>
|
||||
<ColumnDefinition Width="1.8*"/>
|
||||
<ColumnDefinition Width="1.8*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="20"/>
|
||||
<RowDefinition Height="1.5*" MinHeight="100"/>
|
||||
<RowDefinition Height="1.5*" MinHeight="100"/>
|
||||
<RowDefinition Height="1.5*" MinHeight="100"/>
|
||||
<RowDefinition Height="1.6*"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Menu IsMainMenu="True" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4">
|
||||
<MenuItem Header="File">
|
||||
<MenuItem Header="Open webcam" Click="openWebcamClick">
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Border Name="VideoBorder" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="Black" BorderThickness="1" Background="LightGray" Margin="5,5,0,0" >
|
||||
<of:OverlayImage x:Name="video" MouseDown="video_MouseDown" />
|
||||
</Border>
|
||||
|
||||
<local:AxesTimeSeriesPlot NumVertGrid="5" x:Name="headPosePlot" ShowLegend="True" MinVal="-1" MaxVal="1" MinHeight="180" Grid.Row="4" Grid.Column="0" Padding="60 20 30 40" RangeLabel="Head pose" Orientation="Horizontal">
|
||||
</local:AxesTimeSeriesPlot>
|
||||
|
||||
<local:AxesTimeSeriesPlot MinHeight="180" Grid.Row="4" Grid.Column="1" Padding="60 20 30 40" x:Name="gazePlot" ShowLegend="True" RangeLabel="Eye gaze" Orientation="Horizontal" MinVal="-20" MaxVal="20" NumVertGrid="5">
|
||||
</local:AxesTimeSeriesPlot>
|
||||
|
||||
<local:AxesTimeSeriesPlot Grid.Column="2" Grid.Row="1" MinHeight="130" ShowXLabel="False" Padding="60 20 30 10" x:Name="smilePlot" ShowLegend="True" XTicks="False" RangeLabel="Lips" Orientation="Horizontal" MinVal="0" MaxVal="1" NumVertGrid="5">
|
||||
</local:AxesTimeSeriesPlot>
|
||||
|
||||
<local:AxesTimeSeriesPlot Grid.Column="2" Grid.Row="2" MinHeight="130" ShowXLabel="False" Padding="60 20 30 10" x:Name="browPlot" ShowLegend="True" XTicks="False" RangeLabel="Brows" Orientation="Horizontal" MinVal="0" MaxVal="1" NumVertGrid="5">
|
||||
</local:AxesTimeSeriesPlot>
|
||||
|
||||
<local:AxesTimeSeriesPlot Grid.Column="2" Grid.Row="3" MinHeight="130" ShowXLabel="False" x:Name="eyePlot" ShowLegend="True" Padding="60 20 30 10" XTicks="False" RangeLabel="Other" Orientation="Horizontal" MinVal="0" MaxVal="1" NumVertGrid="5">
|
||||
</local:AxesTimeSeriesPlot>
|
||||
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
494
pkg/OpenFace/gui/OpenFaceDemo/MainWindow.xaml.cs
Normal file
494
pkg/OpenFace/gui/OpenFaceDemo/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,494 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017, Carnegie Mellon University and University of Cambridge,
|
||||
// all rights reserved.
|
||||
//
|
||||
// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY
|
||||
//
|
||||
// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT.
|
||||
// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE.
|
||||
//
|
||||
// License can be found in OpenFace-license.txt
|
||||
|
||||
// * Any publications arising from the use of this software, including but
|
||||
// not limited to academic journal and conference publications, technical
|
||||
// reports and manuals, must cite at least one of the following works:
|
||||
//
|
||||
// OpenFace 2.0: Facial Behavior Analysis Toolkit
|
||||
// Tadas Baltrušaitis, Amir Zadeh, Yao Chong Lim, and Louis-Philippe Morency
|
||||
// in IEEE International Conference on Automatic Face and Gesture Recognition, 2018
|
||||
//
|
||||
// Convolutional experts constrained local model for facial landmark detection.
|
||||
// A. Zadeh, T. Baltrušaitis, and Louis-Philippe Morency,
|
||||
// in Computer Vision and Pattern Recognition Workshops, 2017.
|
||||
//
|
||||
// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation
|
||||
// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling
|
||||
// in IEEE International. Conference on Computer Vision (ICCV), 2015
|
||||
//
|
||||
// Cross-dataset learning and person-specific normalisation for automatic Action Unit detection
|
||||
// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson
|
||||
// in Facial Expression Recognition and Analysis Challenge,
|
||||
// IEEE International Conference on Automatic Face and Gesture Recognition, 2015
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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.Threading;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
// Internal libraries
|
||||
using OpenFaceOffline;
|
||||
using OpenCVWrappers;
|
||||
using CppInterop.LandmarkDetector;
|
||||
using FaceAnalyser_Interop;
|
||||
using FaceDetectorInterop;
|
||||
using GazeAnalyser_Interop;
|
||||
using UtilitiesOF;
|
||||
|
||||
|
||||
namespace OpenFaceDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Members
|
||||
// -----------------------------------------------------------------
|
||||
// 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 WriteableBitmap latest_img;
|
||||
|
||||
private volatile bool thread_running;
|
||||
|
||||
FpsTracker processing_fps = new FpsTracker();
|
||||
|
||||
// Controlling the model reset
|
||||
volatile bool reset = false;
|
||||
Point? resetPoint = null;
|
||||
|
||||
// For selecting webcams
|
||||
CameraSelection cam_sec;
|
||||
|
||||
// For tracking
|
||||
FaceModelParameters face_model_params;
|
||||
|
||||
FaceAnalyserManaged face_analyser;
|
||||
CLNF landmark_detector;
|
||||
GazeAnalyserManaged gaze_analyser;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Set the icon
|
||||
Uri iconUri = new Uri("logo1.ico", UriKind.RelativeOrAbsolute);
|
||||
this.Icon = BitmapFrame.Create(iconUri);
|
||||
|
||||
String root = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
// TODO, create a demo version of parameters
|
||||
face_model_params = new FaceModelParameters(root, true, false, false);
|
||||
face_model_params.optimiseForVideo();
|
||||
|
||||
// Initialize the face detector
|
||||
FaceDetector face_detector = new FaceDetector(face_model_params.GetHaarLocation(), face_model_params.GetMTCNNLocation());
|
||||
|
||||
// If MTCNN model not available, use HOG
|
||||
if (!face_detector.IsMTCNNLoaded())
|
||||
{
|
||||
face_model_params.SetFaceDetector(false, true, false);
|
||||
}
|
||||
|
||||
landmark_detector = new CLNF(face_model_params);
|
||||
face_analyser = new FaceAnalyserManaged(root, true, 112, true);
|
||||
gaze_analyser = new GazeAnalyserManaged();
|
||||
|
||||
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||
{
|
||||
|
||||
headPosePlot.AssocColor(0, Colors.Blue);
|
||||
headPosePlot.AssocColor(1, Colors.Red);
|
||||
headPosePlot.AssocColor(2, Colors.Green);
|
||||
|
||||
headPosePlot.AssocName(1, "Turn");
|
||||
headPosePlot.AssocName(2, "Tilt");
|
||||
headPosePlot.AssocName(0, "Up/Down");
|
||||
|
||||
headPosePlot.AssocThickness(0, 2);
|
||||
headPosePlot.AssocThickness(1, 2);
|
||||
headPosePlot.AssocThickness(2, 2);
|
||||
|
||||
gazePlot.AssocColor(0, Colors.Red);
|
||||
gazePlot.AssocColor(1, Colors.Blue);
|
||||
|
||||
gazePlot.AssocName(0, "Left-right");
|
||||
gazePlot.AssocName(1, "Up-down");
|
||||
gazePlot.AssocThickness(0, 2);
|
||||
gazePlot.AssocThickness(1, 2);
|
||||
|
||||
smilePlot.AssocColor(0, Colors.Green);
|
||||
smilePlot.AssocColor(1, Colors.Red);
|
||||
smilePlot.AssocName(0, "Smile");
|
||||
smilePlot.AssocName(1, "Frown");
|
||||
smilePlot.AssocThickness(0, 2);
|
||||
smilePlot.AssocThickness(1, 2);
|
||||
|
||||
browPlot.AssocColor(0, Colors.Green);
|
||||
browPlot.AssocColor(1, Colors.Red);
|
||||
browPlot.AssocName(0, "Raise");
|
||||
browPlot.AssocName(1, "Furrow");
|
||||
browPlot.AssocThickness(0, 2);
|
||||
browPlot.AssocThickness(1, 2);
|
||||
|
||||
eyePlot.AssocColor(0, Colors.Green);
|
||||
eyePlot.AssocColor(1, Colors.Red);
|
||||
eyePlot.AssocName(0, "Eye widen");
|
||||
eyePlot.AssocName(1, "Nose wrinkle");
|
||||
eyePlot.AssocThickness(0, 2);
|
||||
eyePlot.AssocThickness(1, 2);
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// The main function call for processing the webcam feed
|
||||
private void ProcessingLoop(SequenceReader reader)
|
||||
{
|
||||
|
||||
thread_running = true;
|
||||
|
||||
Thread.CurrentThread.IsBackground = true;
|
||||
|
||||
DateTime? startTime = CurrentTime;
|
||||
|
||||
var lastFrameTime = CurrentTime;
|
||||
|
||||
landmark_detector.Reset();
|
||||
face_analyser.Reset();
|
||||
|
||||
int frame_id = 0;
|
||||
|
||||
double old_gaze_x = 0;
|
||||
double old_gaze_y = 0;
|
||||
|
||||
double smile_cumm = 0;
|
||||
double frown_cumm = 0;
|
||||
double brow_up_cumm = 0;
|
||||
double brow_down_cumm = 0;
|
||||
double widen_cumm = 0;
|
||||
double wrinkle_cumm = 0;
|
||||
|
||||
while (thread_running)
|
||||
{
|
||||
|
||||
// Loading an image file
|
||||
RawImage frame = reader.GetNextImage();
|
||||
RawImage gray_frame = reader.GetCurrentFrameGray();
|
||||
|
||||
lastFrameTime = CurrentTime;
|
||||
processing_fps.AddFrame();
|
||||
|
||||
// The face analysis step
|
||||
bool detection_succeeding = landmark_detector.DetectLandmarksInVideo(frame, face_model_params, gray_frame);
|
||||
face_analyser.AddNextFrame(frame, landmark_detector.CalculateAllLandmarks(), detection_succeeding, true);
|
||||
gaze_analyser.AddNextFrame(landmark_detector, detection_succeeding, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
|
||||
|
||||
double confidence = landmark_detector.GetConfidence();
|
||||
|
||||
if (confidence < 0)
|
||||
confidence = 0;
|
||||
else if (confidence > 1)
|
||||
confidence = 1;
|
||||
|
||||
List<float> pose = new List<float>();
|
||||
|
||||
landmark_detector.GetPose(pose, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
|
||||
|
||||
List<float> non_rigid_params = landmark_detector.GetNonRigidParams();
|
||||
float scale = landmark_detector.GetRigidParams()[0];
|
||||
|
||||
double time_stamp = (DateTime.Now - (DateTime)startTime).TotalMilliseconds;
|
||||
|
||||
|
||||
List<Tuple<Point, Point>> lines = null;
|
||||
List<Tuple<float, float>> landmarks = null;
|
||||
List<Tuple<float, float>> eye_landmarks = null;
|
||||
List<Tuple<Point, Point>> gaze_lines = null;
|
||||
List<bool> visibilities = null;
|
||||
|
||||
Tuple<float, float> gaze_angle = gaze_analyser.GetGazeAngle();
|
||||
|
||||
if (detection_succeeding)
|
||||
{
|
||||
landmarks = landmark_detector.CalculateVisibleLandmarks();
|
||||
eye_landmarks = landmark_detector.CalculateVisibleEyeLandmarks();
|
||||
lines = landmark_detector.CalculateBox(reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
|
||||
gaze_lines = gaze_analyser.CalculateGazeLines(reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
|
||||
visibilities = landmark_detector.GetVisibilities();
|
||||
}
|
||||
|
||||
// Visualisation
|
||||
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||
{
|
||||
|
||||
var au_regs = face_analyser.GetCurrentAUsReg();
|
||||
if (au_regs.Count > 0)
|
||||
{
|
||||
double smile = (au_regs["AU12"] + au_regs["AU06"] + au_regs["AU25"]) / 13.0;
|
||||
double frown = (au_regs["AU15"] + au_regs["AU17"]) / 12.0;
|
||||
|
||||
double brow_up = (au_regs["AU01"] + au_regs["AU02"]) / 10.0;
|
||||
double brow_down = au_regs["AU04"] / 5.0;
|
||||
|
||||
double eye_widen = au_regs["AU05"] / 3.0;
|
||||
double nose_wrinkle = au_regs["AU09"] / 4.0;
|
||||
|
||||
Dictionary<int, double> smileDict = new Dictionary<int, double>();
|
||||
smileDict[0] = 0.7 * smile_cumm + 0.3 * smile;
|
||||
smileDict[1] = 0.7 * frown_cumm + 0.3 * frown;
|
||||
smilePlot.AddDataPoint(new DataPointGraph() { Time = CurrentTime, values = smileDict, Confidence = confidence });
|
||||
|
||||
Dictionary<int, double> browDict = new Dictionary<int, double>();
|
||||
browDict[0] = 0.7 * brow_up_cumm + 0.3 * brow_up;
|
||||
browDict[1] = 0.7 * brow_down_cumm + 0.3 * brow_down;
|
||||
browPlot.AddDataPoint(new DataPointGraph() { Time = CurrentTime, values = browDict, Confidence = confidence });
|
||||
|
||||
Dictionary<int, double> eyeDict = new Dictionary<int, double>();
|
||||
eyeDict[0] = 0.7 * widen_cumm + 0.3 * eye_widen;
|
||||
eyeDict[1] = 0.7 * wrinkle_cumm + 0.3 * nose_wrinkle;
|
||||
eyePlot.AddDataPoint(new DataPointGraph() { Time = CurrentTime, values = eyeDict, Confidence = confidence });
|
||||
|
||||
smile_cumm = smileDict[0];
|
||||
frown_cumm = smileDict[1];
|
||||
brow_up_cumm = browDict[0];
|
||||
brow_down_cumm = browDict[1];
|
||||
widen_cumm = eyeDict[0];
|
||||
wrinkle_cumm = eyeDict[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no AUs present disable the AU visualization
|
||||
MainGrid.ColumnDefinitions[2].Width = new GridLength(0);
|
||||
eyePlot.Visibility = Visibility.Collapsed;
|
||||
browPlot.Visibility = Visibility.Collapsed;
|
||||
smilePlot.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
Dictionary<int, double> poseDict = new Dictionary<int, double>();
|
||||
poseDict[0] = -pose[3];
|
||||
poseDict[1] = pose[4];
|
||||
poseDict[2] = pose[5];
|
||||
headPosePlot.AddDataPoint(new DataPointGraph() { Time = CurrentTime, values = poseDict, Confidence = confidence });
|
||||
|
||||
Dictionary<int, double> gazeDict = new Dictionary<int, double>();
|
||||
gazeDict[0] = gaze_angle.Item1 * (180.0 / Math.PI);
|
||||
gazeDict[0] = 0.5 * old_gaze_x + 0.5 * gazeDict[0];
|
||||
gazeDict[1] = -gaze_angle.Item2 * (180.0 / Math.PI);
|
||||
gazeDict[1] = 0.5 * old_gaze_y + 0.5 * gazeDict[1];
|
||||
gazePlot.AddDataPoint(new DataPointGraph() { Time = CurrentTime, values = gazeDict, Confidence = confidence });
|
||||
|
||||
old_gaze_x = gazeDict[0];
|
||||
old_gaze_y = gazeDict[1];
|
||||
|
||||
if (latest_img == null)
|
||||
{
|
||||
latest_img = frame.CreateWriteableBitmap();
|
||||
}
|
||||
|
||||
frame.UpdateWriteableBitmap(latest_img);
|
||||
|
||||
video.Source = latest_img;
|
||||
|
||||
video.FPS = processing_fps.GetFPS();
|
||||
|
||||
// First clear the old results
|
||||
video.Clear();
|
||||
|
||||
video.Confidence.Add(confidence);
|
||||
|
||||
if(detection_succeeding)
|
||||
{
|
||||
video.FaceScale.Add(scale);
|
||||
|
||||
video.OverlayLines.Add(lines);
|
||||
|
||||
List<Point> landmark_points = new List<Point>();
|
||||
foreach (var p in landmarks)
|
||||
{
|
||||
landmark_points.Add(new Point(p.Item1, p.Item2));
|
||||
}
|
||||
|
||||
List<Point> eye_landmark_points = new List<Point>();
|
||||
foreach (var p in eye_landmarks)
|
||||
{
|
||||
eye_landmark_points.Add(new Point(p.Item1, p.Item2));
|
||||
}
|
||||
|
||||
video.OverlayPoints.Add(landmark_points);
|
||||
video.OverlayEyePoints.Add(eye_landmark_points);
|
||||
video.OverlayPointsVisibility.Add(visibilities);
|
||||
video.OverlayEyePoints.Add(eye_landmark_points);
|
||||
|
||||
video.GazeLines.Add(gaze_lines);
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
if (reset)
|
||||
{
|
||||
// TODO add
|
||||
if (resetPoint.HasValue)
|
||||
{
|
||||
//landmark_detector.Reset(resetPoint.Value.X, resetPoint.Value.Y);
|
||||
resetPoint = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO add
|
||||
//landmark_detector.Reset();
|
||||
}
|
||||
|
||||
// TODO add
|
||||
//face_analyser.Reset();
|
||||
reset = false;
|
||||
|
||||
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
|
||||
{
|
||||
headPosePlot.ClearDataPoints();
|
||||
headPosePlot.ClearDataPoints();
|
||||
gazePlot.ClearDataPoints();
|
||||
smilePlot.ClearDataPoints();
|
||||
browPlot.ClearDataPoints();
|
||||
eyePlot.ClearDataPoints();
|
||||
}));
|
||||
}
|
||||
|
||||
frame_id++;
|
||||
|
||||
|
||||
}
|
||||
reader.Close();
|
||||
latest_img = null;
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Button handling
|
||||
// --------------------------------------------------------
|
||||
|
||||
private void openWebcamClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StopTracking();
|
||||
|
||||
if (cam_sec == null)
|
||||
{
|
||||
cam_sec = new CameraSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_sec = new CameraSelection(cam_sec.cams);
|
||||
cam_sec.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
// Set the icon
|
||||
Uri iconUri = new Uri("logo1.ico", UriKind.RelativeOrAbsolute);
|
||||
cam_sec.Icon = BitmapFrame.Create(iconUri);
|
||||
|
||||
if (!cam_sec.no_cameras_found)
|
||||
cam_sec.ShowDialog();
|
||||
|
||||
if (cam_sec.camera_selected)
|
||||
{
|
||||
|
||||
int cam_id = cam_sec.selected_camera.Item1;
|
||||
int width = cam_sec.selected_camera.Item2;
|
||||
int height = cam_sec.selected_camera.Item3;
|
||||
|
||||
SequenceReader reader = new SequenceReader(cam_id, width, height);
|
||||
|
||||
processing_thread = new Thread(() => ProcessingLoop(reader));
|
||||
processing_thread.Name = "Webcam processing";
|
||||
processing_thread.Start();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Cleanup stuff when closing the window
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
if (processing_thread != null)
|
||||
{
|
||||
// Stop capture and tracking
|
||||
thread_running = false;
|
||||
processing_thread.Join();
|
||||
|
||||
}
|
||||
|
||||
if (face_analyser != null)
|
||||
face_analyser.Dispose();
|
||||
if(landmark_detector != null)
|
||||
landmark_detector.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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
159
pkg/OpenFace/gui/OpenFaceDemo/OpenFaceDemo.csproj
Normal file
159
pkg/OpenFace/gui/OpenFaceDemo/OpenFaceDemo.csproj
Normal file
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>OpenFaceDemo</RootNamespace>
|
||||
<AssemblyName>OpenFaceDemo</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\..\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>logo1.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="UI_items\AxesTimeSeriesPlot.xaml.cs">
|
||||
<DependentUpon>AxesTimeSeriesPlot.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="UI_items\AxesTimeSeriesPlot.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenFaceOffline\OpenFaceOffline.csproj">
|
||||
<Project>{a4760f41-2b1f-4144-b7b2-62785affe79b}</Project>
|
||||
<Name>OpenFaceOffline</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\lib\local\CppInerop\CppInerop.vcxproj">
|
||||
<Project>{78196985-ee54-411f-822b-5a23edf80642}</Project>
|
||||
<Name>CppInerop</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="logo1.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /I /E /Y /D "$(ProjectDir)logo1.ico" "$(ProjectDir)$(OutDir)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
55
pkg/OpenFace/gui/OpenFaceDemo/Properties/AssemblyInfo.cs
Normal file
55
pkg/OpenFace/gui/OpenFaceDemo/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
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("OpenFaceDemo")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("OpenFaceDemo")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 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
|
||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
//in your source files, set the <UICulture> 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")]
|
||||
71
pkg/OpenFace/gui/OpenFaceDemo/Properties/Resources.Designer.cs
generated
Normal file
71
pkg/OpenFace/gui/OpenFaceDemo/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace OpenFaceDemo.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// 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()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenFaceDemo.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
pkg/OpenFace/gui/OpenFaceDemo/Properties/Resources.resx
Normal file
117
pkg/OpenFace/gui/OpenFaceDemo/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
pkg/OpenFace/gui/OpenFaceDemo/Properties/Settings.Designer.cs
generated
Normal file
30
pkg/OpenFace/gui/OpenFaceDemo/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace OpenFaceDemo.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,8 @@
|
||||
<UserControl x:Class="OpenFaceDemo.AxesTimeSeriesPlot"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="200" d:DesignWidth="900">
|
||||
</UserControl>
|
||||
@@ -0,0 +1,397 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
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;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace OpenFaceDemo
|
||||
{
|
||||
public class DataPointGraph
|
||||
{
|
||||
public DataPointGraph()
|
||||
{
|
||||
Time = AxesTimeSeriesPlot.CurrentTime;
|
||||
|
||||
}
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
public Dictionary<int, double> values = new Dictionary<int, double>();
|
||||
|
||||
public double Confidence { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Interaction logic for AxesTimeSeriesPlot.xaml
|
||||
/// </summary>
|
||||
public partial class AxesTimeSeriesPlot : UserControl
|
||||
{
|
||||
|
||||
#region High-Resolution Timing
|
||||
static DateTime startTime;
|
||||
static Stopwatch sw = new Stopwatch();
|
||||
|
||||
public double MinVal { get; set; }
|
||||
public double MaxVal { get; set; }
|
||||
public int NumVertGrid { get; set; }
|
||||
|
||||
public bool ShowXLabel { get; set; }
|
||||
public bool ShowYLabel { get; set; }
|
||||
|
||||
public string RangeLabel { get; set; }
|
||||
|
||||
public bool XTicks { get; set; }
|
||||
|
||||
static AxesTimeSeriesPlot()
|
||||
{
|
||||
startTime = DateTime.Now;
|
||||
sw.Start();
|
||||
|
||||
}
|
||||
public static DateTime CurrentTime
|
||||
{
|
||||
get { return startTime + sw.Elapsed; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public Orientation Orientation { get; set; }
|
||||
|
||||
public bool ShowLegend { get; set; }
|
||||
|
||||
Queue<DataPointGraph> dataPoints = new Queue<DataPointGraph>();
|
||||
TimeSpan historyLength = TimeSpan.FromSeconds(10);
|
||||
Dictionary<int, Brush> brushes = new Dictionary<int, Brush>();
|
||||
Dictionary<int, int> brush_thicknesses = new Dictionary<int, int>();
|
||||
Dictionary<int, String> line_names = new Dictionary<int, String>();
|
||||
Dictionary<int, Color> brush_colors = new Dictionary<int, Color>();
|
||||
|
||||
// Knowing where to draw things
|
||||
private double MinAxesX { get; set; }
|
||||
private double MinAxesY { get; set; }
|
||||
private double MaxAxesX { get; set; }
|
||||
private double MaxAxesY { get; set; }
|
||||
|
||||
public AxesTimeSeriesPlot()
|
||||
{
|
||||
InitializeComponent();
|
||||
ShowLegend = false;
|
||||
ClipToBounds = true;
|
||||
DispatcherTimer dt = new DispatcherTimer(TimeSpan.FromMilliseconds(20), DispatcherPriority.Background, Timer_Tick, Dispatcher);
|
||||
|
||||
MinVal = -1;
|
||||
MaxVal = 1;
|
||||
NumVertGrid = 5;
|
||||
ShowXLabel = true;
|
||||
ShowYLabel = true;
|
||||
XTicks = true;
|
||||
|
||||
}
|
||||
|
||||
private void PruneData()
|
||||
{
|
||||
lock (dataPoints)
|
||||
{
|
||||
while (dataPoints.Count > 0 && dataPoints.Peek().Time < CurrentTime - historyLength - TimeSpan.FromSeconds(2))
|
||||
dataPoints.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddDataPoint(DataPointGraph dp)
|
||||
{
|
||||
lock (dataPoints)
|
||||
dataPoints.Enqueue(dp);
|
||||
}
|
||||
|
||||
public void ClearDataPoints()
|
||||
{
|
||||
lock (dataPoints)
|
||||
dataPoints.Clear();
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
PruneData();
|
||||
|
||||
if (this.IsVisible)
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
public void AssocColor(int seriesId, Color b)
|
||||
{
|
||||
Color bTransparent = b;
|
||||
bTransparent.A = 0;
|
||||
|
||||
GradientStopCollection gs = new GradientStopCollection();
|
||||
gs.Add(new GradientStop(bTransparent, 0));
|
||||
gs.Add(new GradientStop(b, 0.2));
|
||||
LinearGradientBrush g = new LinearGradientBrush(gs, new Point(0, 0), Orientation == System.Windows.Controls.Orientation.Horizontal ? new Point(ActualWidth, 0) : new Point(0, ActualHeight));
|
||||
g.MappingMode = BrushMappingMode.Absolute;
|
||||
g.Freeze();
|
||||
brushes[seriesId] = g;
|
||||
|
||||
brush_colors[seriesId] = b;
|
||||
}
|
||||
|
||||
public void AssocThickness(int seriesId, int thickness)
|
||||
{
|
||||
brush_thicknesses[seriesId] = thickness;
|
||||
}
|
||||
|
||||
public void AssocName(int seriesId, String name)
|
||||
{
|
||||
line_names[seriesId] = name;
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
base.OnRender(dc);
|
||||
|
||||
if (Orientation == System.Windows.Controls.Orientation.Horizontal)
|
||||
RenderHorizontal(dc);
|
||||
else
|
||||
RenderVertical(dc);
|
||||
|
||||
}
|
||||
|
||||
// Grid rendering
|
||||
private void RenderHorizontal(DrawingContext dc)
|
||||
{
|
||||
Pen p = new Pen(Brushes.Black, 1);
|
||||
Pen q = new Pen(Brushes.LightGray, 1);
|
||||
|
||||
double padLeft = Padding.Left;
|
||||
double padBottom = Padding.Bottom - 2 + 10;
|
||||
double padTop = Padding.Top;
|
||||
double padRight = Padding.Right;
|
||||
|
||||
// Draw horizontal gridlines
|
||||
|
||||
double step_size = (MaxVal - MinVal) / (NumVertGrid - 1.0);
|
||||
|
||||
for (int i = 0; i < NumVertGrid; i++)
|
||||
{
|
||||
double y = (int)(padTop + ((NumVertGrid - 1.0) - i) * ((ActualHeight - padBottom - padTop) / (NumVertGrid - 1.0))) - 0.5;
|
||||
|
||||
|
||||
double y_val = MinVal + i * step_size;
|
||||
|
||||
if (y_val != 0)
|
||||
dc.DrawLine(q, new Point(padLeft, y), new Point(ActualWidth - padRight, y));
|
||||
else
|
||||
dc.DrawLine(p, new Point(padLeft, y), new Point(ActualWidth - padRight, y));
|
||||
|
||||
dc.DrawLine(p, new Point(padLeft - 10, y), new Point(padLeft, y));
|
||||
|
||||
var t = FormT((MinVal + i * step_size).ToString("0.0"), 10);
|
||||
dc.DrawText(t, new Point(padLeft - t.Width - 12, y - t.Height / 2));
|
||||
|
||||
if (i == 0)
|
||||
MinAxesY = y;
|
||||
if (i == NumVertGrid - 1)
|
||||
MaxAxesY = y;
|
||||
}
|
||||
|
||||
// Draw vertical gridlines
|
||||
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
double x = (int)(padLeft + (10 - i) * ((ActualWidth - padLeft - padRight) / 10.0)) - 0.5;
|
||||
if (i < 10)
|
||||
dc.DrawLine(q, new Point(x, ActualHeight - padBottom), new Point(x, padTop));
|
||||
dc.DrawLine(p, new Point(x, ActualHeight - padBottom + 10), new Point(x, ActualHeight - padBottom));
|
||||
|
||||
if (XTicks)
|
||||
{
|
||||
var t = FormT(i.ToString(), 10);
|
||||
dc.DrawText(t, new Point(x - t.Width / 2, ActualHeight - padBottom + t.Height));
|
||||
}
|
||||
if (i == 0)
|
||||
MaxAxesX = x;
|
||||
if (i == (11 - 1))
|
||||
MinAxesX = x;
|
||||
}
|
||||
|
||||
// Draw y axis
|
||||
dc.DrawLine(p, new Point(((int)padLeft) - 0.5, padTop), new Point(((int)padLeft) - 0.5, ActualHeight - padBottom));
|
||||
|
||||
//dc.DrawLine(p, new Point(MinAxesX, MinAxesY), new Point(MaxAxesX, MaxAxesY));
|
||||
//dc.DrawLine(p, new Point(MaxAxesX, padTop), new Point(MaxAxesX, ActualHeight - padBottom));
|
||||
|
||||
// Draw x axis label
|
||||
if (ShowXLabel)
|
||||
{
|
||||
FormattedText ft = FormT("History (seconds)", 20);
|
||||
dc.DrawText(ft, new Point(padLeft + (ActualWidth - padLeft - padRight) / 2 - ft.Width / 2, ActualHeight - ft.Height));
|
||||
}
|
||||
|
||||
// Draw y axis label
|
||||
if (ShowYLabel)
|
||||
{
|
||||
FormattedText ft = FormT(RangeLabel, 20);
|
||||
dc.PushTransform(new RotateTransform(-90));
|
||||
dc.DrawText(ft, new Point(-ft.Width - ActualHeight / 2 + ft.Width / 2, 0));
|
||||
dc.Pop();
|
||||
}
|
||||
|
||||
DataPointGraph[] localPoints;
|
||||
lock (dataPoints)
|
||||
localPoints = dataPoints.ToArray();
|
||||
|
||||
var pfs = new Dictionary<int, PathFigure>();
|
||||
|
||||
for (int i = 0; i < localPoints.Length; i++)
|
||||
{
|
||||
var ptTime = localPoints[i].Time;
|
||||
var ptAge = (DateTime.Now - ptTime).TotalSeconds;
|
||||
|
||||
foreach (var kvp in localPoints[i].values)
|
||||
{
|
||||
var seriesId = kvp.Key;
|
||||
|
||||
double v = (kvp.Value - MinVal) / (MaxVal - MinVal);
|
||||
|
||||
// X starts here MinAxesX
|
||||
// X ends here MaxAxesX
|
||||
|
||||
double y = MinAxesY - (MinAxesY - MaxAxesY) * v;
|
||||
double x = MaxAxesX - (CurrentTime - localPoints[i].Time).TotalMilliseconds * ((MaxAxesX-MinAxesX) / historyLength.TotalMilliseconds);
|
||||
|
||||
// Make sure everything is within bounds
|
||||
if (x < MinAxesX)
|
||||
continue;
|
||||
|
||||
y = Math.Min(MinAxesY, Math.Max(MaxAxesY, y));
|
||||
|
||||
if (!pfs.ContainsKey(seriesId))
|
||||
{
|
||||
pfs[seriesId] = new PathFigure();
|
||||
pfs[seriesId].IsClosed = false;
|
||||
pfs[seriesId].StartPoint = new Point(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
pfs[seriesId].Segments.Add(new LineSegment(new Point(x, y), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var kvp in pfs)
|
||||
{
|
||||
var seriesId = kvp.Key;
|
||||
var pf = kvp.Value;
|
||||
|
||||
Brush b = brushes.ContainsKey(seriesId) ? brushes[seriesId] : Brushes.Black;
|
||||
|
||||
int thickness = brush_thicknesses.ContainsKey(seriesId) ? brush_thicknesses[seriesId] : 2;
|
||||
|
||||
PathGeometry pg = new PathGeometry(new PathFigure[] { pf });
|
||||
|
||||
Pen p2 = new Pen(b, thickness);
|
||||
|
||||
dc.DrawGeometry(null, p2, pg);
|
||||
}
|
||||
|
||||
if (ShowLegend && line_names.Count > 0)
|
||||
{
|
||||
int height_one = 18;
|
||||
int height = height_one * line_names.Count;
|
||||
|
||||
Pen p2 = new Pen(Brushes.Black, 1);
|
||||
Brush legend_b = new SolidColorBrush(Color.FromRgb(255, 255, 255));
|
||||
|
||||
dc.DrawRectangle(legend_b, p2, new Rect(MinAxesX, MaxAxesY, 100, height));
|
||||
|
||||
int i = 0;
|
||||
foreach (var key_name_pair in line_names)
|
||||
{
|
||||
var line_name = key_name_pair.Value;
|
||||
FormattedText ft = FormT(line_name, 11);
|
||||
|
||||
// Draw the text
|
||||
dc.DrawText(ft, new Point(MinAxesX + 15, MaxAxesY + 1 + height_one * i));
|
||||
// Draw example lines
|
||||
|
||||
Brush legend_c = new SolidColorBrush(brush_colors[key_name_pair.Key]);
|
||||
Pen p_line = new Pen(legend_c, brush_thicknesses[key_name_pair.Key]);
|
||||
dc.DrawLine(p_line, new Point(MinAxesX, MaxAxesY + height_one * i - 1 + height_one / 2), new Point(MinAxesX + 14, MaxAxesY -1 + height_one * i + height_one / 2));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void RenderVertical(DrawingContext dc)
|
||||
{
|
||||
Pen p = new Pen(Brushes.Black, 1);
|
||||
Pen q = new Pen(Brushes.LightGray, 1);
|
||||
|
||||
double padLeft = Padding.Left;
|
||||
double padBottom = Padding.Bottom - 2 + 10;
|
||||
double padTop = Padding.Top;
|
||||
double padRight = Padding.Right;
|
||||
|
||||
// Draw horizontal gridlines
|
||||
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
double y = (int)(padTop + (10 - i) * ((ActualHeight - padBottom - padTop) / 10.0)) - 0.5;
|
||||
if (i > 0)
|
||||
dc.DrawLine(q, new Point(padLeft, y), new Point(ActualWidth - padRight, y));
|
||||
dc.DrawLine(p, new Point(padLeft - 10, y), new Point(padLeft, y));
|
||||
var t = FormT(i.ToString(), 10);
|
||||
dc.DrawText(t, new Point(padLeft - t.Width - 12, y - t.Height / 2));
|
||||
}
|
||||
|
||||
// Draw vertical gridlines
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
double x = (int)(padLeft + (4 - i) * ((ActualWidth - padLeft - padRight) / 4.0)) - 0.5;
|
||||
if (i < 10)
|
||||
dc.DrawLine(q, new Point(x, ActualHeight - padBottom), new Point(x, padTop));
|
||||
dc.DrawLine(p, new Point(x, ActualHeight - padBottom + 10), new Point(x, ActualHeight - padBottom));
|
||||
|
||||
var t = FormT(((4 - i) / 2.0 - 1).ToString("0.0"), 10);
|
||||
dc.DrawText(t, new Point(x - t.Width / 2, ActualHeight - padBottom + t.Height));
|
||||
}
|
||||
|
||||
// Draw y axis
|
||||
|
||||
dc.DrawLine(p, new Point(((int)((ActualWidth - padRight - padLeft) / 2 + padLeft)) - 0.5, padTop), new Point(((int)((ActualWidth - padRight - padLeft) / 2 + padLeft)) - 0.5, ActualHeight - padBottom));
|
||||
|
||||
// Draw x axis
|
||||
dc.DrawLine(p, new Point(padLeft, ((int)((ActualHeight - padBottom))) - 0.5), new Point(ActualWidth - padRight, ((int)((ActualHeight - padBottom))) - 0.5));
|
||||
|
||||
// Draw x axis label
|
||||
|
||||
FormattedText ft = FormT(RangeLabel, 20);
|
||||
dc.DrawText(ft, new Point(padLeft + (ActualWidth - padLeft - padRight) / 2 - ft.Width / 2, ActualHeight - ft.Height));
|
||||
|
||||
// Draw y axis label
|
||||
|
||||
ft = FormT("History (seconds)", 20);
|
||||
dc.PushTransform(new RotateTransform(-90));
|
||||
dc.DrawText(ft, new Point(-ft.Width - ActualHeight / 2 + ft.Width / 2, 0));
|
||||
}
|
||||
|
||||
private FormattedText FormT(string text, int size)
|
||||
{
|
||||
return new FormattedText(text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface("Verdana"), size, Brushes.Black);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
BIN
pkg/OpenFace/gui/OpenFaceDemo/logo1.ico
Normal file
BIN
pkg/OpenFace/gui/OpenFaceDemo/logo1.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Reference in New Issue
Block a user