AffdexMe upgraded to include a new selection ui as well as enable /
disable all expressions and emotions
This commit is contained in:
parent
e4ba8321e0
commit
383bb912e7
5 changed files with 461 additions and 217 deletions
|
@ -37,7 +37,7 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Affdex, Version=1.0.5589.23093, Culture=neutral, processorArchitecture=x86">
|
||||
<Reference Include="Affdex, Version=2.0.0.10, Culture=neutral, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>c:\Program Files (x86)\Affectiva\Affdex SDK\bin\release\Affdex.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -55,8 +55,14 @@
|
|||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WpfAnimatedGif">
|
||||
<HintPath>$(ProjectDir)packages\WpfAnimatedGif.1.4.13\lib\net\WpfAnimatedGif.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MetricSelectionUI.xaml.cs" />
|
||||
<Compile Include="NameToResourceConverter.cs" />
|
||||
<Compile Include="UpperCaseConverter.cs" />
|
||||
<Page Include="$(ProjectDir)MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -68,6 +74,10 @@
|
|||
<DependentUpon>$(ProjectDir)MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="MetricSelectionUI.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(ProjectDir)Properties\AssemblyInfo.cs">
|
||||
|
@ -102,9 +112,59 @@
|
|||
<Resource Include="$(ProjectDir)Resources\AffdexMe_Logo.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="affdex-native.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="affdex-native.dll" />
|
||||
<Resource Include="anger.jpg" />
|
||||
<Resource Include="attention.jpg" />
|
||||
<Resource Include="brow_furrow.jpg" />
|
||||
<Resource Include="brow_raise.jpg" />
|
||||
<Resource Include="chin_raise.jpg" />
|
||||
<Resource Include="contempt.jpg" />
|
||||
<Resource Include="disgust.jpg" />
|
||||
<Resource Include="engagement.jpg" />
|
||||
<Resource Include="eye_closure.jpg" />
|
||||
<Resource Include="fear.jpg" />
|
||||
<Resource Include="frown.jpg" />
|
||||
<Resource Include="inner_brow_raise.jpg" />
|
||||
<Resource Include="joy.jpg" />
|
||||
<Resource Include="lip_press.jpg" />
|
||||
<Resource Include="lip_pucker.jpg" />
|
||||
<Resource Include="lip_suck.jpg" />
|
||||
<Resource Include="mouth_open.jpg" />
|
||||
<Resource Include="negative_valence.jpg" />
|
||||
<Resource Include="nose_wrinkle.jpg" />
|
||||
<Resource Include="positive_valence.jpg" />
|
||||
<Resource Include="sadness.jpg" />
|
||||
<Resource Include="smile.jpg" />
|
||||
<Resource Include="smirk.jpg" />
|
||||
<Resource Include="surprise.jpg" />
|
||||
<Resource Include="upper_lip_raise.jpg" />
|
||||
<Resource Include="valence.jpg" />
|
||||
<Resource Include="anger.gif" />
|
||||
<Resource Include="attention.gif" />
|
||||
<Resource Include="brow_furrow.gif" />
|
||||
<Resource Include="brow_raise.gif" />
|
||||
<Resource Include="chin_raise.gif" />
|
||||
<Resource Include="contempt.gif" />
|
||||
<Resource Include="disgust.gif" />
|
||||
<Resource Include="engagement.gif" />
|
||||
<Resource Include="eye_closure.gif" />
|
||||
<Resource Include="fear.gif" />
|
||||
<Resource Include="frown.gif" />
|
||||
<Resource Include="inner_brow_raise.gif" />
|
||||
<Resource Include="joy.gif" />
|
||||
<Resource Include="lip_press.gif" />
|
||||
<Resource Include="lip_pucker.gif" />
|
||||
<Resource Include="lip_suck.gif" />
|
||||
<Resource Include="mouth_open.gif" />
|
||||
<Resource Include="negative_valence.gif" />
|
||||
<Resource Include="nose_wrinkle.gif" />
|
||||
<Resource Include="positive_valence.gif" />
|
||||
<Resource Include="sadness.gif" />
|
||||
<Resource Include="smile.gif" />
|
||||
<Resource Include="smirk.gif" />
|
||||
<Resource Include="surprise.gif" />
|
||||
<Resource Include="upper_lip_raise.gif" />
|
||||
<Resource Include="valence.gif" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<Setter Property="Margin" Value="1"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
|
@ -81,7 +81,7 @@
|
|||
<Setter Property="Margin" Value="1"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="MinWidth" Value="20"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
|
@ -103,7 +103,8 @@
|
|||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" TargetName="rectangle" Value="0.2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Trigger Property
|
||||
="IsPressed" Value="True">
|
||||
<Setter Property="Opacity" TargetName="rectangle" Value="0.3"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
|
@ -127,13 +128,16 @@
|
|||
<StackPanel Name="stackPanelImage" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
|
||||
<Grid Name="gridAffdexFaceDisplay" VerticalAlignment="Stretch" Width="auto" Height="560" >
|
||||
|
||||
<Image Name="imgAffdexFaceDisplay" Visibility="Hidden" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="UniformToFill"/>
|
||||
|
||||
<Image Name="imgAffdexLogoDisplay" Margin="40" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
Height="auto" Source="Resources/AffectivaLogo1.png" Visibility="Visible"/>
|
||||
Height="auto" Source="AffectivaLogo1.png" Visibility="Visible"/>
|
||||
|
||||
<Canvas Name="canvasFacePoints" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<TextBlock Name="interocularDistanceDisplay" Visibility="Hidden" Text="Interocular Distance: " FontWeight="SemiBold" Foreground="White" VerticalAlignment="Center" Margin="10,131,0,413"/>
|
||||
<TextBlock Name="pitchDisplay" Visibility="Hidden" Text="pitch: " FontWeight="SemiBold" Foreground="White" VerticalAlignment="Center" Margin="10,131,0,380"/>
|
||||
<TextBlock Name="yawDisplay" Visibility="Hidden" Text="Yaw: " FontWeight="SemiBold" Foreground="White" VerticalAlignment="Center" Margin="10,131,0,347"/>
|
||||
<TextBlock Name="rollDisplay" Visibility="Hidden" Text="Roll: " FontWeight="SemiBold" Foreground="White" VerticalAlignment="Center" Margin="10,131,0,314"/>
|
||||
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
@ -158,51 +162,51 @@
|
|||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="0" Margin="0,0,0,0">
|
||||
<TextBlock Name="txtSmileClassifierName" Text="SMILE" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<StackPanel Name="stackPanel0" Orientation="Vertical" Grid.Row="0" Grid.Column="0" Margin="0,0,0,0">
|
||||
<TextBlock Name="stackPanel0Name" Text="STACKPANEL0" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Name="txtSmileClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center"/>
|
||||
<TextBlock Name="txtSmileClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center"/>
|
||||
<TextBlock Name="stackPanel0ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center"/>
|
||||
<TextBlock Name="stackPanel0Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="txtFrownClassifierName" Text="FROWN" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<StackPanel Name="stackPanel1" Orientation="Vertical" Grid.Row="0" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="stackPanel1Name" Text="STACKPANEL1" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Name="txtFrownClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="txtFrownClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel1ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel1Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="0" Margin="0,0,0,0" >
|
||||
<TextBlock Name="txtBrowRaiseClassifierName" Text="BROW RAISE" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<StackPanel Name="stackPanel2" Orientation="Vertical" Grid.Row="1" Grid.Column="0" Margin="0,0,0,0" >
|
||||
<TextBlock Name="stackPanel2Name" Text="STACKPANEL2" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Name="txtBrowRaiseClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="txtBrowRaiseClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel2ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel2Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="txtValenceClassifierName" Text="VALENCE" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<StackPanel Name="stackPanel3" Orientation="Vertical" Grid.Row="1" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="stackPanel3Name" Text="STACKPANEL3" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Name="txtValenceClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="txtValenceClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center"/>
|
||||
<TextBlock Name="stackPanel3ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel3Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="2" Grid.Column="0" Margin="0,0,0,0" >
|
||||
<TextBlock Name="txtBrowLowerClassifierName" Text="BROW FURROW" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<StackPanel Name="stackPanel4" Orientation="Vertical" Grid.Row="2" Grid.Column="0" Margin="0,0,0,0" >
|
||||
<TextBlock Name="stackPanel4Name" Text="STACKPANEL4" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center"/>
|
||||
<Grid>
|
||||
<TextBlock Name="txtBrowLowerClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="txtBrowLowerClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel4ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel4Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Vertical" Grid.Row="2" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="txtEngagementClassifierName" Text="ENGAGEMENT" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center" />
|
||||
<StackPanel Name="stackPanel5" Orientation="Vertical" Grid.Row="2" Grid.Column="2" Margin="0,0,0,0" >
|
||||
<TextBlock Name="stackPanel5Name" Text="STACKPANEL5" Foreground="OrangeRed" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center" />
|
||||
<Grid>
|
||||
<TextBlock Name="txtEngagementClassifierValueBackground" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="txtEngagementClassifierValue" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel5ValueBackgroud" Width="50" Background="LimeGreen" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="stackPanel5Value" Width="50" TextAlignment="Center" Text="10%" FontWeight="SemiBold" Foreground="Black" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
@ -224,7 +228,7 @@
|
|||
|
||||
<Image Name="imgAffdexLogoBackground" Width="auto" Grid.Column="1" Grid.Row="1"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
Height="auto" Source="Resources/AffectivaLogo1.png" Margin="0,0,0,-34" Grid.RowSpan="2"/>
|
||||
Height="auto" Source="AffectivaLogo1.png" Margin="0,0,0,-34" Grid.RowSpan="2"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
@ -234,11 +238,13 @@
|
|||
<Grid HorizontalAlignment="Center">
|
||||
<GroupBox Margin="0,5,0,0" Height="40" VerticalAlignment="Stretch" BorderBrush="Transparent" BorderThickness="0">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Button Name="btnStartCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="55" Content="Start" />
|
||||
<Button Name="btnResetCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="56" Content="Reset" />
|
||||
<Button Name="btnShowPoints" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="90" Content="Show Points" />
|
||||
<Button Name="btnStopCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="55" Content="Stop" />
|
||||
<Button Name="btnExit" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Bottom" Width="55" Content="Exit" />
|
||||
<Button Name="btnStartCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="40" Content="Start" />
|
||||
<Button Name="btnResetCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="40" Content="Reset" />
|
||||
<Button Name="btnShowPoints" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="80" Content="Show Points" />
|
||||
<Button Name="btnShowMeasurements" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="120" Content="Show Measurements" />
|
||||
<Button Name="btnChooseWin" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="60" Content="Classifiers" Click="btnChooseWin_Click" />
|
||||
<Button Name="btnStopCamera" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Top" Width="40" Content="Stop" />
|
||||
<Button Name="btnExit" Style="{StaticResource CustomButtonStyle}" HorizontalAlignment="Center" Margin="0,0,5,0" VerticalAlignment="Bottom" Width="35" Content="Exit" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
|
|
|
@ -10,38 +10,21 @@ using System.Windows.Controls;
|
|||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
using Microsoft.Win32;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AffdexMe
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
public partial class MainWindow : Window, Affdex.ImageListener, Affdex.ProcessStatusListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Location of Affdex Data files
|
||||
/// </summary>
|
||||
private const String AFFDEX_DATA_PATH = "C:\\Program Files (x86)\\Affectiva\\Affdex SDK\\data";
|
||||
|
||||
/// <summary>
|
||||
/// Location of AffdexSDK Licence file
|
||||
/// </summary>
|
||||
private const String AFFDEX_LICENSE_FILE = "C:\\Program Files (x86)\\Affectiva\\Affdex SDK\\affdex.license";
|
||||
|
||||
#region Member Variables and Enums
|
||||
|
||||
enum AffdexFaceClassifiers : int
|
||||
{
|
||||
Smile = 0,
|
||||
BrowFurrow = 1,
|
||||
BrowRaise = 2,
|
||||
LipCornerDepressor = 3,
|
||||
Engagement = 4,
|
||||
Valence = 5
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The minimum length of the Classifier Value textbox
|
||||
/// </summary>
|
||||
|
@ -71,8 +54,9 @@ namespace AffdexMe
|
|||
|
||||
private Affdex.CameraDetector mCameraDetector;
|
||||
|
||||
private DateTime mStartTime;
|
||||
private StringCollection mEnabledClassifiers;
|
||||
|
||||
private DateTime mStartTime;
|
||||
private float mCurrentTimeStamp;
|
||||
|
||||
/// <summary>
|
||||
|
@ -82,6 +66,7 @@ namespace AffdexMe
|
|||
private double mImageYScaleFactor;
|
||||
|
||||
private bool mShowFacePoints;
|
||||
private bool mShowMeasurements;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -109,65 +94,34 @@ namespace AffdexMe
|
|||
|
||||
#region Listener Implementation
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
class Listener : Affdex.ImageListener, Affdex.ProcessStatusListener
|
||||
public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame image)
|
||||
{
|
||||
public event EventHandler<ImageCaptureDataUpdateArgs> ImageCaptureUpdate;
|
||||
public event EventHandler<ImageResultsDataUpdateArgs> ImageResultsUpdate;
|
||||
public event EventHandler<Affdex.AffdexException> ExceptionHandler;
|
||||
|
||||
public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame image)
|
||||
// For now only single face is supported
|
||||
if ((faces.Count() >= 1))
|
||||
{
|
||||
// For now only single face is supported
|
||||
if ((faces.Count() >= 1))
|
||||
{
|
||||
Affdex.Face face = faces[0];
|
||||
Affdex.Face face = faces[0];
|
||||
|
||||
if (ImageResultsUpdate != null)
|
||||
{
|
||||
ImageResultsDataUpdateArgs imageResultsData = new ImageResultsDataUpdateArgs()
|
||||
{
|
||||
Image = image,
|
||||
ImageResultsTimeStamp = image.getTimestamp(),
|
||||
Face = face
|
||||
};
|
||||
ImageResultsUpdate(this, imageResultsData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="affdexImage"></param>
|
||||
public void onImageCapture(Affdex.Frame image)
|
||||
{
|
||||
if (ImageCaptureUpdate != null)
|
||||
{
|
||||
ImageCaptureDataUpdateArgs imageCaptureData = new ImageCaptureDataUpdateArgs()
|
||||
{
|
||||
Image = image,
|
||||
ImageCaptureTimeStamp = image.getTimestamp()
|
||||
};
|
||||
ImageCaptureUpdate(this, imageCaptureData);
|
||||
|
||||
}
|
||||
UpdateClassifierPanel(face);
|
||||
DisplayFeaturePoints(image, face);
|
||||
DisplayMeasurements(face);
|
||||
}
|
||||
}
|
||||
|
||||
public void onProcessingException(Affdex.AffdexException ex)
|
||||
{
|
||||
if (ExceptionHandler != null)
|
||||
{
|
||||
ExceptionHandler(this, ex);
|
||||
}
|
||||
}
|
||||
public void onImageCapture(Affdex.Frame image)
|
||||
{
|
||||
UpdateClassifierPanel();
|
||||
DisplayImageToOffscreenCanvas(image);
|
||||
}
|
||||
|
||||
public void onProcessingFinished()
|
||||
{
|
||||
}
|
||||
};
|
||||
public void onProcessingException(Affdex.AffdexException ex)
|
||||
{
|
||||
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
|
||||
ShowExceptionAndShutDown(message);
|
||||
}
|
||||
|
||||
public void onProcessingFinished()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -183,6 +137,67 @@ namespace AffdexMe
|
|||
}));
|
||||
}
|
||||
|
||||
private String GetClassifierDataFolder()
|
||||
{
|
||||
// First see if we can get the Install Path from the registry
|
||||
RegistryKey rkCurrentUser = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
|
||||
RegistryKey rkAffdexMe = rkCurrentUser.OpenSubKey("Software\\Affectiva\\AffdexMe");
|
||||
String classifierPath = String.Empty;
|
||||
if (rkAffdexMe != null && !String.IsNullOrEmpty((String)rkAffdexMe.GetValue("Install Directory")))
|
||||
{
|
||||
classifierPath = (String)rkAffdexMe.GetValue("Install Directory") + "\\data";
|
||||
}
|
||||
else
|
||||
{
|
||||
String affdexClassifierDir = Environment.GetEnvironmentVariable("AFFDEX_DATA_DIR");
|
||||
if (String.IsNullOrEmpty(affdexClassifierDir))
|
||||
{
|
||||
ShowExceptionAndShutDown("AFFDEX_DATA_DIR environment variable (Classifier Data Directory) is not set");
|
||||
}
|
||||
else
|
||||
{
|
||||
classifierPath = affdexClassifierDir;
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(classifierPath);
|
||||
if (!directoryInfo.Exists)
|
||||
{
|
||||
ShowExceptionAndShutDown("AFFDEX_DATA_DIR (Classifier Data Directory) is set to an invalid folder location");
|
||||
}
|
||||
|
||||
return classifierPath;
|
||||
}
|
||||
|
||||
private String GetAffdexLicense()
|
||||
{
|
||||
// First see if we can get the License from the registry
|
||||
RegistryKey rkCurrentUser = Registry.LocalMachine;
|
||||
RegistryKey rkAffdexMe = rkCurrentUser.OpenSubKey("Software\\Affectiva\\AffdexMe");
|
||||
String licensePath = String.Empty;
|
||||
if ( rkAffdexMe != null && !String.IsNullOrEmpty((string)rkAffdexMe.GetValue("Install Directory")))
|
||||
{
|
||||
licensePath = (String)rkAffdexMe.GetValue("Install Directory");
|
||||
}
|
||||
else
|
||||
{
|
||||
licensePath = Environment.GetEnvironmentVariable("AFFDEX_LICENSE_DIR");
|
||||
if (String.IsNullOrEmpty(licensePath))
|
||||
{
|
||||
ShowExceptionAndShutDown("AFFDEX_LICENSE_DIR environment variable (Affdex License Folder) is not set");
|
||||
}
|
||||
}
|
||||
|
||||
// Test the directory
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(licensePath);
|
||||
if (!directoryInfo.Exists)
|
||||
{
|
||||
ShowExceptionAndShutDown("AFFDEX_License_DIR (Affex License Folder) is set to an invalid folder location");
|
||||
}
|
||||
|
||||
return licensePath + "\\affdex.license";
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -193,6 +208,7 @@ namespace AffdexMe
|
|||
{
|
||||
InitializeCameraApp();
|
||||
|
||||
mEnabledClassifiers = AffdexMe.Settings.Default.Classifiers;
|
||||
// Enable/Disable buttons on start
|
||||
btnStartCamera.IsEnabled =
|
||||
btnResetCamera.IsEnabled =
|
||||
|
@ -200,6 +216,16 @@ namespace AffdexMe
|
|||
btnStopCamera.IsEnabled =
|
||||
btnExit.IsEnabled = true;
|
||||
|
||||
if (AffdexMe.Settings.Default.ShowPoints)
|
||||
{
|
||||
btnShowPoints_Click(null, null);
|
||||
}
|
||||
|
||||
if (AffdexMe.Settings.Default.ShowMeasurements)
|
||||
{
|
||||
btnShowMeasurements_Click(null, null);
|
||||
}
|
||||
|
||||
this.ContentRendered += MainWindow_ContentRendered;
|
||||
}
|
||||
|
||||
|
@ -248,6 +274,29 @@ namespace AffdexMe
|
|||
return null;
|
||||
}
|
||||
|
||||
private void DisplayMeasurements(Affdex.Face affdexFace)
|
||||
{
|
||||
//Update measurements
|
||||
try
|
||||
{
|
||||
var result = this.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
if (mShowMeasurements && (affdexFace != null))
|
||||
{
|
||||
interocularDistanceDisplay.Text = String.Format("Interocular Distance: {0}", affdexFace.Measurements.InterocularDistance);
|
||||
pitchDisplay.Text = String.Format("Pitch Angle: {0}", affdexFace.Measurements.Orientation.Pitch);
|
||||
yawDisplay.Text = String.Format("Yaw Angle: {0}", affdexFace.Measurements.Orientation.Yaw);
|
||||
rollDisplay.Text = String.Format("Roll Angle: {0}", affdexFace.Measurements.Orientation.Roll);
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
|
||||
ShowExceptionAndShutDown(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayFeaturePoints(Affdex.Frame affdexImage, Affdex.Face affdexFace)
|
||||
{
|
||||
try
|
||||
|
@ -255,7 +304,7 @@ namespace AffdexMe
|
|||
// Plot Face Points
|
||||
if ((mShowFacePoints) && (affdexFace != null))
|
||||
{
|
||||
canvasFacePoints.Dispatcher.BeginInvoke((Action)(() =>
|
||||
var result = this.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
|
||||
{
|
||||
|
@ -268,7 +317,7 @@ namespace AffdexMe
|
|||
mImageYScaleFactor = imgAffdexFaceDisplay.ActualHeight / affdexImage.getHeight();
|
||||
|
||||
SolidColorBrush pointBrush = new SolidColorBrush(Colors.Cornsilk);
|
||||
var featurePoints = affdexFace.getFeaturePoints();
|
||||
var featurePoints = affdexFace.FeaturePoints;
|
||||
foreach (var point in featurePoints)
|
||||
{
|
||||
Ellipse ellipse = new Ellipse()
|
||||
|
@ -279,15 +328,15 @@ namespace AffdexMe
|
|||
};
|
||||
|
||||
canvasFacePoints.Children.Add(ellipse);
|
||||
Canvas.SetLeft(ellipse, point.x * mImageXScaleFactor);
|
||||
Canvas.SetTop(ellipse, point.y * mImageYScaleFactor);
|
||||
Canvas.SetLeft(ellipse, point.X * mImageXScaleFactor);
|
||||
Canvas.SetTop(ellipse, point.Y * mImageYScaleFactor);
|
||||
}
|
||||
|
||||
// Draw Face Bounding Rectangle
|
||||
var xMax = featurePoints.Max(r => r.x);
|
||||
var xMin = featurePoints.Min(r => r.x);
|
||||
var yMax = featurePoints.Max(r => r.y);
|
||||
var yMin = featurePoints.Min(r => r.y);
|
||||
var xMax = featurePoints.Max(r => r.X);
|
||||
var xMin = featurePoints.Min(r => r.X);
|
||||
var yMax = featurePoints.Max(r => r.Y);
|
||||
var yMin = featurePoints.Min(r => r.Y);
|
||||
|
||||
// Adjust the x/y min to accomodate all points
|
||||
xMin -= 2;
|
||||
|
@ -312,14 +361,11 @@ namespace AffdexMe
|
|||
Canvas.SetTop(boundingBox, yMin * mImageYScaleFactor);
|
||||
|
||||
mFeaturePointsSkipCount = 0;
|
||||
|
||||
affdexFace.Dispose();
|
||||
affdexImage.Dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch(Exception ex)
|
||||
{
|
||||
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
|
||||
ShowExceptionAndShutDown(message);
|
||||
|
@ -343,13 +389,19 @@ namespace AffdexMe
|
|||
// A Face was found - this comes from ImageResults CallBack
|
||||
if (face != null)
|
||||
{
|
||||
// Convert classifier value to Integer (percentage) for display purposes
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Smile] = Convert.ToInt32(Math.Round(face.getSmileScore(), MidpointRounding.AwayFromZero));
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.BrowFurrow] = Convert.ToInt32(Math.Round(face.getBrowFurrowScore(), MidpointRounding.AwayFromZero));
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.BrowRaise] = Convert.ToInt32(Math.Round(face.getBrowRaiseScore(), MidpointRounding.AwayFromZero));
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.LipCornerDepressor] = Convert.ToInt32(Math.Round(face.getLipCornerDepressorScore(), MidpointRounding.AwayFromZero));
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Engagement] = Convert.ToInt32(Math.Round(face.getEngagementScore(), MidpointRounding.AwayFromZero));
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Valence] = Convert.ToInt32(Math.Round(face.getValenceScore(), MidpointRounding.AwayFromZero));
|
||||
int index = 0;
|
||||
foreach (String metric in mEnabledClassifiers)
|
||||
{
|
||||
PropertyInfo info;
|
||||
float value = -1;
|
||||
if ((info = face.Expressions.GetType().GetProperty(NameMappings(metric))) != null) value = (float)info.GetValue(face.Expressions, null);
|
||||
else if ((info = face.Emotions.GetType().GetProperty(NameMappings(metric))) != null) value = (float)info.GetValue(face.Emotions, null);
|
||||
|
||||
// Convert classifier value to Integer (percentage) for display purposes
|
||||
mAffdexClassifierValues[index] = Convert.ToInt32(Math.Round(value, MidpointRounding.AwayFromZero));
|
||||
index++;
|
||||
|
||||
}
|
||||
|
||||
// Reset the cache count
|
||||
mCachedSkipFaceResultsCount = 0;
|
||||
|
@ -362,12 +414,7 @@ namespace AffdexMe
|
|||
}
|
||||
else if (++mCachedSkipFaceResultsCount > 10)
|
||||
{
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Smile] =
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.BrowFurrow] =
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.BrowRaise] =
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.LipCornerDepressor] =
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Engagement] =
|
||||
mAffdexClassifierValues[(int)AffdexFaceClassifiers.Valence] = 0;
|
||||
for (int r = 0; r < mAffdexClassifierValues.Count(); r++) mAffdexClassifierValues[r] = 0;
|
||||
|
||||
// If we haven't seen a face in the past 30 frames (roughly 30/15fps seconds), don't display the classifiers
|
||||
if (mCachedSkipFaceResultsCount >= 30)
|
||||
|
@ -376,21 +423,26 @@ namespace AffdexMe
|
|||
}
|
||||
}
|
||||
|
||||
// Only display the classifiers and FacePoints if we've had a re
|
||||
if (displayClassifiers)
|
||||
var result = this.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
// Update the Classifier Display
|
||||
UpdateClassifier(txtSmileClassifierName, txtSmileClassifierValue, txtSmileClassifierValueBackground, AffdexFaceClassifiers.Smile);
|
||||
UpdateClassifier(txtFrownClassifierName, txtFrownClassifierValue, txtFrownClassifierValueBackground, AffdexFaceClassifiers.LipCornerDepressor);
|
||||
UpdateClassifier(txtBrowRaiseClassifierName, txtBrowRaiseClassifierValue, txtBrowRaiseClassifierValueBackground, AffdexFaceClassifiers.BrowRaise);
|
||||
UpdateClassifier(txtValenceClassifierName, txtValenceClassifierValue, txtValenceClassifierValueBackground, AffdexFaceClassifiers.Valence);
|
||||
UpdateClassifier(txtBrowLowerClassifierName, txtBrowLowerClassifierValue, txtBrowLowerClassifierValueBackground, AffdexFaceClassifiers.BrowFurrow);
|
||||
UpdateClassifier(txtEngagementClassifierName, txtEngagementClassifierValue, txtEngagementClassifierValueBackground, AffdexFaceClassifiers.Engagement);
|
||||
}
|
||||
// Only display the classifiers and FacePoints if we've had a re
|
||||
if (displayClassifiers)
|
||||
{
|
||||
int r = 0;
|
||||
foreach (String classifier in mEnabledClassifiers)
|
||||
{
|
||||
String stackPanelName = String.Format("stackPanel{0}", r);
|
||||
TextBlock ClassifierName = (TextBlock) gridClassifierDisplay.FindName(String.Format("{0}Name", stackPanelName));
|
||||
TextBlock ClassifierValueBackgroud = (TextBlock)gridClassifierDisplay.FindName(String.Format("{0}ValueBackgroud", stackPanelName));
|
||||
TextBlock ClassifierValue = (TextBlock)gridClassifierDisplay.FindName(String.Format("{0}Value", stackPanelName));
|
||||
// Update the Classifier Display
|
||||
UpdateClassifier(ClassifierName, ClassifierValue, ClassifierValueBackgroud, classifier, r);
|
||||
r++;
|
||||
|
||||
// Update the Image control from the UI thread
|
||||
stackPanelClassifiers.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Update the Image control from the UI thread
|
||||
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
|
||||
{
|
||||
if (imgAffdexFaceDisplay.Visibility == Visibility.Hidden)
|
||||
|
@ -400,6 +452,10 @@ namespace AffdexMe
|
|||
stackPanelLogoBackground.Visibility = Visibility.Visible;
|
||||
}
|
||||
stackPanelClassifiers.Visibility = (displayClassifiers)?Visibility.Visible : Visibility.Hidden;
|
||||
interocularDistanceDisplay.Visibility = (displayClassifiers && mShowMeasurements) ? Visibility.Visible : Visibility.Hidden;
|
||||
pitchDisplay.Visibility = (displayClassifiers && mShowMeasurements) ? Visibility.Visible : Visibility.Hidden;
|
||||
yawDisplay.Visibility = (displayClassifiers && mShowMeasurements) ? Visibility.Visible : Visibility.Hidden;
|
||||
rollDisplay.Visibility = (displayClassifiers && mShowMeasurements) ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -411,11 +467,22 @@ namespace AffdexMe
|
|||
}
|
||||
}
|
||||
|
||||
private String NameMappings(String classifierName)
|
||||
{
|
||||
if (classifierName == "Frown")
|
||||
{
|
||||
return "LipCornerDepressor";
|
||||
}
|
||||
return classifierName;
|
||||
}
|
||||
|
||||
private void UpdateClassifier(TextBlock txtClassifier, TextBlock txtClassifierValue,
|
||||
TextBlock txtClassifierValueBackground, AffdexFaceClassifiers classifierIndex)
|
||||
TextBlock txtClassifierValueBackground, String classifierName, int classifierIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
UpperCaseConverter conv = new UpperCaseConverter();
|
||||
txtClassifier.Text = (String)conv.Convert(classifierName, null, null, null);
|
||||
int classifierValue = mAffdexClassifierValues[(int)classifierIndex];
|
||||
|
||||
// Calculate the width
|
||||
|
@ -432,13 +499,9 @@ namespace AffdexMe
|
|||
backgroundColor = Colors.Red;
|
||||
}
|
||||
|
||||
txtClassifierValue.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
txtClassifierValueBackground.Background = new SolidColorBrush(backgroundColor);
|
||||
txtClassifierValueBackground.Width = width;
|
||||
txtClassifierValue.Text = String.Format("{0}%", classifierValue);
|
||||
}));
|
||||
|
||||
txtClassifierValueBackground.Background = new SolidColorBrush(backgroundColor);
|
||||
txtClassifierValueBackground.Width = width;
|
||||
txtClassifierValue.Text = String.Format("{0}%", classifierValue);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -450,7 +513,7 @@ namespace AffdexMe
|
|||
private void DisplayImageToOffscreenCanvas(Affdex.Frame image)
|
||||
{
|
||||
// Update the Image control from the UI thread
|
||||
imgAffdexFaceDisplay.Dispatcher.BeginInvoke((Action)(() =>
|
||||
var result = this.Dispatcher.BeginInvoke((Action)(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -493,6 +556,7 @@ namespace AffdexMe
|
|||
btnStartCamera.Click += btnStartCamera_Click;
|
||||
btnStopCamera.Click += btnStopCamera_Click;
|
||||
btnShowPoints.Click += btnShowPoints_Click;
|
||||
btnShowMeasurements.Click += btnShowMeasurements_Click;
|
||||
btnResetCamera.Click += btnResetCamera_Click;
|
||||
btnExit.Click += btnExit_Click;
|
||||
|
||||
|
@ -510,6 +574,7 @@ namespace AffdexMe
|
|||
|
||||
// Face Points are off by default
|
||||
mShowFacePoints = false;
|
||||
mShowMeasurements = false;
|
||||
|
||||
// Show the logo
|
||||
imgAffdexLogoDisplay.Visibility = Visibility.Visible;
|
||||
|
@ -555,6 +620,44 @@ namespace AffdexMe
|
|||
}
|
||||
}
|
||||
|
||||
void btnShowMeasurements_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Style style;
|
||||
String buttonText = String.Empty;
|
||||
|
||||
mShowMeasurements = !mShowMeasurements;
|
||||
if (mShowMeasurements)
|
||||
{
|
||||
style = this.FindResource("PointsOnButtonStyle") as Style;
|
||||
buttonText = "Hide Measurements";
|
||||
interocularDistanceDisplay.Visibility = Visibility.Visible;
|
||||
pitchDisplay.Visibility = Visibility.Visible;
|
||||
yawDisplay.Visibility = Visibility.Visible;
|
||||
rollDisplay.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
style = this.FindResource("CustomButtonStyle") as Style;
|
||||
buttonText = "Show Measurements";
|
||||
interocularDistanceDisplay.Visibility = Visibility.Hidden;
|
||||
pitchDisplay.Visibility = Visibility.Hidden;
|
||||
yawDisplay.Visibility = Visibility.Hidden;
|
||||
rollDisplay.Visibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
btnShowMeasurements.Style = style;
|
||||
btnShowMeasurements.Content = buttonText;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
|
||||
ShowExceptionAndShutDown(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnResetCamera_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ResetCameraProcessing();
|
||||
|
@ -581,9 +684,18 @@ namespace AffdexMe
|
|||
|
||||
void btnExit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SaveSettings();
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
void SaveSettings()
|
||||
{
|
||||
AffdexMe.Settings.Default.ShowPoints = mShowFacePoints;
|
||||
AffdexMe.Settings.Default.ShowMeasurements = mShowMeasurements;
|
||||
AffdexMe.Settings.Default.Classifiers = mEnabledClassifiers;
|
||||
AffdexMe.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void ClearClassifiersAndPointsDisplay()
|
||||
{
|
||||
// Hide AffdexFace Image
|
||||
|
@ -591,6 +703,12 @@ namespace AffdexMe
|
|||
stackPanelLogoBackground.Visibility =
|
||||
stackPanelClassifiersBackground.Visibility = Visibility.Hidden;
|
||||
|
||||
//Clean measurements
|
||||
interocularDistanceDisplay.Text = String.Format("Interocular Distance: {0}", 0);
|
||||
pitchDisplay.Text = String.Format("Pitch Angle: {0}", 0);
|
||||
yawDisplay.Text = String.Format("Yaw Angle: {0}", 0);
|
||||
rollDisplay.Text = String.Format("Roll Angle: {0}", 0);
|
||||
|
||||
// Hide the Classifier Panel
|
||||
stackPanelClassifiers.Visibility = Visibility.Hidden;
|
||||
|
||||
|
@ -614,21 +732,33 @@ namespace AffdexMe
|
|||
}
|
||||
}
|
||||
|
||||
private void TurnOnClassifiers()
|
||||
{
|
||||
mCameraDetector.setDetectAllEmotions(false);
|
||||
mCameraDetector.setDetectAllExpressions(false);
|
||||
foreach (String metric in mEnabledClassifiers)
|
||||
{
|
||||
MethodInfo setMethodInfo = mCameraDetector.GetType().GetMethod(String.Format("setDetect{0}", NameMappings(metric)));
|
||||
setMethodInfo.Invoke(mCameraDetector, new object[] { true });
|
||||
}
|
||||
}
|
||||
|
||||
private void StartCameraProcessing()
|
||||
{
|
||||
try
|
||||
{
|
||||
btnStartCamera.IsEnabled = false;
|
||||
btnResetCamera.IsEnabled =
|
||||
btnShowPoints.IsEnabled =
|
||||
btnStopCamera.IsEnabled =
|
||||
btnExit.IsEnabled = true;
|
||||
|
||||
// Instantiate CameraDetector using default camera ID
|
||||
mCameraDetector = new Affdex.CameraDetector();
|
||||
mCameraDetector.setClassifierPath(AFFDEX_DATA_PATH);
|
||||
mCameraDetector.setClassifierPath(GetClassifierDataFolder());
|
||||
|
||||
// Set the Classifiers that we are interested in tracking
|
||||
mCameraDetector.setDetectSmile(true);
|
||||
mCameraDetector.setDetectBrowFurrow(true);
|
||||
mCameraDetector.setDetectBrowRaise(true);
|
||||
mCameraDetector.setDetectLipCornerDepressor(true);
|
||||
mCameraDetector.setDetectEngagement(true);
|
||||
mCameraDetector.setDetectValence(true);
|
||||
TurnOnClassifiers();
|
||||
|
||||
// Initialize Classifier cache
|
||||
for (int index = 0; index < mAffdexClassifierValues.Count(); index++)
|
||||
|
@ -637,23 +767,13 @@ namespace AffdexMe
|
|||
}
|
||||
|
||||
mCachedSkipFaceResultsCount = 0;
|
||||
mCameraDetector.setImageListener(this);
|
||||
mCameraDetector.setProcessStatusListener(this);
|
||||
|
||||
Listener listener = new Listener();
|
||||
listener.ImageCaptureUpdate += imageListener_ImageCaptureUpdate;
|
||||
listener.ImageResultsUpdate += imageListener_ImageResultsUpdate;
|
||||
listener.ExceptionHandler += imageListener_ExceptionHandler;
|
||||
|
||||
mCameraDetector.setImageListener(listener);
|
||||
mCameraDetector.setProcessStatusListener(listener);
|
||||
|
||||
btnStartCamera.IsEnabled = false;
|
||||
btnResetCamera.IsEnabled =
|
||||
btnShowPoints.IsEnabled =
|
||||
btnStopCamera.IsEnabled =
|
||||
btnExit.IsEnabled = true;
|
||||
|
||||
// Set the License Path
|
||||
mCameraDetector.setLicensePath(AFFDEX_LICENSE_FILE);
|
||||
mCameraDetector.setLicensePath(GetAffdexLicense());
|
||||
|
||||
mStartTime = DateTime.Now;
|
||||
mCameraDetector.start();
|
||||
|
@ -690,24 +810,6 @@ namespace AffdexMe
|
|||
}
|
||||
}
|
||||
|
||||
void imageListener_ExceptionHandler(object sender, Affdex.AffdexException ex)
|
||||
{
|
||||
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
|
||||
ShowExceptionAndShutDown(message);
|
||||
}
|
||||
|
||||
void imageListener_ImageResultsUpdate(object sender, MainWindow.ImageResultsDataUpdateArgs e)
|
||||
{
|
||||
UpdateClassifierPanel(e.Face);
|
||||
DisplayFeaturePoints(e.Image, e.Face);
|
||||
}
|
||||
|
||||
void imageListener_ImageCaptureUpdate(object sender, MainWindow.ImageCaptureDataUpdateArgs e)
|
||||
{
|
||||
UpdateClassifierPanel();
|
||||
DisplayImageToOffscreenCanvas(e.Image);
|
||||
}
|
||||
|
||||
private void ResetCameraProcessing()
|
||||
{
|
||||
try
|
||||
|
@ -748,8 +850,28 @@ namespace AffdexMe
|
|||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
StopCameraProcessing();
|
||||
SaveSettings();
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private void btnChooseWin_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Boolean wasRunning = false;
|
||||
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
|
||||
{
|
||||
StopCameraProcessing();
|
||||
ResetDisplayArea();
|
||||
wasRunning = true;
|
||||
}
|
||||
|
||||
MetricSelectionUI w = new MetricSelectionUI(mEnabledClassifiers);
|
||||
w.ShowDialog();
|
||||
mEnabledClassifiers = w.Classifiers;
|
||||
if (wasRunning)
|
||||
{
|
||||
StartCameraProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
60
AffdexMe/Properties/Settings.Designer.cs
generated
60
AffdexMe/Properties/Settings.Designer.cs
generated
|
@ -1,30 +1,70 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34209
|
||||
// Runtime Version:4.0.30319.18444
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AffdexMe.Properties
|
||||
{
|
||||
namespace AffdexMe {
|
||||
|
||||
|
||||
[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
|
||||
{
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.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
|
||||
{
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<ArrayOfString xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
||||
<string>Joy</string>
|
||||
<string>Sadness</string>
|
||||
<string>Anger</string>
|
||||
<string>Disgust</string>
|
||||
<string>Surprise</string>
|
||||
<string>Fear</string>
|
||||
</ArrayOfString>")]
|
||||
public global::System.Collections.Specialized.StringCollection Classifiers {
|
||||
get {
|
||||
return ((global::System.Collections.Specialized.StringCollection)(this["Classifiers"]));
|
||||
}
|
||||
set {
|
||||
this["Classifiers"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool ShowPoints {
|
||||
get {
|
||||
return ((bool)(this["ShowPoints"]));
|
||||
}
|
||||
set {
|
||||
this["ShowPoints"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool ShowMeasurements {
|
||||
get {
|
||||
return ((bool)(this["ShowMeasurements"]));
|
||||
}
|
||||
set {
|
||||
this["ShowMeasurements"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AffdexMe" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Classifiers" Type="System.Collections.Specialized.StringCollection" Scope="User">
|
||||
<Value Profile="(Default)"><?xml version="1.0" encoding="utf-16"?>
|
||||
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<string>Joy</string>
|
||||
<string>Sadness</string>
|
||||
<string>Anger</string>
|
||||
<string>Disgust</string>
|
||||
<string>Surprise</string>
|
||||
<string>Fear</string>
|
||||
</ArrayOfString></Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowPoints" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowMeasurements" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
Loading…
Reference in a new issue