Quickstart: Detect faces in an image using the Face .NET SDK

In this quickstart, you will use the Face service SDK with C# to detect human faces in an image. For a working example of the code in this quickstart, see the Face project in the Cognitive Services Vision csharp quickstarts repo on GitHub.

If you don't have an Azure subscription, create a free account before you begin.

Prerequisites

Create the Visual Studio project

  1. In Visual Studio, create a new Console app (.NET Framework) project and name it FaceDetection.
  2. If there are other projects in your solution, select this one as the single startup project.
  3. Get the required NuGet packages. Right-click on your project in the Solution Explorer and select Manage NuGet Packages. Click the Browse tab and select Include prerelease; then find and install the following package:
  4. Make sure you have installed the latest versions of all NuGet packages for your project. Right-click on your project in the Solution Explorer and select Manage NuGet Packages. Click the Updates tab and install the latest versions of any packages that appear.

Add face detection code

Open the new project's Program.cs file. Here, you will add the code needed to load images and detect faces.

Include namespaces

Add the following using statements to the top of your Program.cs file.

using Microsoft.Azure.CognitiveServices.Vision.Face;
using Microsoft.Azure.CognitiveServices.Vision.Face.Models;

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

Add essential fields

Add the Program class with the following fields. This data specifies how to connect to the Face service and where to get the input data. You'll need to update the subscriptionKey field with the value of your subscription key, and you may need to change the faceEndpoint string so that it contains the correct region identifier. You'll also need to set the localImagePath and/or remoteImageUrl values to paths that point to actual image files.

The faceAttributes field is simply an array of certain types of attributes. It will specify which information to retrieve about the detected faces.

namespace DetectFace
{
    class Program
    {
        // subscriptionKey = "0123456789abcdef0123456789ABCDEF"
        private const string subscriptionKey = "<SubscriptionKey>";

        // You must use the same region as you used to get your subscription
        // keys. For example, if you got your subscription keys from westus,
        // replace "westcentralus" with "westus".
        //
        // Free trial subscription keys are generated in the westcentralus
        // region. If you use a free trial subscription key, you shouldn't
        // need to change the region.
        // Specify the Azure region
        private const string faceEndpoint =
            "https://westcentralus.api.cognitive.microsoft.com";

        // localImagePath = @"C:\Documents\LocalImage.jpg"
        private const string localImagePath = @"<LocalImage>";

        private const string remoteImageUrl =
            "https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg";

        private static readonly FaceAttributeType[] faceAttributes =
            { FaceAttributeType.Age, FaceAttributeType.Gender };

Create and use the Face client

Next, add the Main method of the Program class with the following code. This sets up a Face API client.

static void Main(string[] args)
{
    FaceClient faceClient = new FaceClient(
        new ApiKeyServiceClientCredentials(subscriptionKey),
        new System.Net.Http.DelegatingHandler[] { });
    faceClient.Endpoint = faceEndpoint;

Also in the Main method, add the following code to use the newly created Face client to detect faces in a remote and local image. The detection methods will be defined next.

    Console.WriteLine("Faces being detected ...");
    var t1 = DetectRemoteAsync(faceClient, remoteImageUrl);
    var t2 = DetectLocalAsync(faceClient, localImagePath);

    Task.WhenAll(t1, t2).Wait(5000);
    Console.WriteLine("Press any key to exit");
    Console.ReadLine();
}

Detect faces

Add the following method to the Program class. It uses the Face service client to detect faces in a remote image, referenced by a URL. It uses the faceAttributes field—the DetectedFace objects added to faceList will have the specified attributes (in this case, age and gender).

// Detect faces in a remote image
private static async Task DetectRemoteAsync(
    FaceClient faceClient, string imageUrl)
{
    if (!Uri.IsWellFormedUriString(imageUrl, UriKind.Absolute))
    {
        Console.WriteLine("\nInvalid remoteImageUrl:\n{0} \n", imageUrl);
        return;
    }

    try
    {
        IList<DetectedFace> faceList =
            await faceClient.Face.DetectWithUrlAsync(
                imageUrl, true, false, faceAttributes);

        DisplayAttributes(GetFaceAttributes(faceList, imageUrl), imageUrl);
    }
    catch (APIErrorException e)
    {
        Console.WriteLine(imageUrl + ": " + e.Message);
    }
}

Similarly, add the DetectLocalAsync method. It uses the Face service client to detect faces in a local image, referenced by a file path.

// Detect faces in a local image
private static async Task DetectLocalAsync(FaceClient faceClient, string imagePath)
{
    if (!File.Exists(imagePath))
    {
        Console.WriteLine(
            "\nUnable to open or read localImagePath:\n{0} \n", imagePath);
        return;
    }

    try
    {
        using (Stream imageStream = File.OpenRead(imagePath))
        {
            IList<DetectedFace> faceList =
                    await faceClient.Face.DetectWithStreamAsync(
                        imageStream, true, false, faceAttributes);
            DisplayAttributes(
                GetFaceAttributes(faceList, imagePath), imagePath);
        }
    }
    catch (APIErrorException e)
    {
        Console.WriteLine(imagePath + ": " + e.Message);
    }
}

Retrieve and display face attributes

Next, define the GetFaceAttributes method. It returns a string with the relevant attribute information.

private static string GetFaceAttributes(
    IList<DetectedFace> faceList, string imagePath)
{
    string attributes = string.Empty;

    foreach (DetectedFace face in faceList)
    {
        double? age = face.FaceAttributes.Age;
        string gender = face.FaceAttributes.Gender.ToString();
        attributes += gender + " " + age + "   ";
    }

    return attributes;
}

Finally, define the DisplayAttributes method to write face attribute data to the console output. You can then close the class and namespace.

        // Display the face attributes
        private static void DisplayAttributes(string attributes, string imageUri)
        {
            Console.WriteLine(imageUri);
            Console.WriteLine(attributes + "\n");
        }
    }
}

Run the app

A successful response will display the gender and age for each face in the image. For example:

https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg
Male 37   Female 56

Next steps

In this quickstart, you created a simple .NET console application that can use the Face API service to detect faces in both local and remote images. Next, follow a more in-depth tutorial to see how you can present face information to the user in an intuitive way.