Initial push of AffdexMe sample application.

This commit is contained in:
John Buczkowski 2015-04-20 18:48:48 -04:00
parent fb19a54689
commit 29f58e4f96
21 changed files with 1867 additions and 0 deletions

112
AffdexMe/AffdexMe.csproj Normal file
View File

@ -0,0 +1,112 @@
<?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>C:\AffdexMe\AffdexMe\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, Version=1.0.5588.11627, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Program Files (x86)\Affectiva\Affdex SDK\bin\debug\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="C:\AffdexMe\AffdexMe\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="C:\AffdexMe\AffdexMe\MainWindow.xaml.cs">
<DependentUpon>C:\AffdexMe\AffdexMe\MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="C:\AffdexMe\AffdexMe\Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="C:\AffdexMe\AffdexMe\Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="C:\AffdexMe\AffdexMe\Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>C:\AffdexMe\AffdexMe\Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>C:\AffdexMe\AffdexMe\Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Resource Include="C:\AffdexMe\AffdexMe\Fonts\Square.ttf" />
<None Include="C:\AffdexMe\AffdexMe\Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>C:\AffdexMe\AffdexMe\Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="C:\AffdexMe\AffdexMe\Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="C:\AffdexMe\AffdexMe\App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="C:\AffdexMe\AffdexMe\Resources\AffectivaLogo1.png" />
<Resource Include="C:\AffdexMe\AffdexMe\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>

View File

@ -0,0 +1,115 @@
<?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>{510690A2-DFD6-49AE-BB72-397D9CE8DC41}</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>${EXECUTABLE_OUTPUT_PATH}\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>${DOS_STYLE_SOURCE_DIR}\Resources\AffdexMe_Logo.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>${EXECUTABLE_OUTPUT_PATH}\Release</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<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="${DOS_STYLE_SOURCE_DIR}\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="${DOS_STYLE_SOURCE_DIR}\App.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="${DOS_STYLE_SOURCE_DIR}\MainWindow.xaml.cs">
<DependentUpon>${DOS_STYLE_SOURCE_DIR}\MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="${DOS_STYLE_SOURCE_DIR}\Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="${DOS_STYLE_SOURCE_DIR}\Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="${DOS_STYLE_SOURCE_DIR}\Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>${DOS_STYLE_SOURCE_DIR}\Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>${DOS_STYLE_SOURCE_DIR}\Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Resource Include="${DOS_STYLE_SOURCE_DIR}\Fonts\Square.ttf" />
<None Include="${DOS_STYLE_SOURCE_DIR}\Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>${DOS_STYLE_SOURCE_DIR}\Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="${DOS_STYLE_SOURCE_DIR}\Properties\" />
</ItemGroup>
<ItemGroup>
<None Include="${DOS_STYLE_SOURCE_DIR}\App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\${AFFDEX_DOTNET_SDK_PROJECT_NAME}\${AFFDEX_DOTNET_SDK_PROJECT_NAME}.vcxproj">
<Project>{c110158b-63b7-431d-bd07-fbed3226c2b7}</Project>
<Name>affdex-sdk-cli</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="${DOS_STYLE_SOURCE_DIR}\Resources\AffectivaLogo.jpg" />
<Resource Include="${DOS_STYLE_SOURCE_DIR}\Resources\AffectivaLogo1.png" />
<Resource Include="${DOS_STYLE_SOURCE_DIR}\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
{
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

24
AffdexMe/CMakelists.txt Normal file
View File

@ -0,0 +1,24 @@
# --------------
# CMake file AFFDEX-SDK-NET
# --------------
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
set(subProject AffdexMe)
PROJECT(${subProject})
#file(GLOB SRCS src/*.c*)
#file(GLOB HDRS include/*.h*)
FILE(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" DOS_STYLE_SOURCE_DIR)
CONFIGURE_FILE(${subProject}.csproj.template ${subProject}.csproj)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Properties/Resources.resx.template Properties/Resources.resx)
file( RELATIVE_PATH PROJECT_SUBDIR ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )
include_external_msproject(
${subProject} ${PROJECT_SUBDIR}/${subProject}.csproj
TYPE 510690A2-DFD6-49AE-BB72-397D9CE8DC41 ${AFFDEX_DOTNET_SDK_PROJECT_NAME})
add_dependencies(${subProject} ${AFFDEX_DOTNET_SDK_PROJECT_NAME})
SET (RELEASE_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}/Release/${subProject}.exe")
install(FILES ${RELEASE_OUTPUT_PATH} DESTINATION ${RUNTIME_INSTALL_DIRECTORY})

BIN
AffdexMe/Fonts/Square.ttf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

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>

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

@ -0,0 +1,792 @@
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();
}));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private String GetClassifierDataFolder()
{
String classifierPath = AFFDEX_DATA_PATH;
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()
{
String licenseFile = AFFDEX_LICENSE_FILE;
if (String.IsNullOrEmpty(licenseFile))
{
ShowExceptionAndShutDown("AFFDEX_LICENSE_DIR environment variable (Affdex License Folder) is not set");
}
// Test the directory
DirectoryInfo directoryInfo = new DirectoryInfo(licenseFile);
if (!directoryInfo.Exists)
{
ShowExceptionAndShutDown("AFFDEX_License_DIR (Affex License Folder) is set to an invalid folder location");
}
return licenseFile;
}
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;
canvasFacePoints.UpdateLayout();
mImageXScaleFactor = imgAffdexFaceDisplay.ActualWidth / affdexImage.getWidth();
mImageYScaleFactor = imgAffdexFaceDisplay.ActualHeight / affdexImage.getHeight();
SolidColorBrush pointBrush = new SolidColorBrush(Colors.Cornsilk);
foreach (var point in affdexFace.getFeaturePoints())
{
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 = affdexFace.getFeaturePoints().Max(r => r.x);
var xMin = affdexFace.getFeaturePoints().Min(r => r.x);
var yMax = affdexFace.getFeaturePoints().Max(r => r.y);
var yMin = affdexFace.getFeaturePoints().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();
}
}));
}
}
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
{
DateTime functionEnter = DateTime.Now;
mCurrentTimeStamp = image.getTimestamp();
// Update the Image control from the UI thread
//imgAffdexFaceDisplay.Source = rtb;
imgAffdexFaceDisplay.Source = ConstructImage(image.getBGRByteArray(), image.getWidth(), image.getHeight());
var elapseTime = (DateTime.Now - functionEnter).Milliseconds;
// 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(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);
// 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>

View File

@ -0,0 +1,127 @@
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="AffectivaLogo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>${DOS_STYLE_SOURCE_DIR}\Resources\AffectivaLogo.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="AffectivaLogo1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>${DOS_STYLE_SOURCE_DIR}\Resources\AffectivaLogo1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</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>

56
AffdexMe/ReadMe.txt Normal file
View File

@ -0,0 +1,56 @@
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 -
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
- 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
AFFDEX_LICENSE_FILE
- The AffdexMe app can be built and run in either debug or release mode.
To build and run in Debug Mode
----------------------------------------------
- Through Visual Studio, add browse to and add a reference to Affdex.dll located at the following location:
C:\Program Files (x86)\Affectiva\Affdex SDK\bin\debug\Affdex.dll
- Add the following to your system path:
C:\Program Files (x86)\Affectiva\Affdex SDK\bin\debug
To build and run in Release Mode:
------------------------------------------------
- Through Visual Studio, add browse to and add a reference to Affdex.dll located at the following location:
C:\Program Files (x86)\Affectiva\Affdex SDK\bin\release\Affdex.dll
- Add the following to your system path:
C:\Program Files (x86)\Affectiva\Affdex SDK\bin\release
- 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