open source pkg v1

This commit is contained in:
Vijay Yadev
2020-08-04 19:12:31 -04:00
parent bef213dba9
commit c389fc2c47
3708 changed files with 1624220 additions and 1 deletions

View 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>

View File

@@ -0,0 +1,9 @@
<Application x:Class="HeadPose_live.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HeadPose_live"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View 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 HeadPose_live
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,179 @@
<?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>{F396362D-821E-4EA6-9BBF-1F6050844118}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HeadPoseLive</RootNamespace>
<AssemblyName>HeadPoseLive</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>
</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.Drawing" />
<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" />
<Reference Include="ZeroMQ, Version=4.1.0.22, Culture=neutral, PublicKeyToken=4a9630883fd6c563, processorArchitecture=MSIL">
<HintPath>..\..\packages\ZeroMQ.4.1.0.22\lib\net40\ZeroMQ.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Liability.xaml.cs">
<DependentUpon>Liability.xaml</DependentUpon>
</Compile>
<Compile Include="TextEntryWindow.xaml.cs">
<DependentUpon>TextEntryWindow.xaml</DependentUpon>
</Compile>
<Page Include="Liability.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<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="TextEntryWindow.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="packages.config" />
<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="..\..\lib\local\CppInerop\CppInerop.vcxproj">
<Project>{78196985-ee54-411f-822b-5a23edf80642}</Project>
<Name>CppInerop</Name>
</ProjectReference>
<ProjectReference Include="..\OpenFaceDemo\OpenFaceDemo.csproj">
<Project>{e143a2aa-312e-4dfe-b61d-9a87ccbc8e90}</Project>
<Name>OpenFaceDemo</Name>
</ProjectReference>
<ProjectReference Include="..\OpenFaceOffline\OpenFaceOffline.csproj">
<Project>{a4760f41-2b1f-4144-b7b2-62785affe79b}</Project>
<Name>OpenFaceOffline</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="logo1.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy /I /E /Y /D "$(ProjectDir)logo1.ico" "$(ProjectDir)$(OutDir)"
xcopy /I /E /Y /D "$(ProjectDir)logo1.png" "$(ProjectDir)$(OutDir)"</PostBuildEvent>
</PropertyGroup>
<Import Project="..\..\packages\ZeroMQ.4.1.0.22\build\net40\ZeroMQ.targets" Condition="Exists('..\..\packages\ZeroMQ.4.1.0.22\build\net40\ZeroMQ.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\ZeroMQ.4.1.0.22\build\net40\ZeroMQ.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\ZeroMQ.4.1.0.22\build\net40\ZeroMQ.targets'))" />
</Target>
<!-- 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>

View File

@@ -0,0 +1,26 @@
<Window x:Class="HeadPoseLive.Liability"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Liability" Height="300" Width="400" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock TextWrapping="WrapWithOverflow" Margin="10,10,10,10" TextAlignment="Justify" Grid.Row="0">This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.</TextBlock>
<Button Grid.Row="1" HorizontalAlignment="Center" Click="Button_Click" Name="ContinueButton">
Continue
</Button>
</Grid>
</Window>

View File

@@ -0,0 +1,83 @@
///////////////////////////////////////////////////////////////////////////////
// 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.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.Shapes;
namespace HeadPoseLive
{
/// <summary>
/// Interaction logic for Liability.xaml
/// </summary>
public partial class Liability : Window
{
public bool continue_pressed = false;
public Liability()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(TextEntry_KeyDown);
FocusManager.SetFocusedElement(this, ContinueButton);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
continue_pressed = true;
this.Close();
}
private void TextEntry_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
continue_pressed = true;
DialogResult = true;
}
}
}
}

View File

@@ -0,0 +1,94 @@
<Window x:Class="HeadPoseLive.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Ophthalm_experiments="clr-namespace:HeadPoseLive"
Title="Cambridge Face Tracker - Head Pose Experiments" MinHeight="400" MinWidth="640" WindowStartupLocation="CenterScreen" UseLayoutRounding="True" Closing="Window_Closing">
<Window.Resources>
<Style TargetType="{x:Type Image}">
<Setter Property="RenderOptions.BitmapScalingMode"
Value="Fant" />
</Style>
</Window.Resources>
<Grid Name="MainGrid" HorizontalAlignment="Stretch" MinWidth="620">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition MinWidth="300"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition MinWidth="10" Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition MinHeight="200"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Label HorizontalAlignment="Left" VerticalAlignment="Bottom" Grid.Column="1" Grid.Row="1" Background="DarkSalmon" Canvas.ZIndex="1" MouseDown="ResetButton_Click" Name="ResetButton" Content="Reset"/>
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Width="110" Height="26" FontSize="16" Click="startRecordingButton_Click" Name="RecordingButton">Record trial 0</Button>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2" VerticalAlignment="Top">
<Button Name="PauseButton" Click="PauseButton_Click">
Pause
</Button>
<Button Name="ScreenshotButton" Click="ScreenshotButton_Click" Margin="0,10,0,0">
Take a screenshot
</Button>
<Button Name="MirrorImageButton" Click="MirrorButton_Click" Margin="0,10,0,0">
Mirror image
</Button>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" Width="185">
<Label Name="headOrientationLabel" Margin="0,0,0,0" FontSize="18" HorizontalContentAlignment="Left">Head Orientation</Label>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" Width="80" HorizontalContentAlignment="Left">Turn:</Label>
<Label Name="YawLabel" FontSize="16" MinWidth="30" HorizontalContentAlignment="Right">0°</Label>
<Label Name="YawLabelDir" FontSize="16" Width="70" HorizontalContentAlignment="Left">straight</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" Width="80" HorizontalContentAlignment="Left">Up/down:</Label>
<Label Name="PitchLabel" FontSize="16" Width="30" HorizontalContentAlignment="Right">0°</Label>
<Label Name="PitchLabelDir" FontSize="16" Width="70" HorizontalContentAlignment="Left">straight</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" Width="80" HorizontalContentAlignment="Left">Tilt:</Label>
<Label Name="RollLabel" FontSize="16" Width="30" HorizontalContentAlignment="Right">0°</Label>
<Label Name="RollLabelDir" FontSize="16" Width="70" HorizontalContentAlignment="Left">straight</Label>
</StackPanel>
<Label Name="gazeLabel" Margin="0,0,0,0" FontSize="18" HorizontalContentAlignment="Left">Gaze Orientation</Label>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" Width="80" HorizontalContentAlignment="Left">Left-right:</Label>
<Label Name="YawLabelGaze" FontSize="16" MinWidth="30" HorizontalContentAlignment="Right">0°</Label>
<Label Name="YawLabelGazeDir" FontSize="16" Width="70" HorizontalContentAlignment="Left">straight</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" Width="80" HorizontalContentAlignment="Left">Up/down:</Label>
<Label Name="PitchLabelGaze" FontSize="16" Width="30" HorizontalContentAlignment="Right">0°</Label>
<Label Name="PitchLabelGazeDir" FontSize="16" Width="70" HorizontalContentAlignment="Left">straight</Label>
</StackPanel>
<Label Name="headPoseLabel" Margin="0,0,0,0" FontSize="18" HorizontalContentAlignment="Left">Pose</Label>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" HorizontalContentAlignment="Left" Width="20">X:</Label>
<Label Name="XPoseLabel" FontSize="16" HorizontalContentAlignment="Right" Width="70">0 mm</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" HorizontalContentAlignment="Left" Width="20">Y:</Label>
<Label Name="YPoseLabel" FontSize="16" HorizontalContentAlignment="Right" Width="70">0 mm</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="5,0,0,0" FontSize="16" HorizontalContentAlignment="Left" Width="20">Z:</Label>
<Label Name="ZPoseLabel" FontSize="16" HorizontalContentAlignment="Right" Width="70">0 mm</Label>
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="2" VerticalAlignment="Bottom">
<Button FontSize="16" HorizontalAlignment="Center" Click="CompleteButton_Click" Name="CompleteButton" >Start new subject</Button>
</StackPanel>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2">
<Image RenderOptions.BitmapScalingMode="Fant" RenderOptions.EdgeMode="Aliased" x:Name="logoLabel" Source="/logo1.png" Stretch="Uniform" />
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,756 @@
///////////////////////////////////////////////////////////////////////////////
// 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.Diagnostics;
using System.Drawing.Imaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using OpenCVWrappers;
using CppInterop;
using CppInterop.LandmarkDetector;
using System.Windows.Threading;
using GazeAnalyser_Interop;
using FaceDetectorInterop;
using ZeroMQ;
using System.Drawing;
using System.Collections.Concurrent;
namespace HeadPoseLive
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
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
OpenFaceOffline.FpsTracker processing_fps = new OpenFaceOffline.FpsTracker();
Thread processing_thread;
Thread rec_thread;
string subject_id;
bool record_video;
bool record_head_pose;
// Controls if the view should be mirrored or not
volatile bool mirror_image = false;
// Capturing and displaying the images
OpenFaceOffline.OverlayImage webcam_img;
// Some members for displaying the results
private WriteableBitmap latest_img;
// For tracking
bool reset = false;
// For recording
string record_root = "./head_pose_live_recordings/subject";
string output_root;
private Object recording_lock = new Object();
int trial_id = 0;
bool recording = false;
int img_width;
int img_height;
double seconds_to_record = 10;
System.IO.StreamWriter recording_success_file = null;
ConcurrentQueue<Tuple<RawImage, bool, List<float>>> recording_objects;
// For broadcasting the results
ZeroMQ.ZContext zero_mq_context;
ZeroMQ.ZSocket zero_mq_socket;
volatile bool running = true;
volatile bool pause = false;
public void StartExperiment()
{
// Inquire more from the user
// Get the entry dialogue now for the subject ID
trial_id = 0;
TextEntryWindow subject_id_window = new TextEntryWindow();
subject_id_window.Icon = this.Icon;
subject_id_window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
if (subject_id_window.ShowDialog() == true)
{
subject_id = subject_id_window.ResponseText;
// Remove trailing spaces and full stops at the end of the folder name
int old_length;
do
{
old_length = subject_id.Length;
subject_id = subject_id.Trim();
if (subject_id.Length > 0)
{
while (subject_id[subject_id.Length - 1].Equals('.'))
{
subject_id = subject_id.Substring(0, subject_id.Length - 1);
}
}
} while (subject_id.Length != old_length);
output_root = record_root + subject_id + "/";
if (System.IO.Directory.Exists(output_root))
{
string messageBoxText = "The recording for subject already exists, are you sure you want to continue?";
string caption = "Directory exists!";
MessageBoxButton button = MessageBoxButton.YesNo;
MessageBoxImage icon = MessageBoxImage.Warning;
MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);
if (result == MessageBoxResult.No)
{
this.Close();
}
// Else find the latest trial from which to continu
int trial_id_not_found = 0;
while (System.IO.File.Exists(output_root + '/' + "trial_" + trial_id_not_found + ".avi"))
{
trial_id_not_found++;
}
trial_id = trial_id_not_found;
}
System.IO.Directory.CreateDirectory(output_root);
record_video = subject_id_window.RecordVideo;
record_head_pose = subject_id_window.RecordHeadPose;
RecordingButton.Content = "Record trial: " + trial_id;
}
else
{
this.Close();
}
}
public MainWindow()
{
InitializeComponent();
DateTime now = DateTime.Now;
// Set the icon
Uri iconUri = new Uri("logo1.ico", UriKind.RelativeOrAbsolute);
this.Icon = BitmapFrame.Create(iconUri);
// Warn about the liability
Liability liab = new Liability();
liab.Icon = BitmapFrame.Create(iconUri);
liab.ShowDialog();
if (!liab.continue_pressed)
{
this.Close();
return;
}
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("logo1.png", UriKind.RelativeOrAbsolute);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
logoLabel.Source = src;
// First make the user chooose a webcam
OpenFaceOffline.CameraSelection cam_select = new OpenFaceOffline.CameraSelection();
cam_select.Icon = BitmapFrame.Create(iconUri);
if (!cam_select.no_cameras_found)
{
cam_select.ShowDialog();
}
if (cam_select.camera_selected)
{
// Create the capture device
int cam_id = cam_select.selected_camera.Item1;
img_width = cam_select.selected_camera.Item2;
img_height = cam_select.selected_camera.Item3;
UtilitiesOF.SequenceReader reader = new UtilitiesOF.SequenceReader(cam_id, img_width, img_height);
if (reader.IsOpened())
{
// Create the ZeroMQ context for broadcasting the results
zero_mq_context = ZeroMQ.ZContext.Create();
zero_mq_socket = new ZSocket(zero_mq_context, ZeroMQ.ZSocketType.PUB);
// Bind on localhost port 5000
zero_mq_socket.Bind("tcp://127.0.0.1:5000");
processing_thread = new Thread(() => VideoLoop(reader));
processing_thread.Name = "Webcam processing";
processing_thread.Start();
}
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);
this.Close();
}
// Create an overlay image for display purposes
webcam_img = new OpenFaceOffline.OverlayImage();
webcam_img.SetValue(Grid.RowProperty, 1);
webcam_img.SetValue(Grid.ColumnProperty, 1);
MainGrid.Children.Add(webcam_img);
StartExperiment();
}
else
{
cam_select.Close();
this.Close();
}
}
private bool ProcessFrame(CLNF landmark_detector, GazeAnalyserManaged gaze_analyser, FaceModelParameters model_params, RawImage frame, RawImage grayscale_frame, float fx, float fy, float cx, float cy)
{
bool detection_succeeding = landmark_detector.DetectLandmarksInVideo(frame, model_params, grayscale_frame);
gaze_analyser.AddNextFrame(landmark_detector, detection_succeeding, fx, fy, cx, cy);
return detection_succeeding;
}
// Capturing and processing the video frame by frame
private void RecordingLoop()
{
// Set up the recording objects first
Thread.CurrentThread.IsBackground = true;
System.IO.StreamWriter output_head_pose_file = null;
if (record_head_pose)
{
String filename_poses = output_root + "/trial_" + trial_id + ".poses.txt";
output_head_pose_file = new System.IO.StreamWriter(filename_poses);
output_head_pose_file.WriteLine("time(ms), success, pose_X(mm), pose_Y(mm), pose_Z(mm), pitch(deg), yaw(deg), roll(deg)");
}
VideoWriter video_writer = null;
if (record_video)
{
double fps = processing_fps.GetFPS();
String filename_video = output_root + "/trial_" + trial_id + ".avi";
video_writer = new VideoWriter(filename_video, img_width, img_height, fps, true);
}
// The timiing should be when the item is captured, but oh well
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while (recording)
{
Tuple<RawImage, bool, List<float>> recording_object;
if (recording_objects.TryDequeue(out recording_object))
{
if (record_video)
{
video_writer.Write(recording_object.Item1);
}
if (record_head_pose)
{
String output_pose_line = stopWatch.ElapsedMilliseconds.ToString();
if (recording_object.Item2)
output_pose_line += ", 1";
else
output_pose_line += ", 0";
for (int i = 0; i < recording_object.Item3.Count; ++i)
{
double num = recording_object.Item3[i];
if (i > 2)
{
output_pose_line += ", " + num * 180 / Math.PI;
}
else
{
output_pose_line += ", " + num;
}
}
output_head_pose_file.WriteLine(output_pose_line);
}
}
Thread.Sleep(10);
}
// Clean up the recording
if (record_head_pose)
{
output_head_pose_file.Close();
}
}
// Capturing and processing the video frame by frame
private void VideoLoop(UtilitiesOF.SequenceReader reader)
{
Thread.CurrentThread.IsBackground = true;
String root = AppDomain.CurrentDomain.BaseDirectory;
FaceModelParameters model_params = new FaceModelParameters(root, true, false, false);
// Initialize the face detector
FaceDetector face_detector = new FaceDetector(model_params.GetHaarLocation(), model_params.GetMTCNNLocation());
// If MTCNN model not available, use HOG
if (!face_detector.IsMTCNNLoaded())
{
model_params.SetFaceDetector(false, true, false);
}
CLNF face_model = new CLNF(model_params);
GazeAnalyserManaged gaze_analyser = new GazeAnalyserManaged();
DateTime? startTime = CurrentTime;
var lastFrameTime = CurrentTime;
while (running)
{
//////////////////////////////////////////////
// CAPTURE FRAME AND DETECT LANDMARKS FOLLOWED BY THE REQUIRED IMAGE PROCESSING
//////////////////////////////////////////////
RawImage frame = reader.GetNextImage();
lastFrameTime = CurrentTime;
processing_fps.AddFrame();
var grayFrame = reader.GetCurrentFrameGray();
if (mirror_image)
{
frame.Mirror();
grayFrame.Mirror();
}
bool detectionSucceeding = ProcessFrame(face_model, gaze_analyser, model_params, frame, grayFrame, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
lock (recording_lock)
{
if (recording)
{
// Add objects to recording queues
List<float> pose = new List<float>();
face_model.GetPose(pose, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
recording_objects.Enqueue(new Tuple<RawImage, bool, List<float>>(frame, detectionSucceeding, pose));
}
}
List<Tuple<System.Windows.Point, System.Windows.Point>> lines = null;
List<Tuple<float, float>> eye_landmarks = null;
List<System.Windows.Point> landmarks = new List<System.Windows.Point>();
List<Tuple<System.Windows.Point, System.Windows.Point>> gaze_lines = null;
Tuple<float, float> gaze_angle = new Tuple<float, float>(0, 0);
var visibilities = face_model.GetVisibilities();
double scale = face_model.GetRigidParams()[0];
if (detectionSucceeding)
{
List<Tuple<float, float>> landmarks_doubles = face_model.CalculateAllLandmarks();
foreach (var p in landmarks_doubles)
landmarks.Add(new System.Windows.Point(p.Item1, p.Item2));
eye_landmarks = face_model.CalculateVisibleEyeLandmarks();
gaze_lines = gaze_analyser.CalculateGazeLines(reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
gaze_angle = gaze_analyser.GetGazeAngle();
lines = face_model.CalculateBox(reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
}
if (reset)
{
face_model.Reset();
reset = false;
}
// Visualisation updating
try
{
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
{
if (latest_img == null)
latest_img = frame.CreateWriteableBitmap();
List<float> pose = new List<float>();
face_model.GetPose(pose, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy());
int yaw = (int)(pose[4] * 180 / Math.PI + 0.5);
int yaw_abs = Math.Abs(yaw);
int roll = (int)(pose[5] * 180 / Math.PI + 0.5);
int roll_abs = Math.Abs(roll);
int pitch = (int)(pose[3] * 180 / Math.PI + 0.5);
int pitch_abs = Math.Abs(pitch);
YawLabel.Content = yaw_abs + "°";
RollLabel.Content = roll_abs + "°";
PitchLabel.Content = pitch_abs + "°";
if (yaw > 0)
YawLabelDir.Content = "Right";
else if (yaw < 0)
YawLabelDir.Content = "Left";
else
YawLabelDir.Content = "Straight";
if (pitch > 0)
PitchLabelDir.Content = "Down";
else if (pitch < 0)
PitchLabelDir.Content = "Up";
else
PitchLabelDir.Content = "Straight";
if (roll > 0)
RollLabelDir.Content = "Left";
else if (roll < 0)
RollLabelDir.Content = "Right";
else
RollLabelDir.Content = "Straight";
XPoseLabel.Content = (int)pose[0] + " mm";
YPoseLabel.Content = (int)pose[1] + " mm";
ZPoseLabel.Content = (int)pose[2] + " mm";
String x_angle = String.Format("{0:F0}°", gaze_angle.Item1 * (180.0 / Math.PI));
String y_angle = String.Format("{0:F0}°", gaze_angle.Item2 * (180.0 / Math.PI));
YawLabelGaze.Content = x_angle;
PitchLabelGaze.Content = y_angle;
if (gaze_angle.Item1 > 0)
YawLabelGazeDir.Content = "Right";
else if (gaze_angle.Item1 < 0)
YawLabelGazeDir.Content = "Left";
else
YawLabelGazeDir.Content = "Straight";
if (gaze_angle.Item2 > 0)
PitchLabelGazeDir.Content = "Down";
else if (gaze_angle.Item2 < 0)
PitchLabelGazeDir.Content = "Up";
else
PitchLabelGazeDir.Content = "Straight";
double confidence = face_model.GetConfidence();
if (confidence < 0)
confidence = 0;
else if (confidence > 1)
confidence = 1;
frame.UpdateWriteableBitmap(latest_img);
webcam_img.Clear();
webcam_img.Source = latest_img;
webcam_img.Confidence.Add(confidence);
webcam_img.FPS = processing_fps.GetFPS();
if(detectionSucceeding)
{
webcam_img.OverlayLines.Add(lines);
webcam_img.OverlayPoints.Add(landmarks);
webcam_img.OverlayPointsVisibility.Add(visibilities);
webcam_img.FaceScale.Add(scale);
List<System.Windows.Point> eye_landmark_points = new List<System.Windows.Point>();
foreach (var p in eye_landmarks)
{
eye_landmark_points.Add(new System.Windows.Point(p.Item1, p.Item2));
}
webcam_img.OverlayEyePoints.Add(eye_landmark_points);
webcam_img.GazeLines.Add(gaze_lines);
// Publish the information for other applications
String str_head_pose = String.Format("{0}:{1:F2}, {2:F2}, {3:F2}, {4:F2}, {5:F2}, {6:F2}", "HeadPose", pose[0], pose[1], pose[2],
pose[3] * 180 / Math.PI, pose[4] * 180 / Math.PI, pose[5] * 180 / Math.PI);
zero_mq_socket.Send(new ZFrame(str_head_pose, Encoding.UTF8));
String str_gaze = String.Format("{0}:{1:F2}, {2:F2}", "GazeAngle", gaze_angle.Item1 * (180.0 / Math.PI), gaze_angle.Item2 * (180.0 / Math.PI));
zero_mq_socket.Send(new ZFrame(str_gaze, Encoding.UTF8));
}
}));
while (running & pause)
{
Thread.Sleep(10);
}
}
catch (TaskCanceledException)
{
// Quitting
break;
}
}
reader.Close();
System.Console.Out.WriteLine("Thread finished");
}
private void startRecordingButton_Click(object sender, RoutedEventArgs e)
{
lock (recording_lock)
{
RecordingButton.IsEnabled = false;
CompleteButton.IsEnabled = false;
PauseButton.IsEnabled = false;
recording_objects = new ConcurrentQueue<Tuple<RawImage, bool, List<float>>>();
recording = true;
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
// Start the recording thread
rec_thread = new Thread(RecordingLoop);
rec_thread.Start();
double d = seconds_to_record * 1000;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while (d > 1000)
{
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
{
RecordingButton.Content = ((int)(d / 1000)).ToString() + " seconds remaining";
}));
System.Threading.Thread.Sleep(1000);
d = seconds_to_record * 1000 - stopWatch.ElapsedMilliseconds;
}
if (d > 0)
{
System.Threading.Thread.Sleep((int)(d));
}
recording = false;
Dispatcher.Invoke(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 200), (Action)(() =>
{
RecordingButton.Content = "0 seconds remaining";
}));
Dispatcher.Invoke(() =>
{
lock (recording_lock)
{
// Wait for the recording thread to finish before enabling
rec_thread.Join();
string messageBoxText = "Was the tracking successful?";
string caption = "Success of tracking";
MessageBoxButton button = MessageBoxButton.YesNo;
MessageBoxImage icon = MessageBoxImage.Question;
MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);
if (recording_success_file == null)
{
recording_success_file = new System.IO.StreamWriter(output_root + "/recording_success.txt", true);
}
if (result == MessageBoxResult.Yes)
{
recording_success_file.WriteLine('1');
}
else
{
recording_success_file.WriteLine('0');
}
recording_success_file.Flush();
trial_id++;
RecordingButton.Content = "Record trial: " + trial_id;
RecordingButton.IsEnabled = true;
CompleteButton.IsEnabled = true;
PauseButton.IsEnabled = true;
}
});
}).Start();
}
}
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
reset = true;
}
private void CompleteButton_Click(object sender, RoutedEventArgs e)
{
StartExperiment();
}
private void MirrorButton_Click(object sender, RoutedEventArgs e)
{
mirror_image = !mirror_image;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Let it finish recording
recording = false;
if (rec_thread != null)
{
rec_thread.Join();
}
// Stop capture and tracking
running = false;
if (processing_thread != null)
{
processing_thread.Join();
}
}
private void MorrorButton_Click(object sender, RoutedEventArgs e)
{
}
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
pause = !pause;
if (pause)
{
PauseButton.Content = "Resume";
}
else
{
PauseButton.Content = "Pause";
}
}
private void ScreenshotButton_Click(object sender, RoutedEventArgs e)
{
PresentationSource source = PresentationSource.FromVisual(Application.Current.MainWindow);
var topLeft = source.CompositionTarget.TransformToDevice.Transform(new System.Windows.Point(this.Left, this.Top));
var bottomRight = source.CompositionTarget.TransformToDevice.Transform(new System.Windows.Point(this.Left + this.Width, this.Top + this.Height));
int Width = (int)(bottomRight.X - topLeft.X);
int Height = (int)(bottomRight.Y - topLeft.Y);
using (Bitmap bmpScreenCapture = new Bitmap(Width,
Height))
{
using (System.Drawing.Graphics g = Graphics.FromImage(bmpScreenCapture))
{
g.CopyFromScreen((int)(topLeft.X),
(int)(topLeft.Y),
0, 0,
bmpScreenCapture.Size,
CopyPixelOperation.SourceCopy);
// Write out the bitmap here encoded by a time-stamp?
String fname = output_root + DateTime.Now.ToString("yyyy-MMM-dd--HH-mm-ss") + ".png";
bmpScreenCapture.Save(fname, ImageFormat.Png);
}
}
}
}
}

View 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("HeadPose-live")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("HeadPose-live")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2017")]
[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")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <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 HeadPoseLive.Properties {
using System;
/// <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 (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeadPoseLive.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;
}
}
}
}

View 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>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <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 HeadPoseLive.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;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,17 @@
<Window x:Class="HeadPoseLive.TextEntryWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Configuration and subject information" Height="210" Width="300">
<Grid>
<StackPanel FocusManager.FocusedElement="{Binding ElementName=ResponseTextBox}">
<TextBlock HorizontalAlignment="Center" Text="Enter subject ID" FontSize="20"/>
<TextBox Margin="0,4,0,0" x:Name="ResponseTextBox" FontSize="20" Width="120" TextChanged="ResponseTextBox_TextChanged" />
<Label Name="warningLabel" Visibility="Collapsed" FontStyle="Italic" Foreground="Red" HorizontalAlignment="Center">Can't use the following characters: " \ / | &lt; > : * ?</Label>
<CheckBox HorizontalAlignment="Center" x:Name="RecordVideoCheckBox" Margin="-25,10,0,0" Content="Record video"/>
<CheckBox Margin="0,6,0,0" IsChecked="True" HorizontalAlignment="Center" x:Name="RecordHeadPoseCheckBox" Content="Record head pose"/>
<Button Margin="0,8,0,0" Content="OK" Click="OKButton_Click" Width="100" VerticalAlignment="Bottom"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,129 @@
///////////////////////////////////////////////////////////////////////////////
// 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.Linq;
using System.Text;
using System.Text.RegularExpressions;
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.Shapes;
namespace HeadPoseLive
{
/// <summary>
/// Interaction logic for TextEntryWindow.xaml
/// </summary>
public partial class TextEntryWindow : Window
{
public TextEntryWindow()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(TextEntry_KeyDown);
}
public string ResponseText
{
get { return ResponseTextBox.Text; }
set { ResponseTextBox.Text = value; }
}
public bool RecordVideo
{
get { return (bool)RecordVideoCheckBox.IsChecked; }
set { RecordVideoCheckBox.IsChecked = value; }
}
public bool RecordHeadPose
{
get { return (bool)RecordHeadPoseCheckBox.IsChecked; }
set { RecordHeadPoseCheckBox.IsChecked = value; }
}
private void OKButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
DialogResult = true;
}
private void TextEntry_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
DialogResult = true;
}
}
// Do not allow illegal characters like
private void ResponseTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Regex regex = new Regex("[/:*?<>|\"]");
Regex regex2 = new Regex(@"[\\]");
MatchCollection matches = regex.Matches(ResponseTextBox.Text);
MatchCollection matches2 = regex2.Matches(ResponseTextBox.Text);
if (matches.Count > 0 || matches2.Count > 0)
{
for (int i = matches.Count - 1; i >= 0; --i)
{
// Remove the illegal characters
ResponseTextBox.Text = ResponseTextBox.Text.Substring(0, matches[i].Index) + ResponseTextBox.Text.Substring(matches[i].Index + 1);
}
//tell the user
for (int i = matches2.Count - 1; i >= 0; --i)
{
// Remove the illegal characters
ResponseTextBox.Text = ResponseTextBox.Text.Substring(0, matches2[i].Index) + ResponseTextBox.Text.Substring(matches2[i].Index + 1);
}
warningLabel.Visibility = System.Windows.Visibility.Visible;
ResponseTextBox.SelectionStart = ResponseTextBox.Text.Length;
}
else
{
warningLabel.Visibility = System.Windows.Visibility.Collapsed;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ZeroMQ" version="4.1.0.22" targetFramework="net452" />
</packages>