Merge pull request #2 from Affectiva/affdexme

Merging AffdexMe SDK demo to master
This commit is contained in:
Jay Turcot 2015-04-21 14:54:08 -04:00
commit 00af1ee714
17 changed files with 1570 additions and 2 deletions

116
AffdexMe/AffdexMe.csproj Normal file
View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.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>{5B893EA1-EB11-425A-BF8A-05822F5E2C9A}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AffdexMe</RootNamespace>
<AssemblyName>AffdexMe</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>$(ProjectDir)Resources\AffdexMe_Logo.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Affdex" Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<HintPath>..\..\Program Files (x86)\Affectiva\Affdex SDK\bin\debug\Affdex.dll</HintPath>
</Reference>
<Reference Include="Affdex" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<HintPath>..\..\Program Files (x86)\Affectiva\Affdex SDK\bin\release\Affdex.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Page Include="$(ProjectDir)MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(ProjectDir)MainWindow.xaml.cs">
<DependentUpon>$(ProjectDir)MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="$(ProjectDir)Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(ProjectDir)Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="$(ProjectDir)Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>$(ProjectDir)Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>$(ProjectDir)Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Resource Include="$(ProjectDir)Fonts\Square.ttf" />
<None Include="$(ProjectDir)Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>$(ProjectDir)Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="$(ProjectDir)Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="$(ProjectDir)App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="$(ProjectDir)Resources\AffectivaLogo1.png" />
<Resource Include="$(ProjectDir)Resources\AffdexMe_Logo.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 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>

6
AffdexMe/App.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

82
AffdexMe/App.cs Normal file
View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.VisualBasic.ApplicationServices;
namespace AffdexMe
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
/// <summary>
/// From reference source: https://msdn.microsoft.com/en-us/library/vstudio/ms771662(v=vs.90).aspx
/// </summary>
public class EntryPoint
{
[STAThread]
public static void Main(string[] args)
{
SingleInstanceManager manager = new SingleInstanceManager();
manager.Run(args);
}
}
// Using VB bits to detect single instances and process accordingly:
// * OnStartup is fired when the first instance loads
// * OnStartupNextInstance is fired when the application is re-run again
// NOTE: it is redirected to this instance thanks to IsSingleInstance
public class SingleInstanceManager : WindowsFormsApplicationBase
{
SingleInstanceApplication app;
public SingleInstanceManager()
{
this.IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// First time app is launched
app = new SingleInstanceApplication();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
// Subsequent launches
base.OnStartupNextInstance(eventArgs);
app.Activate();
}
}
public class SingleInstanceApplication : Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
// Create and show the application's main window
MainWindow window = new MainWindow();
window.Show();
}
public void Activate()
{
// Reactivate application's main window
this.MainWindow.Activate();
}
}
}

8
AffdexMe/App.xaml Normal file
View File

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

17
AffdexMe/App.xaml.cs Normal file
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 AffdexMe
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

BIN
AffdexMe/Fonts/Square.ttf Normal file

Binary file not shown.

248
AffdexMe/MainWindow.xaml Normal file
View File

@ -0,0 +1,248 @@
<Window x:Class="AffdexMe.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AffdexMe"
Height="640" Width="480"
MinHeight="640" MinWidth="480"
MaxHeight="640" MaxWidth="480"
ResizeMode="NoResize"
Loaded="Window_Loaded"
Closing="Window_Closing">
<Window.Resources>
<Style TargetType="{x:Type ButtonBase}" x:Key="CustomButtonStyle">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF2778BB" Offset="0.51"/>
<GradientStop Color="#FF2683C5" Offset="0.484"/>
<GradientStop Color="#FF8CD4FF" Offset="1"/>
<GradientStop Color="#FF1973AE" Offset="0.497"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="BorderBrush" Value="#FF2B5F91"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="Height" Value="30"/>
<Setter Property="MinWidth" Value="20"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Stroke="{TemplateBinding BorderBrush}" RadiusX="15" RadiusY="15" Fill="{TemplateBinding Background}"/>
<Rectangle VerticalAlignment="Top" Height="10" Margin="7,2,7,1" RadiusX="10" RadiusY="10">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#11FFFFFF" Offset="1"/>
<GradientStop Color="#B2FFFFFF" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="rectangle" RadiusX="15" RadiusY="15" Fill="White" Margin="1" Opacity="0"/>
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False" Margin="{TemplateBinding Padding}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="rectangle" Value="0.2"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="rectangle" Value="0.3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Fill" TargetName="rectangle" Value="#666"/>
<Setter Property="Opacity" TargetName="rectangle" Value="0.6"/>
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ButtonBase}" x:Key="PointsOnButtonStyle">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF3CB371" Offset="0.51"/>
<GradientStop Color="#FF3CB371" Offset="0.484"/>
<GradientStop Color="#FF3CB371" Offset="1"/>
<GradientStop Color="#FF1973AE" Offset="0.497"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="BorderBrush" Value="#FF2B5F91"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="Height" Value="30"/>
<Setter Property="MinWidth" Value="20"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Stroke="{TemplateBinding BorderBrush}" RadiusX="15" RadiusY="15" Fill="{TemplateBinding Background}"/>
<Rectangle VerticalAlignment="Top" Height="10" Margin="7,2,7,1" RadiusX="10" RadiusY="10">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#11FFFFFF" Offset="1"/>
<GradientStop Color="#B2FFFFFF" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="rectangle" RadiusX="15" RadiusY="15" Fill="White" Margin="1" Opacity="0"/>
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False" Margin="{TemplateBinding Padding}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="rectangle" Value="0.2"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="rectangle" Value="0.3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Fill" TargetName="rectangle" Value="#666"/>
<Setter Property="Opacity" TargetName="rectangle" Value="0.6"/>
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Name="gridMainDisplay" Margin="0,0,0,0" >
<Grid Name="gridContentDisplay" DockPanel.Dock="Top">
<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"/>
<Canvas Name="canvasFacePoints" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</StackPanel>
<StackPanel Name="stackPanelClassifiersBackground" Orientation="Vertical" Background="Gainsboro" Height="130" HorizontalAlignment="Stretch" VerticalAlignment="Top" Opacity=".3" />
<StackPanel Name="stackPanelClassifiers" Orientation="Vertical" Background="Transparent" Height="130" HorizontalAlignment="Stretch" VerticalAlignment="Top" >
<Grid Name="gridClassifierDisplay" VerticalAlignment="Stretch" Background="Transparent" Margin="0,5,0,0"
Width="{Binding ElementName=stackPanelClassifiers, Path=ActualWidth}"
Height="{Binding ElementName=stackPanelClassifiers, Path=ActualHeight}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.36*" />
<ColumnDefinition Width="0.28*" />
<ColumnDefinition Width="0.36*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<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"/>
<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"/>
</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"/>
<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" />
</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"/>
<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" />
</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"/>
<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"/>
</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"/>
<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" />
</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" />
<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" />
</Grid>
</StackPanel>
</Grid>
</StackPanel>
<StackPanel Name="stackPanelLogoBackground" Orientation="Vertical" Background="Transparent" Height="75" HorizontalAlignment="Stretch" VerticalAlignment="Top" >
<Grid Name="gridLogoBackground">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.36*" />
<ColumnDefinition Width="0.28*" />
<ColumnDefinition Width="0.36*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="35" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<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"/>
</Grid>
</StackPanel>
</Grid>
<DockPanel VerticalAlignment="Bottom" Background="Coral" >
<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="80" 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" />
</StackPanel>
</GroupBox>
</Grid>
</DockPanel>
</Grid>
</Window>

755
AffdexMe/MainWindow.xaml.cs Normal file
View File

@ -0,0 +1,755 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;
namespace AffdexMe
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
/// <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:\\Affectiva\\Build\\AffdexfaceWindows\\bin\\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>
const int ClassiferValueDisplayLength = 90;
/// <summary>
/// So the Classifiers can be cached
/// </summary>
int[] mAffdexClassifierValues = new int[6];
/// <summary>
/// Once a face has been recognized, the number of captures that occur before the classifiers get zero displayed
/// This helps prevent classifier numbers from flashing on the screen.
/// </summary>
int mCachedSkipFaceResultsCount;
/// <summary>
/// Once a face's feature points get displayed, the number of successive captures that occur without
/// the points getting redrawn in the OnResults callback.
/// </summary>
int mFeaturePointsSkipCount;
/// <summary>
/// Used to delay the display of the Classifier panel until the 1st face is recognized
/// </summary>
bool mFirstFaceRecognized;
private Affdex.CameraDetector mCameraDetector;
private DateTime mStartTime;
private float mCurrentTimeStamp;
/// <summary>
/// Scale factor based on ratio between current and original size
/// </summary>
private double mImageXScaleFactor;
private double mImageYScaleFactor;
private bool mShowFacePoints;
#endregion
#region Image and Results Arg Classes
/// <summary>
///
/// </summary>
class ImageCaptureDataUpdateArgs
{
public float ImageCaptureTimeStamp {get; set;}
public Affdex.Frame Image { get; set; }
}
/// <summary>
///
/// </summary>
class ImageResultsDataUpdateArgs
{
public float ImageResultsTimeStamp { get; set; }
public Affdex.Frame Image { get; set; }
public Affdex.Face Face { get; set; }
}
#endregion
#region Listener Implementation
/// <summary>
///
/// </summary>
class Listener : Affdex.ImageListener, Affdex.ProcessStatusListener
{
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))
{
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);
}
}
public void onProcessingException(Affdex.AffdexException ex)
{
if (ExceptionHandler != null)
{
ExceptionHandler(this, ex);
}
}
public void onProcessingFinished()
{
}
};
#endregion
private void ShowExceptionAndShutDown(String exceptionMessage)
{
MessageBoxResult result = MessageBox.Show(exceptionMessage,
"AffdexMe Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
this.Dispatcher.BeginInvoke((Action)(() =>
{
StopCameraProcessing();
}));
}
public MainWindow()
{
InitializeComponent();
CenterWindowOnScreen();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
InitializeCameraApp();
// Enable/Disable buttons on start
btnStartCamera.IsEnabled =
btnResetCamera.IsEnabled =
btnShowPoints.IsEnabled =
btnStopCamera.IsEnabled =
btnExit.IsEnabled = true;
this.ContentRendered += MainWindow_ContentRendered;
}
/// <summary>
/// Once the window las been loaded and the content rendered, the camera
/// can be initialized and started. This sequence allows for the underlying controls
/// and watermark logo to be displayed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void MainWindow_ContentRendered(object sender, EventArgs e)
{
StartCameraProcessing();
}
/// <summary>
///
/// </summary>
private void CenterWindowOnScreen()
{
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
double windowWidth = this.Width;
double windowHeight = this.Height;
this.Left = (screenWidth / 2) - (windowWidth / 2);
this.Top = (screenHeight / 2) - (windowHeight / 2);
}
private BitmapSource ConstructImage(byte[] imageData, int width, int height)
{
try
{
if (imageData != null && imageData.Length > 0)
{
var stride = (width * PixelFormats.Bgr24.BitsPerPixel + 7) / 8;
var imageSrc = BitmapSource.Create(width, height, 96d, 96d, PixelFormats.Bgr24, null, imageData, stride);
return imageSrc;
}
}
catch(Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
return null;
}
private void DisplayFeaturePoints(Affdex.Frame affdexImage, Affdex.Face affdexFace)
{
try
{
// Plot Face Points
if ((mShowFacePoints) && (affdexFace != null))
{
canvasFacePoints.Dispatcher.BeginInvoke((Action)(() =>
{
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
{
// Clear the previous points
canvasFacePoints.Children.Clear();
canvasFacePoints.Width = imgAffdexFaceDisplay.ActualWidth;
canvasFacePoints.Height = imgAffdexFaceDisplay.ActualHeight;
mImageXScaleFactor = imgAffdexFaceDisplay.ActualWidth / affdexImage.getWidth();
mImageYScaleFactor = imgAffdexFaceDisplay.ActualHeight / affdexImage.getHeight();
SolidColorBrush pointBrush = new SolidColorBrush(Colors.Cornsilk);
var featurePoints = affdexFace.getFeaturePoints();
foreach (var point in featurePoints)
{
Ellipse ellipse = new Ellipse()
{
Width = 4,
Height = 4,
Fill = pointBrush
};
canvasFacePoints.Children.Add(ellipse);
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);
// Adjust the x/y min to accomodate all points
xMin -= 2;
yMin -= 2;
// Increase the width/height to accomodate the entire max pixel position
// EllipseWidth + N to make sure max points in the box
double width = (xMax - xMin + 6) * mImageXScaleFactor;
double height = (yMax - yMin + 6) * mImageYScaleFactor;
SolidColorBrush boundingBrush = new SolidColorBrush(Colors.Bisque);
Rectangle boundingBox = new Rectangle()
{
Width = width,
Height = height,
Stroke = boundingBrush,
StrokeThickness = 1,
};
canvasFacePoints.Children.Add(boundingBox);
Canvas.SetLeft(boundingBox, xMin * mImageXScaleFactor);
Canvas.SetTop(boundingBox, yMin * mImageYScaleFactor);
mFeaturePointsSkipCount = 0;
affdexFace.Dispose();
affdexImage.Dispose();
}
}));
}
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
/// <summary>
/// Since the panel is getting updated from a separate callback thread, access to controls must be
/// made through BeginInvoke()
/// </summary>
/// <param name="face"></param>
private void UpdateClassifierPanel(Affdex.Face face = null)
{
try
{
bool displayClassifiers = (imgAffdexFaceDisplay.Visibility == Visibility.Hidden)? false : true;
if (mCameraDetector.isRunning() == true)
{
// 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));
// Reset the cache count
mCachedSkipFaceResultsCount = 0;
mFirstFaceRecognized =
displayClassifiers = true;
}
else if (mFirstFaceRecognized == false)
{
displayClassifiers = false;
}
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;
// If we haven't seen a face in the past 30 frames (roughly 30/15fps seconds), don't display the classifiers
if (mCachedSkipFaceResultsCount >= 30)
{
displayClassifiers = false;
}
}
// Only display the classifiers and FacePoints if we've had a re
if (displayClassifiers)
{
// 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);
}
// Update the Image control from the UI thread
stackPanelClassifiers.Dispatcher.BeginInvoke((Action)(() =>
{
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
{
if (imgAffdexFaceDisplay.Visibility == Visibility.Hidden)
{
imgAffdexFaceDisplay.Visibility =
stackPanelClassifiersBackground.Visibility =
stackPanelLogoBackground.Visibility = Visibility.Visible;
}
stackPanelClassifiers.Visibility = (displayClassifiers)?Visibility.Visible : Visibility.Hidden;
}
}));
}
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
private void UpdateClassifier(TextBlock txtClassifier, TextBlock txtClassifierValue,
TextBlock txtClassifierValueBackground, AffdexFaceClassifiers classifierIndex)
{
try
{
int classifierValue = mAffdexClassifierValues[(int)classifierIndex];
// Calculate the width
double width = ClassiferValueDisplayLength * Math.Abs(classifierValue) / 100;
var backgroundColor = Colors.Transparent;
if (classifierValue > 0)
{
backgroundColor = Colors.LimeGreen;
}
else if (classifierValue < 0)
{
backgroundColor = Colors.Red;
}
txtClassifierValue.Dispatcher.BeginInvoke((Action)(() =>
{
txtClassifierValueBackground.Background = new SolidColorBrush(backgroundColor);
txtClassifierValueBackground.Width = width;
txtClassifierValue.Text = String.Format("{0}%", classifierValue);
}));
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
private void DisplayImageToOffscreenCanvas(Affdex.Frame image)
{
// Update the Image control from the UI thread
imgAffdexFaceDisplay.Dispatcher.BeginInvoke((Action)(() =>
{
try
{
mCurrentTimeStamp = image.getTimestamp();
// Update the Image control from the UI thread
//imgAffdexFaceDisplay.Source = rtb;
imgAffdexFaceDisplay.Source = ConstructImage(image.getBGRByteArray(), image.getWidth(), image.getHeight());
// Allow N successive OnCapture callbacks before the FacePoint drawing canvas gets cleared.
if (++mFeaturePointsSkipCount > 4)
{
canvasFacePoints.Children.Clear();
mFeaturePointsSkipCount = 0;
}
if (image != null)
{
image.Dispose();
}
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}));
}
/// <summary>
///
/// </summary>
private void InitializeCameraApp()
{
try
{
mCameraDetector = null;
// Initialize Button Click Handlers
btnStartCamera.Click += btnStartCamera_Click;
btnStopCamera.Click += btnStopCamera_Click;
btnShowPoints.Click += btnShowPoints_Click;
btnResetCamera.Click += btnResetCamera_Click;
btnExit.Click += btnExit_Click;
// Disable Stop/Reset buttons
btnResetCamera.IsEnabled =
btnStopCamera.IsEnabled = false;
mFeaturePointsSkipCount =
mCachedSkipFaceResultsCount = 0;
// Initially hide Classifier Panels
stackPanelLogoBackground.Visibility =
stackPanelClassifiersBackground.Visibility =
stackPanelClassifiers.Visibility = Visibility.Hidden;
// Face Points are off by default
mShowFacePoints = false;
// Show the logo
imgAffdexLogoDisplay.Visibility = Visibility.Visible;
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void btnShowPoints_Click(object sender, RoutedEventArgs e)
{
try
{
Style style;
String buttonText = String.Empty;
mShowFacePoints = !mShowFacePoints;
if (mShowFacePoints)
{
style = this.FindResource("PointsOnButtonStyle") as Style;
buttonText = "Hide Points";
}
else
{
style = this.FindResource("CustomButtonStyle") as Style;
buttonText = "Show Points";
}
btnShowPoints.Style = style;
btnShowPoints.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();
}
void btnStartCamera_Click(object sender, RoutedEventArgs e)
{
try
{
StartCameraProcessing();
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
void btnStopCamera_Click(object sender, RoutedEventArgs e)
{
StopCameraProcessing();
ResetDisplayArea();
}
void btnExit_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void ClearClassifiersAndPointsDisplay()
{
// Hide AffdexFace Image
imgAffdexFaceDisplay.Visibility =
stackPanelLogoBackground.Visibility =
stackPanelClassifiersBackground.Visibility = Visibility.Hidden;
// Hide the Classifier Panel
stackPanelClassifiers.Visibility = Visibility.Hidden;
// Clear any Face Points
canvasFacePoints.Children.Clear();
}
private void ResetDisplayArea()
{
try
{
ClearClassifiersAndPointsDisplay();
// Show the logo
imgAffdexLogoDisplay.Visibility = Visibility.Visible;
}
catch (Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
private void StartCameraProcessing()
{
try
{
// Instantiate CameraDetector using default camera ID
mCameraDetector = new Affdex.CameraDetector();
mCameraDetector.setClassifierPath(AFFDEX_DATA_PATH);
// 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);
// Initialize Classifier cache
for (int index = 0; index < mAffdexClassifierValues.Count(); index++)
{
mAffdexClassifierValues[index] = 0;
}
mCachedSkipFaceResultsCount = 0;
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);
mStartTime = DateTime.Now;
mCameraDetector.start();
// Delay loading the Classifier panel until 1st face
mFirstFaceRecognized = false;
// Hide the logo
imgAffdexLogoDisplay.Visibility = Visibility.Hidden;
}
catch(Affdex.AffdexException ex)
{
if (!String.IsNullOrEmpty(ex.Message))
{
// If this is a camera failure, then reset the application to allow the user to turn on/enable camera
if (ex.Message.Equals("Unable to open webcam."))
{
MessageBoxResult result = MessageBox.Show(ex.Message,
"AffdexMe Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
StopCameraProcessing();
return;
}
}
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
catch(Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
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
{
mCameraDetector.reset();
}
catch(Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
private void StopCameraProcessing()
{
try
{
if ((mCameraDetector != null) && (mCameraDetector.isRunning()))
{
mCameraDetector.stop();
mCameraDetector.Dispose();
mCameraDetector = null;
}
// Enable/Disable buttons on start
btnStartCamera.IsEnabled = true;
btnResetCamera.IsEnabled =
btnStopCamera.IsEnabled = false;
}
catch(Exception ex)
{
String message = String.IsNullOrEmpty(ex.Message) ? "AffdexMe error encountered." : ex.Message;
ShowExceptionAndShutDown(message);
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
StopCameraProcessing();
Application.Current.Shutdown();
}
}
}

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("AffdexMe")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AffdexMe")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[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,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AffdexMe.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AffdexMe.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>

30
AffdexMe/Properties/Settings.Designer.cs generated Normal file
View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AffdexMe.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

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>

53
AffdexMe/README.md Normal file
View File

@ -0,0 +1,53 @@
# AffdexMe
**Affdex SDK** is the culmination of years of scientific research into emotion detection, validated across thousands of tests worldwide on PC platforms, and now made available as a software development kit for Windows. Affdex SDK turns your ordinary app into an extraordinary app by emotion-enabling it to respond in real-time to user emotions.
**AffdexMe** is a windows application that demonstrates the use of the Affdex SDK for Windows. It uses the camera on your Windows PC to view, process and analyze live video of your face. Start the app and you will see your own face on the screen, and metrics describing your expressions.
#### This app includes the following command buttons:
* Start - Starts the camera processing.
* Reset - Resets the context of the video frames.
* ShowPoints/HidePoints - toggles the display of facial feature points, which Affdex uses to detect expressions.
* Stop - Stops the camera processing.
* Exit - exits the application.
This application runs on Windows 7.0, 8.0 and 8.1
#### To use this project, you will need:
* Visual Studio 2013
* To download and install the Windows SDK from Affectiva By default, the Windows SDK is installed to the following location: C:\Program Files (x86)\Affectiva\Affdex SDK
If you have installed the SDK to a location other than the default, you will have to modify the following String constants located in the MainWindow.xaml.cs file:
* **AFFDEX_DATA_PATH** - the classifier data path
* **AFFDEX_LICENSE_FILE** - the full path to the Affdex license file (including the license file name)
* The AffdexMe app can be built and run in either debug or release mode.
**To build and run in Debug Mode**
* Through Visual Studio select the "Debug" configuration.
* Add the following to your system path: C:\Program Files (x86)\Affectiva\Affdex SDK\bin\debug
* Clean, rebuild and then run the project.
**To build and run in Release Mode:**
* Through Visual Studio select the "Debug" configuration.
* Add the following to your system path: C:\Program Files (x86)\Affectiva\Affdex SDK\bin\release
* Clean, rebuild and then run the project.
**It is important** not to mix Release and Debug versions of the DLLs. If you run into issues when switching between the two different build types, check to make sure that your system path points to the matching build type.
* In order to modify the system path, from the Control Panel, navigiate to the following: **Control Panel -> Advanced System Settings -> Environment Variables -> System Variables -> Path**
* Build the project
* Run the app through Visual Studio
Copyright (c) 2015 Affectiva. All rights reserved.

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

View File

@ -1,10 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.30723.0
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencv-webcam-demo", "opencv-webcam-demo\opencv-webcam-demo.vcxproj", "{8DCDC209-C25D-4C61-B2AC-2FBA1775DD6B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AffdexMe", "AffdexMe\AffdexMe.csproj", "{5B893EA1-EB11-425A-BF8A-05822F5E2C9A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Win32 = Release|Win32
@ -12,6 +14,7 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8DCDC209-C25D-4C61-B2AC-2FBA1775DD6B}.Release|Win32.ActiveCfg = Release|Win32
{8DCDC209-C25D-4C61-B2AC-2FBA1775DD6B}.Release|Win32.Build.0 = Release|Win32
{5B893EA1-EB11-425A-BF8A-05822F5E2C9A}.Release|Win32.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE