From 512f0340c99156596acbd4f2a5b9d872d191e1b4 Mon Sep 17 00:00:00 2001 From: wangjun Date: Thu, 30 Mar 2017 11:06:24 +0800 Subject: [PATCH] Windows SDK GA release update (#21) * Add emotion support for SDK and Sample. * Update Cognitive-Common-Windows submodule. * Make userData as optional for CreateFaceListAsync * Add facial hair and head pose in sample. (#15) * Endpoint change. (#20) * Bump version to 1.2.5 --- ClientLibrary/Contract/ClientError.cs | 2 - ClientLibrary/Contract/FaceAttributes.cs | 11 ++++ ClientLibrary/FaceClientSDK.nuspec | 4 +- ClientLibrary/FaceServiceClient.cs | 6 +- ClientLibrary/IFaceServiceClient.cs | 8 ++- .../Microsoft.ProjectOxford.Face.csproj | 4 ++ .../Microsoft.ProjectOxford.Face.sln | 2 +- ClientLibrary/Properties/AssemblyInfo.cs | 6 +- ClientLibrary/packages.config | 3 +- README.md | 15 +---- Sample-WPF/App.config | 8 +-- Sample-WPF/Controls/Face.cs | 37 +++++------- Sample-WPF/Controls/FaceDetectionPage.xaml | 8 +-- Sample-WPF/Controls/FaceDetectionPage.xaml.cs | 58 ++++++++++++++++--- Sample-WPF/FaceAPI-WPF-Samples.csproj | 10 +++- Sample-WPF/Properties/AssemblyInfo.cs | 6 +- Sample-WPF/packages.config | 3 +- 17 files changed, 119 insertions(+), 72 deletions(-) diff --git a/ClientLibrary/Contract/ClientError.cs b/ClientLibrary/Contract/ClientError.cs index f4a90d0..c60282e 100644 --- a/ClientLibrary/Contract/ClientError.cs +++ b/ClientLibrary/Contract/ClientError.cs @@ -31,8 +31,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; -using System.Net; using System.Runtime.Serialization; namespace Microsoft.ProjectOxford.Face.Contract diff --git a/ClientLibrary/Contract/FaceAttributes.cs b/ClientLibrary/Contract/FaceAttributes.cs index 7b9d778..1474aa6 100644 --- a/ClientLibrary/Contract/FaceAttributes.cs +++ b/ClientLibrary/Contract/FaceAttributes.cs @@ -98,6 +98,17 @@ public FacialHair FacialHair get; set; } + /// + /// Gets or sets the emotion. + /// + /// + /// The emotion. + /// + public Microsoft.ProjectOxford.Common.Contract.EmotionScores Emotion + { + get; set; + } + /// /// Gets or sets the glasses type. /// diff --git a/ClientLibrary/FaceClientSDK.nuspec b/ClientLibrary/FaceClientSDK.nuspec index 781117c..b99c7da 100644 --- a/ClientLibrary/FaceClientSDK.nuspec +++ b/ClientLibrary/FaceClientSDK.nuspec @@ -12,9 +12,9 @@ true Microsoft Cognitive Services Face API Client Library Use Face API Client Library to enrich your apps with Microsoft's state-of-the-art cloud-based face algorithms. - User-configurable hostname + Support emotion attributes in Face Detection. Copyright (c) 2016 - Face Oxford ProjectOxford Microsoft Cognitive + Face Oxford ProjectOxford Microsoft Cognitive CognitiveServices diff --git a/ClientLibrary/FaceServiceClient.cs b/ClientLibrary/FaceServiceClient.cs index 5b261a2..ff64ea5 100644 --- a/ClientLibrary/FaceServiceClient.cs +++ b/ClientLibrary/FaceServiceClient.cs @@ -40,9 +40,7 @@ using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; - using Microsoft.ProjectOxford.Face.Contract; - using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -462,7 +460,7 @@ public async Task GetPersonGroupsAsync() public async Task ListPersonGroupsAsync(string start = "", int top = 1000) { var requestUrl = string.Format( - "{0}/{1}?start={2}$top={3}", + "{0}/{1}?start={2}&top={3}", ServiceHost, PersonGroupsQuery, start, @@ -781,7 +779,7 @@ public async Task GroupAsync(Guid[] faceIds) /// /// Task object. /// - public async Task CreateFaceListAsync(string faceListId, string name, string userData) + public async Task CreateFaceListAsync(string faceListId, string name, string userData = null) { var requestUrl = string.Format("{0}/{1}/{2}", ServiceHost, FaceListsQuery, faceListId); diff --git a/ClientLibrary/IFaceServiceClient.cs b/ClientLibrary/IFaceServiceClient.cs index 1e3d052..9aec727 100644 --- a/ClientLibrary/IFaceServiceClient.cs +++ b/ClientLibrary/IFaceServiceClient.cs @@ -36,7 +36,6 @@ using System.IO; using System.Net.Http.Headers; using System.Threading.Tasks; - using Microsoft.ProjectOxford.Face.Contract; namespace Microsoft.ProjectOxford.Face @@ -77,6 +76,11 @@ public enum FaceAttributeType /// Analyses glasses type /// Glasses, + + /// + /// Analyses emotion + /// + Emotion, } /// @@ -173,7 +177,7 @@ HttpRequestHeaders DefaultRequestHeaders /// The name. /// The user data. /// Task object. - Task CreateFaceListAsync(string faceListId, string name, string userData); + Task CreateFaceListAsync(string faceListId, string name, string userData = null); /// /// Creates a person asynchronously. diff --git a/ClientLibrary/Microsoft.ProjectOxford.Face.csproj b/ClientLibrary/Microsoft.ProjectOxford.Face.csproj index 343dd14..5f10716 100644 --- a/ClientLibrary/Microsoft.ProjectOxford.Face.csproj +++ b/ClientLibrary/Microsoft.ProjectOxford.Face.csproj @@ -68,6 +68,10 @@ + + packages\Microsoft.ProjectOxford.Common.1.0.324\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Microsoft.ProjectOxford.Common.dll + True + packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll True diff --git a/ClientLibrary/Microsoft.ProjectOxford.Face.sln b/ClientLibrary/Microsoft.ProjectOxford.Face.sln index be14e3b..b7d6e1d 100644 --- a/ClientLibrary/Microsoft.ProjectOxford.Face.sln +++ b/ClientLibrary/Microsoft.ProjectOxford.Face.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ProjectOxford.Face", "Microsoft.ProjectOxford.Face.csproj", "{25D58BA5-660F-407B-803C-22B4547C09DC}" EndProject diff --git a/ClientLibrary/Properties/AssemblyInfo.cs b/ClientLibrary/Properties/AssemblyInfo.cs index b1abcec..ba01b9c 100644 --- a/ClientLibrary/Properties/AssemblyInfo.cs +++ b/ClientLibrary/Properties/AssemblyInfo.cs @@ -37,9 +37,9 @@ [assembly: AssemblyDescription("Microsoft.ProjectOxford.Face")] [assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyProduct("Microsoft ProjectOxford")] -[assembly: AssemblyCopyright("Copyright © 2015 Microsoft")] +[assembly: AssemblyCopyright("Copyright © 2016 Microsoft")] [assembly: AssemblyTrademark("Microsoft")] [assembly: NeutralResourcesLanguage("en")] -[assembly: AssemblyVersion("1.2.1.1")] -[assembly: AssemblyFileVersion("1.2.1.1")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.5")] +[assembly: AssemblyFileVersion("1.2.5")] \ No newline at end of file diff --git a/ClientLibrary/packages.config b/ClientLibrary/packages.config index d7b3922..1c9b951 100644 --- a/ClientLibrary/packages.config +++ b/ClientLibrary/packages.config @@ -1,4 +1,5 @@  + - + \ No newline at end of file diff --git a/README.md b/README.md index 7c5f3dd..d1bfa4b 100644 --- a/README.md +++ b/README.md @@ -54,19 +54,8 @@ You can reach out to us anytime with questions and suggestions using our communi This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Updates -- **8/2016 update for [July 2016 Face API changes](https://www.microsoft.com/cognitive-services/en-us/face-api/documentation/overview#changes)** - - *Client Library* - - `VerifyAsync` interface with `faceId`, `personGroupId` and `personId` as paramters. - - Optional user-specified `confidenceThreshold` paramter in `IdentifyAsync`. - - `FindSimilarMatchMode` enum declaration and adopted in `FindSimilarAsync`. - - New `ListPersonGroupsAsync` interface with `start` and `top` as paramters and recommend to use `ListPersonGroupsAsync` instead of `GetPersonGroupsAsync`. - - *Sample* - - `Verfication` demo for face and person authentication. - - `FindSimilar` demo of `MatchFace` mode. - - +* [Face API Release Notes](https://www.microsoft.com/cognitive-services/en-us/face-api/documentation/ReleaseNotes) + ## License All Microsoft Cognitive Services SDKs and samples are licensed with the MIT License. For more details, see [LICENSE](). diff --git a/Sample-WPF/App.config b/Sample-WPF/App.config index f32ffc5..71a06ba 100644 --- a/Sample-WPF/App.config +++ b/Sample-WPF/App.config @@ -1,13 +1,13 @@ - + - + - - + + diff --git a/Sample-WPF/Controls/Face.cs b/Sample-WPF/Controls/Face.cs index 1f97938..fe00f4d 100644 --- a/Sample-WPF/Controls/Face.cs +++ b/Sample-WPF/Controls/Face.cs @@ -88,11 +88,6 @@ public class Face : INotifyPropertyChanged /// private string _facialHair; - /// - /// Indicates whether the face is smile or not - /// - private string _isSmiling; - /// /// Indicates the glasses type /// @@ -103,6 +98,11 @@ public class Face : INotifyPropertyChanged /// private string _headPose; + /// + /// Indicates the emotion + /// + private string _emotion; + #endregion Fields #region Events @@ -298,23 +298,6 @@ public string FacialHair } } - /// - /// Gets or sets a value indicating whether the face is smile or not - /// - public string IsSmiling - { - get - { - return _isSmiling; - } - - set - { - _isSmiling = value; - OnPropertyChanged(); - } - } - /// /// Gets or sets a value indicating the glasses type /// @@ -345,6 +328,16 @@ public string HeadPose } } + public string Emotion + { + get { return _emotion; } + set + { + _emotion = value; + OnPropertyChanged(); + } + } + #endregion Properties #region Methods diff --git a/Sample-WPF/Controls/FaceDetectionPage.xaml b/Sample-WPF/Controls/FaceDetectionPage.xaml index aacd523..41586a7 100644 --- a/Sample-WPF/Controls/FaceDetectionPage.xaml +++ b/Sample-WPF/Controls/FaceDetectionPage.xaml @@ -126,10 +126,10 @@ - - - - + + + + diff --git a/Sample-WPF/Controls/FaceDetectionPage.xaml.cs b/Sample-WPF/Controls/FaceDetectionPage.xaml.cs index abed750..ec81b90 100644 --- a/Sample-WPF/Controls/FaceDetectionPage.xaml.cs +++ b/Sample-WPF/Controls/FaceDetectionPage.xaml.cs @@ -32,15 +32,12 @@ // using System; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; namespace Microsoft.ProjectOxford.Face.Controls { @@ -204,7 +201,7 @@ private async void ImagePicker_Click(object sender, RoutedEventArgs e) // Show file picker dialog Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.DefaultExt = ".jpg"; - dlg.Filter = "Image files (*.jpg, *.png, *bmp, *.gif) | *.jpg; *.png; *.bmp; *.gif"; + dlg.Filter = "Image files (*.jpg, *.png, *.bmp, *.gif) | *.jpg; *.png; *.bmp; *.gif"; var result = dlg.ShowDialog(); if (result.HasValue && result.Value) @@ -230,7 +227,7 @@ private async void ImagePicker_Click(object sender, RoutedEventArgs e) string subscriptionKey = mainWindow._scenariosControl.SubscriptionKey; var faceServiceClient = new FaceServiceClient(subscriptionKey); - Contract.Face[] faces = await faceServiceClient.DetectAsync(fileStream, false, true, new FaceAttributeType[] { FaceAttributeType.Gender, FaceAttributeType.Age, FaceAttributeType.Smile, FaceAttributeType.Glasses, FaceAttributeType.HeadPose, FaceAttributeType.FacialHair }); + Contract.Face[] faces = await faceServiceClient.DetectAsync(fileStream, false, true, new FaceAttributeType[] { FaceAttributeType.Gender, FaceAttributeType.Age, FaceAttributeType.Smile, FaceAttributeType.Glasses, FaceAttributeType.HeadPose, FaceAttributeType.FacialHair, FaceAttributeType.Emotion }); MainWindow.Log("Response: Success. Detected {0} face(s) in {1}", faces.Length, SelectedFile); DetectedResultsInText = string.Format("{0} face(s) has been detected", faces.Length); @@ -247,10 +244,10 @@ private async void ImagePicker_Click(object sender, RoutedEventArgs e) FaceId = face.FaceId.ToString(), Gender = face.FaceAttributes.Gender, Age = string.Format("{0:#} years old", face.FaceAttributes.Age), - IsSmiling = face.FaceAttributes.Smile > 0.0 ? "Smile" : "Not Smile", Glasses = face.FaceAttributes.Glasses.ToString(), FacialHair = string.Format("Facial Hair: {0}", face.FaceAttributes.FacialHair.Moustache + face.FaceAttributes.FacialHair.Beard+face.FaceAttributes.FacialHair.Sideburns > 0 ? "Yes":"No"), - HeadPose = string.Format("Pitch: {0}, Roll: {1}, Yaw: {2}", Math.Round(face.FaceAttributes.HeadPose.Pitch, 2), Math.Round(face.FaceAttributes.HeadPose.Roll, 2), Math.Round(face.FaceAttributes.HeadPose.Yaw, 2)) + HeadPose = string.Format("Pitch: {0}, Roll: {1}, Yaw: {2}", Math.Round(face.FaceAttributes.HeadPose.Pitch, 2), Math.Round(face.FaceAttributes.HeadPose.Roll, 2), Math.Round(face.FaceAttributes.HeadPose.Yaw, 2)), + Emotion = $"{GetEmotion(face.FaceAttributes.Emotion)}" }); } @@ -271,6 +268,53 @@ private async void ImagePicker_Click(object sender, RoutedEventArgs e) } } + private string GetEmotion(Microsoft.ProjectOxford.Common.Contract.EmotionScores emotion) + { + string emotionType = string.Empty; + double emotionValue = 0.0; + if (emotion.Anger > emotionValue) + { + emotionValue = emotion.Anger; + emotionType = "Anger"; + } + if (emotion.Contempt > emotionValue) + { + emotionValue = emotion.Contempt; + emotionType = "Contempt"; + } + if (emotion.Disgust > emotionValue) + { + emotionValue = emotion.Disgust; + emotionType = "Disgust"; + } + if (emotion.Fear > emotionValue) + { + emotionValue = emotion.Fear; + emotionType = "Fear"; + } + if (emotion.Happiness > emotionValue) + { + emotionValue = emotion.Happiness; + emotionType = "Happiness"; + } + if (emotion.Neutral > emotionValue) + { + emotionValue = emotion.Neutral; + emotionType = "Neutral"; + } + if (emotion.Sadness > emotionValue) + { + emotionValue = emotion.Sadness; + emotionType = "Sadness"; + } + if (emotion.Surprise > emotionValue) + { + emotionValue = emotion.Surprise; + emotionType = "Surprise"; + } + return $"{emotionType}"; + } + #endregion Methods } } \ No newline at end of file diff --git a/Sample-WPF/FaceAPI-WPF-Samples.csproj b/Sample-WPF/FaceAPI-WPF-Samples.csproj index 11423f1..291ac9b 100644 --- a/Sample-WPF/FaceAPI-WPF-Samples.csproj +++ b/Sample-WPF/FaceAPI-WPF-Samples.csproj @@ -26,7 +26,7 @@ false true 0 - 1.0.0.%2a + 1.2.5 false false true @@ -52,8 +52,12 @@ 4 - - packages\Microsoft.ProjectOxford.Face.1.2.1.2\lib\portable-net45+wp80+win8+wpa81+aspnetcore50\Microsoft.ProjectOxford.Face.dll + + packages\Microsoft.ProjectOxford.Common.1.0.324\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Microsoft.ProjectOxford.Common.dll + True + + + packages\Microsoft.ProjectOxford.Face.1.2.5\lib\portable-net45+wp80+win8+wpa81+aspnetcore50\Microsoft.ProjectOxford.Face.dll True diff --git a/Sample-WPF/Properties/AssemblyInfo.cs b/Sample-WPF/Properties/AssemblyInfo.cs index b4f9f21..d6a63f8 100644 --- a/Sample-WPF/Properties/AssemblyInfo.cs +++ b/Sample-WPF/Properties/AssemblyInfo.cs @@ -45,7 +45,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyProduct("Microsoft ProjectOxford")] -[assembly: AssemblyCopyright("Copyright © 2015 Microsoft")] +[assembly: AssemblyCopyright("Copyright © 2016 Microsoft")] [assembly: AssemblyTrademark("Microsoft")] [assembly: AssemblyCulture("")] @@ -80,5 +80,5 @@ // 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")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.5")] +[assembly: AssemblyFileVersion("1.2.5")] \ No newline at end of file diff --git a/Sample-WPF/packages.config b/Sample-WPF/packages.config index 6111bf3..8b42a32 100644 --- a/Sample-WPF/packages.config +++ b/Sample-WPF/packages.config @@ -1,5 +1,6 @@  - + + \ No newline at end of file