Deploying The Face API Using Visual Studio 2017

Introduction

This article demonstrates how to use Face API with C# in Visual Studio 2017 and develop a simple Windows application that invokes the Face API to detect faces in an image, by framing the faces.

Prerequisites
  • Visual Studio 2015 or 2017
  • Azure Subscription.
What is Face API?

It detects human faces and compares the similar ones. Also, it organizes images into groups based on the similarity by identifying the previously tagged people in images. The Face API is also a service that provides how to detect the human face with single or group of members and also shows the difference in the face expressions.The cloud-based Face API provides developers with access to advanced face algorithms. MIcrosoft Face Algorithms enable face attribute detection and face recognition.

Follow these steps to create the Face API

Open the new WPF app in the Classic Windows Desktop templates.
 
Navigate to "File-->New--> Project-->Windows Classic Desktop-->WPF App(.NET framework) and give the name for your solution, followed by a click on "OK".



Our project is opened. In the Solution Explorer, we need to add two nuGet packages. Right click on your project (DemoApp) and click Manage NuGet Packages.





Then, we are going to get the Face API keys that are used in our app. To create the Face API keys, Click Here.
Press "Create" for the Face API to create the Face API.



Accept the terms and conditions also, give the desired country name, and press " Next " to proceed to the next step.

Choose the preferred account to login with.


And also, login by givig the email and password to log into the ACOM Azure website.

Then, it gives two keys - primary and secondary - to be used in our WPF application. Copy these keys from that website.



In Visual Studio, paste the following code in the MainWindow.xaml and replace the old code.
  1. <Window x:Class="DemoApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Face_API" Height="350" Width="525">  
  2.     <Grid x:Name="BackPanel">  
  3.         <Grid.ColumnDefinitions>  
  4.             <ColumnDefinition Width="194*" />  
  5.             <ColumnDefinition Width="323*" /> </Grid.ColumnDefinitions>  
  6.         <Image x:Name="FacePhoto" Stretch="Uniform" Margin="0,0,0,30" Grid.ColumnSpan="2" />  
  7.         <Button x:Name="BrowseButton" Margin="20,0,20,5" Height="20" VerticalAlignment="Bottom" Content="Browse..." Click="BrowseButton_Click" Grid.ColumnSpan="2" /> </Grid>  
  8. </Window>  
Then, paste the following code in the MainWindow.xaml.cs window. In the 18th line, change the "keys" word by the key that we copied from the subcription.
  1. using System;  
  2. using System.Linq;  
  3. using System.Threading.Tasks;  
  4. using System.Windows;  
  5. using System.Windows.Media;  
  6. using System.Windows.Media.Imaging;  
  7. using System.IO;  
  8. using Microsoft.ProjectOxford.Face;  
  9. using Microsoft.ProjectOxford.Face.Contract;  
  10. namespace DemoApp {  
  11.     /// <summary>  
  12.     /// Interaction logic for MainWindow.xaml  
  13.     /// </summary>  
  14.     public partial class MainWindow: Window {  
  15.         IFaceServiceClient faceServiceClient = new FaceServiceClient("Keys");  
  16.         private async void BrowseButton_Click(object sender, RoutedEventArgs e) {  
  17.             var openDlg = new Microsoft.Win32.OpenFileDialog();  
  18.             openDlg.Filter = "JPEG Image(*.jpg)|*.jpg";  
  19.             bool ? result = openDlg.ShowDialog(this);  
  20.             if (!(bool) result) {  
  21.                 return;  
  22.             }  
  23.             string filePath = openDlg.FileName;  
  24.             Uri fileUri = new Uri(filePath);  
  25.             BitmapImage bitmapSource = new BitmapImage();  
  26.             bitmapSource.BeginInit();  
  27.             bitmapSource.CacheOption = BitmapCacheOption.None;  
  28.             bitmapSource.UriSource = fileUri;  
  29.             bitmapSource.EndInit();  
  30.             FacePhoto.Source = bitmapSource;  
  31.             Title = "Detecting...";  
  32.             FaceRectangle[] faceRects = await UploadAndDetectFaces(filePath);  
  33.             Title = String.Format("Detection Finished. {0} face(s) detected", faceRects.Length);  
  34.             if (faceRects.Length > 0) {  
  35.                 DrawingVisual visual = new DrawingVisual();  
  36.                 DrawingContext drawingContext = visual.RenderOpen();  
  37.                 drawingContext.DrawImage(bitmapSource, new Rect(0, 0, bitmapSource.Width, bitmapSource.Height));  
  38.                 double dpi = bitmapSource.DpiX;  
  39.                 double resizeFactor = 96 / dpi;  
  40.                 foreach(var faceRect in faceRects) {  
  41.                     drawingContext.DrawRectangle(Brushes.Transparent, new Pen(Brushes.Red, 2), new Rect(faceRect.Left * resizeFactor, faceRect.Top * resizeFactor, faceRect.Width * resizeFactor, faceRect.Height * resizeFactor));  
  42.                 }  
  43.                 drawingContext.Close();  
  44.                 RenderTargetBitmap faceWithRectBitmap = new RenderTargetBitmap(  
  45.                     (int)(bitmapSource.PixelWidth * resizeFactor), (int)(bitmapSource.PixelHeight * resizeFactor), 96, 96, PixelFormats.Pbgra32);  
  46.                 faceWithRectBitmap.Render(visual);  
  47.                 FacePhoto.Source = faceWithRectBitmap;  
  48.             }  
  49.         }  
  50.         private async Task < FaceRectangle[] > UploadAndDetectFaces(string imageFilePath) {  
  51.             try {  
  52.                 using(Stream imageFileStream = File.OpenRead(imageFilePath)) {  
  53.                     var faces = await faceServiceClient.DetectAsync(imageFileStream);  
  54.                     var faceRects = faces.Select(face => face.FaceRectangle);  
  55.                     return faceRects.ToArray();  
  56.                 }  
  57.             } catch (Exception) {  
  58.                 return new FaceRectangle[0];  
  59.             }  
  60.         }  
  61.         public MainWindow() {  
  62.             InitializeComponent();  
  63.         }  
  64.     }  
  65. }  
Select Start to deploy our WPF application. Press "Browse" button to browse the image in the local computer.



Then, our app detects the image.



You can see that it has detected the faces in the image that we browsed from the local computer.



Summary

I hope you understood how to create the Face API application using C# in the Micosoft Visual Studio2017.