Partager via



Octobre 2016

Volume 31, numéro 10

Cet article a fait l'objet d'une traduction automatique.

Cognitive Services : reconnaissance des visages et émotions dans Xamarin avec Microsoft Cognitive Services

Par Alessandro Del Del

Lors de la conférence Build 2016, Microsoft a annoncé un premier aperçu de Services cognitifs (microsoft.com/cognitifs-services), un ensemble complet d’API RESTful que vous pouvez exploiter pour créer la nouvelle génération d’applications basées sur l’interaction utilisateur naturelle pour n’importe quelle plateforme sur tout appareil inter-plateformes. Services cognitives, également appelé « projet Oxford, » reposent sur la machine d’apprentissage et la philosophie de conversation en tant que plate-forme Microsoft est prêt à importer dans l’écosystème d’applications s’intègrent parfaitement. À un niveau supérieur, les API des Services cognitifs sont disponibles via les services RESTful et offre actuellement les catégories suivantes d’API :

  • Vision : Les services de Vision offrent des API qui vous permettent d’analyser les images et vidéos pour identifier les faces et émotions et pour détecter des informations utilisables. Cette catégorie inclut la Vision de l’ordinateur Face, émotion et API de la vidéo.
  • Reconnaissance vocale : Les services de reconnaissance vocale offrent des API qui le rendent plus facile à implémenter la synthèse vocale, la reconnaissance vocale naturelle et même de reconnaître qui communique avec le service de reconnaissance du conférencier. Ils incluent la reconnaissance vocale Bing, Service Intelligent de reconnaissance personnalisé et les API de reconnaissance du présentateur.
  • Langue : Les services de langage sont orientés vers la compréhension de langage naturel, ce qui signifie que la détection et correction des fautes d’orthographe, présentation des commandes vocales et l’analyse de texte complexe, y compris les sentiments et expressions clés. Ils incluent le Bing le vérificateur orthographique, Service Intelligent de langage de présentation, analyse linguistique, texte Analytique et modèle API Web.
  • Connaissance : Les services de base de connaissances permettent aux applications approfondir les connaissances de clients en recherchant les recommandations de produits personnalisées, des événements, emplacements et éducation livres ou les journaux. Ils incluent des connaissances universitaires, entité liaison Intelligence Service, Service d’Exploration de connaissances et les API Recommendations.
  • Search : Services de recherche sont basés sur Bing et vous permettent d’implémenter des puissants outils de recherche dans leurs applications. Noms de services inclus sont vraiment explicites : Bing de suggestion automatique, de recherche Bing Image, de recherche Bing News, Bing Search vidéo et API de recherche Bing Web.

Dans cet article, j’expliquerai comment combiner la Face et les API d’émotion pour récupérer les détails de l’image et d’émotions à partir d’images que vous pouvez effectuer à partir d’un appareil photo ou d’un album sur disque dans une application Xamarin.Forms créée avec c# et Visual Studio 2015 s’exécutant sur Android, iOS ou Windows 10. Figure 1 montre les résultats du didacticiel de l’article. Il est important de mentionner que, lorsque vous utilisez Xamarin.Forms pour cet article, le même peut être effectué avec des applications Xamarin traditionnelles, ainsi qu’avec toute autre plate-forme qui prend en charge de REST. Je suppose que vous avez une connaissance élémentaire de la création d’une application Xamarin.Forms et des concepts sur le partage de code ; Si ce n’est pas le cas, assurez-vous que vous lu mes articles précédents : « Créer une expérience Utilisateur interplateforme avec Xamarin.Forms » (msdn.com/magazine/mt595754) et « Partager du Code de l’interface Utilisateur sur les plateformes mobiles avec Xamarin.Forms » (msdn.com/magazine/dn904669).

Face et reconnaissance d’émotions sur une application interplateforme avec Xamarin.Forms
Figure 1 Face et reconnaissance d’émotions sur une application interplateforme avec Xamarin.Forms (appareil Android sur la gauche, Windows 10 Desktop située à droite)

L’abonnement aux Services cognitifs API

Pour créer des applications qui tirent parti des Services Cognitive, vous devez vous abonner au service qui vous intéresse. Actuellement, Microsoft est offre d’essais gratuits que vous pouvez activer dans la page Abonnements (bit.ly/2b2rKDO), mais les plans actuels peuvent être soumis à des modifications à l’avenir. Sur la page, inscrivez-vous avec un compte Microsoft, puis cliquez sur « Demander de nouvelles versions d’essai ». Vous devez voir une liste des services disponibles ; Veillez à que sélectionner les aperçus libres de la Face et les API émotion. À ce stade, votre page Abonnements affiche la liste des services actifs ; Vous devez voir les abonnements de Face et les API émotion. Figure 2 présente un exemple basé sur Mes abonnements. Notez comment, pour chaque service actif, il y a deux clés secrètes. Vous en faut un pour appeler l’API. Pour l’instant, conservez-les masqué. Vous allez afficher la clé lors de la création de l’application Xamarin.Forms.

Activation des abonnements de Face et les API d’émotion
Figure 2 activant des abonnements de Face et les API émotion

En règle générale, Services cognitifs fournissent une API RESTful, ce qui signifie que vous pouvez interagir avec ces services via des demandes HTTP sur n’importe quelle plateforme et avec n’importe quel langage prenant en charge le RESTE. Par exemple, la requête HTTP POST suivante montre comment envoyer une image au service pour la détection d’émotion reconnaissance émotion :

POST https://api.projectoxford.ai/emotion/v1.0/recognize HTTP/1.1
Content-Type: application/json
Host: api.projectoxford.ai
Content-Length: 107
Ocp-Apim-Subscription-Key: YOUR-KEY-GOES-HERE
{ "url": "http://www.samplewebsite.com/sampleimage.jpg" }

Bien sûr, vous devez remplacer Ocp-Apim-Subscription-Key avec l’une de vos propres clés et l’URL d’image factice avec une adresse de l’image réelle. Dans exchange, le service de reconnaissance d’émotions renverra le résultat de la détection en réponse JSON, comme indiqué dans Figure 3.

Figure 3 la réponse de détection du Service de reconnaissance émotion

[
  {
    "faceRectangle": {
      "height": 70,
      "left": 26,
      "top": 35,
      "width": 70
    },
    "scores": {
      "anger": 2.012591E-11,
      "contempt": 1.95578984E-10,
      "disgust": 1.02281912E-10,
      "fear": 1.16242682E-13,
      "happiness": 1.0,
      "neutral": 9.79047E-09,
      "sadness": 2.91102975E-10,
      "surprise": 1.71011272E-09
    }
  }
]

L’exemple de réponse à la Figure 3 montre comment l’émotion service a renvoyé le rectangle dans lequel une image a été détectée et un tableau appelé scores contenant une liste d’émotions et une valeur comprise entre 0 et 1 qui indique la probabilité l’émotion est true. En règle générale, l’envoi des demandes HTTP aux services RESTful et attend une réponse JSON sont une approche commune à tous les Services Cognitive. Toutefois, pour les développeurs .NET utilisation de c#, Microsoft est également offre client bibliothèques portables que vous pouvez le télécharger à partir de NuGet et le rendre plus facile d’interagir avec les services en code managé et d’une manière entièrement orienté objet. C’est le cas de la Face et les API émotion, comme vous le verrez bientôt. N’oubliez pas de consulter la documentation officielle, qui contient des exemples basés sur la méthode REST et bibliothèques clientes disponibles (bit.ly/2b2KJrB). Maintenant que vous avez enregistré pour les deux services et que vos clés, il est temps de créer une application interplateforme avec Xamarin.Forms et Microsoft Visual Studio 2015.

Création d’une Application Xamarin.Forms

Comme vous le savez, vous pouvez créer une application interplateforme avec Xamarin.Forms en choisissant l’ordinateur Portable ou le modèle de projet partagé. Étant donné que je vais expliquer comment exploiter les bibliothèques clientes pour les API des Services Cognitive, l’exemple d’application est basée sur le modèle de bibliothèque de classes Portable (PCL). Dans Visual Studio 2015, sélectionnez fichier | Nouveau projet. Si vous avez installé les dernières mises à jour à partir de Xamarin (xamarin.com/download), vous trouverez un nouveau modèle de projet appelé application Xaml vierge (Xamarin.Forms Portable) sous Visual c#, nœud Cross-Platform de la boîte de dialogue Nouveau projet. Il s’agit d’un modèle intéressant qui fournit une page XAML vierge et évite d’avoir à en créer un manuellement. Figure 4 montre le nouveau modèle.

Appelez la solution FaceEmotionRecognition et cliquez sur OK. Lors de la génération de la solution, vous devez spécifier la version cible minimale pour le projet de plate-forme de Windows universelle (UWP). En revanche, votre choix, mais je vous recommande de cibler la version la plus récente disponible.

Création d’une Application Xamarin.Forms
Figure 4 Création d’une Application Xamarin.Forms

Présentation des Plug-ins pour Xamarin

L’exemple d’application utiliseront les API de Services cognitifs reconnaît les détails de la face et émotions à partir d’images, à l’aide d’images existants à partir du périphérique ou de prendre de nouvelles images à partir de la caméra. Cela implique que l’application doit accéder à Internet pour vous connecter aux services et sera devez fournir la possibilité de prendre et de sélection d’images. Pendant une application peut facilement se connecter à un réseau, il est de votre responsabilité, en tant que développeur, pour vérifier la disponibilité du réseau. En fait, des fonctionnalités telles que la vérification de la disponibilité du réseau et prendre des photos nécessite l’écriture de code spécifique dans les projets Android, iOS et Windows. Heureusement, Xamarin prend en charge les plug-ins que vous pouvez utiliser dans Xamarin.Forms et que vous pouvez installer sur le projet PCL, afin qu’ils amèneront faire le travail pour vous. Un plug-in est une bibliothèque installée de NuGet qui encapsule les API natives dans une implémentation de code commune et appelé dans le projet PCL. Il existe un grand nombre des plug-ins, certains développés et pris en charge par Xamarin et d’autres créés et publiés par la Communauté des développeurs. Plug-ins sont tous open source et répertorié sur GitHub à l’adresse bit.ly/29XZ3VM. Dans cet article, je vais montrer à utiliser les plug-ins de connectivité et de support.

Installation des Packages NuGet

Lorsque la solution est prête, la première chose à faire est d’installer les packages NuGet suivants :

  • Microsoft.ProjectOxford.Face : Installe la bibliothèque cliente pour les API de Face et doit être installé pour seulement le projet PCL.
  • Microsoft.ProjectOxford.Emotion : Installe la bibliothèque cliente pour les API émotion et, comme pour la surface API, doit être installé pour seulement le projet PCL.
  • Xam.Plugin.Connectivity : Contient la connectivité plug-in pour Xamarin.Forms et doit être installé pour tous les projets dans la solution.
  • Xam.Plugin.Media : Contient le support plug-in pour Xamarin.Forms et, comme l’API de connectivité, doit être installé pour tous les projets dans la solution.

Une fois que vous avez installé les packages NuGet, assurez-vous que vous générez la solution avant d’écrire le code afin que toutes les références seront actualisées.

Conception de l'IU

L’interface Utilisateur de l’exemple d’application se compose d’une seule page. Par souci de simplicité, je vais utiliser le fichier MainPage.xaml généré automatiquement. Cette page définit deux boutons, une pour prendre une photo de l’appareil photo et un pour le chargement d’une image existante ; un contrôle ActivityIndicator qui présentent l’état occupé pendant l’attente d’une réponse du service ; un contrôle Image qui affiche l’image sélectionnée. nombre d’étiquettes, dans les volets de StackLayout, qui sont liés aux données à une classe personnalisée qui contient le résultat de détections sur l’image sélectionnée. Figure 5 illustre le code XAML complet pour la page.

Figure 5 l’interface Utilisateur pour le siège Page

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:local="clr-namespace:FaceEmotionRecognition"
  xmlns:conv="clr-namespace:FaceEmotionRecognition. 
    Converters;assembly=FaceEmotionRecognition"
    x:Class="FaceEmotionRecognition.MainPage">
  <StackLayout Orientation="Vertical">
    <Button x:Name="TakePictureButton" Clicked="TakePictureButton_Clicked"
      Text="Take from camera"/>
    <Button x:Name="UploadPictureButton" Clicked="UploadPictureButton_Clicked"
      Text="Pick a photo"/>
    <ActivityIndicator x:Name="Indicator1" IsVisible="False" IsRunning="False" />
    <Image x:Name="Image1" HeightRequest="240" />
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Gender: "/>
      <Label x:Name="GenderLabel" Text="{Binding Path=Gender}" />
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Age: "/>
      <Label x:Name="AgeLabel" Text="{Binding Path=Age}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Emotion: "/>
      <Label x:Name="EmotionLabel" Text="{Binding Path=Emotion}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Smile: "/>
      <Label x:Name="SmileLabel"
        Text="{Binding Path=Smile}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Glasses: "/>
      <Label x:Name="GlassesLabel" Text="{Binding Path=Glasses}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Beard: "/>
      <Label x:Name="BeardLabel"
        Text="{Binding Path=Beard}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Moustache: "/>
      <Label x:Name="MoustacheLabel"
        Text="{Binding Path=Moustache}"/>
    </StackLayout>
  </StackLayout>
</ContentPage>

L’étape suivante consiste à préparer un emplacement pour stocker le résultat de la détection de face et émotion.

Stockage des résultats de détection avec une classe

Au lieu de remplir manuellement les étiquettes dans l’interface Utilisateur avec les résultats de la détection de face et émotion, il est recommandé de créer une classe personnalisée. Non seulement cela constitue une approche plus orientée objet, mais il permet également de l’instance de la classe de liaison à l’interface Utilisateur de données. Ceci dit, nous allons créer une nouvelle classe appelée FaceEmotionDetection :

public class FaceEmotionDetection
{
  public string Emotion { get; set; }
  public double Smile { get; set; }
  public string Glasses { get; set; }
  public string Gender { get; set; }
  public double Age { get; set; }
  public double Beard { get; set; }
  public double Moustache { get; set; }
}

Chaque propriété a un nom explicite et stocke les informations provenant de la combinaison de la Face et les API d’émotion.

Déclarer les Clients de Service

Avant d’écrire un autre code, il est judicieux d’ajouter les éléments suivants à l’aide de directives :

using Microsoft.ProjectOxford.Emotion;
using Microsoft.ProjectOxford.Emotion.Contract;
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Face.Contract;
using Plugin.Connectivity;
using Plugin.Media;

Il simplifie l’appel aux noms d’objet pour les API des Services cognitifs et les plug-ins. Les API de Face et les API émotion fournissent le Microsoft.ProjectOxford.Face.FaceServiceClient et classes Microsoft.ProjectOxford.Emotion.EmotionServiceClient, qui se connectent aux Services cognitifs et respectivement retournent des informations sur les détails de face et émotion. Vous devez tout d’abord faire est de déclarer une instance, en passant la clé secrète pour le constructeur, comme indiqué ici :

private readonly IFaceServiceClient faceServiceClient;
private readonly EmotionServiceClient emotionServiceClient;
public MainPage()
{
  InitializeComponent();
  // Provides access to the Face APIs
  this.faceServiceClient = new FaceServiceClient("YOUR-KEY-GOES-HERE");
  // Provides access to the Emotion APIs
  this.emotionServiceClient = new EmotionServiceClient("YOUR-KEY-GOES-HERE");
}

Notez que vous devez fournir vos propres clés secrètes. Le type et l’API d’émotion clés secrètes sont accessibles dans la page abonnements du portail Microsoft Services cognitifs (bit.ly/2b2rKDO), comme indiqué dans Figure 2.

Capture et le chargement des Images

Dans Xamarin.Forms, l’accès à la caméra et le système de fichiers nécessiterait écrire du code de plate-forme spécifiques. Une approche plus simple qu’utilise le support de plug-in pour Xamarin.Forms, ce qui vous permet de choisir les images et vidéos à partir du disque et de prendre des photos et vidéos avec l’appareil photo à partir du projet PCL et avec seulement quelques lignes de code. Ce plug-in expose une classe appelée CrossMedia, qui expose les membres suivants :

  • En cours : Retourne une instance singleton de la classe CrossMedia.
  • IsPickPhotoSupported et IsPickVideoSupported : Propriétés bool qui retournent la valeur true si le périphérique en cours prend en charge la sélection des images et des vidéos à partir du disque.
  • PickPhotoAsync et PickVideoAsync : Les méthodes qui appellent l’interface Utilisateur spécifique à la plateforme pour sélectionner une image locale ou une vidéo, respectivement et retournent un objet de type MediaFile.
  • IsCameraAvailable : Propriété booléenne qui retourne true si le périphérique a une caméra intégrée.
  • IsTakePhotoSupported et IsTakeVideoSupported : Propriétés bool qui retournent la valeur true si le périphérique en cours prend en charge de prendre des photos et vidéos à partir de l’appareil photo.
  • TakePhotoAsync et TakeVideoAsync : Les méthodes qui lancement la caméra intégrée pour prendre une image ou vidéo, respectivement et retournent un objet de type MediaFile.

N’oubliez pas de définir les autorisations appropriées dans le manifeste d’application d’accéder à la caméra. Par exemple, dans un projet UWP besoin des autorisations de la Webcam et la bibliothèque d’images, tandis que sur Android, vous devez les autorisations de l’appareil PHOTO, READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE. Oublier de définir les autorisations requises provoquent des exceptions d’exécution. Maintenant nous allons écrire le Gestionnaire d’événements Clicked pour UploadPictureButton, ce qui est indiqué dans Figure 6.

Figure 6 sélection d’une image à partir du disque

private async void UploadPictureButton_Clicked(object sender, EventArgs e)
{
  if (!CrossMedia.Current.IsPickPhotoSupported)
  {
    await DisplayAlert("No upload", "Picking a photo is not supported.", "OK");
    return;
  }
  var file = await CrossMedia.Current.PickPhotoAsync();
  if (file == null)
    return;
  this.Indicator1.IsVisible = true;
  this.Indicator1.IsRunning = true;
  Image1.Source = ImageSource.FromStream(() => file.GetStream());
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}

Le code vérifie d’abord si la sélection d’images est pris en charge, indiquant une erreur de message si IsPickPhotoSupported retourne false. PickPhotoAsync (comme PickVideoAsync) retourne un objet de type MediaFile, qui est une classe définie dans l’espace de noms Plugin.Media et qui représente le fichier sélectionné. Vous devez appeler sa méthode GetStream pour retourner un flux qui peut être utilisé comme source pour le contrôle d’Image via sa méthode FromStream. Prendre une photo avec l’appareil photo est également très simple, comme indiqué dans Figure 7.

Figure 7 une photo avec l’appareil photo

private async void TakePictureButton_Clicked(object sender, EventArgs e)
{
  await CrossMedia.Current.Initialize();
  if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.
    IsTakePhotoSupported)
  {
    await DisplayAlert("No Camera", "No camera available.", "OK");
    return;
  }
  var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
  {
    SaveToAlbum = true,
    Name = "test.jpg"
  });
  if (file == null)
    return;
  this.Indicator1.IsVisible = true;
  this.Indicator1.IsRunning = true;
  Image1.Source = ImageSource.FromStream(() => file.GetStream());
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}

Le point d’intérêt ici est que TakePhotoAsync prend un paramètre de type StoreCameraMediaOptions, un objet qui vous permet de spécifier où et comment enregistrer une image. Si vous souhaitez que l’image à enregistrer dans la pellicule local, ou vous pouvez définir la propriété du répertoire si vous souhaitez enregistrer dans un dossier différent, vous pouvez définir la propriété SaveToAlbum true. Comme vous pouvez le voir, avec un effort très limité et avec quelques lignes de code, votre application peut exploiter facilement une fonctionnalité importante de toutes les plateformes prises en charge.

Détection des émotions et l’implémentation de reconnaissance faciale

Il est maintenant temps d’implémentation de reconnaissance de visage et émotion. Comme il s’agit d’un article de présentation, je me concentrerai sur plus de simplicité. Je montrerai comment implémenter la détection sur un type unique d’une image et je vais décrire les objets et les membres dans les API plus importantes. Je donnerai également vous des suggestions sur l’implémentation des détections plus détaillées le cas échéant. Basé sur les hypothèses, commençons écrire une méthode asynchrone qui effectue des détections. Le premier élément est sur la détection d’émotion et ressemble à ceci :

private async Task<FaceEmotionDetection> DetectFaceAndEmotionsAsync(MediaFile inputFile)
{
  try
  {
    // Get emotions from the specified stream
    Emotion[] emotionResult = await
      emotionServiceClient.RecognizeAsync(inputFile.GetStream());
    // Assuming the picture has one face, retrieve emotions for the
    // first item in the returned array
    var faceEmotion = emotionResult[0]?.Scores.ToRankedList();

La méthode reçoit le MediaFile qui est généré en sélectionnant ou prendre une photo. Détection des émotions sur faces sur une image est simple, car il suffit d’appeler la méthode RecognizeAsync à partir de l’instance de la classe EmotionServiceClient. Cette méthode peut recevoir un flux ou une URL en tant qu’argument. Dans ce cas, il obtient un flux de données à partir de l’objet MediaFile. RecognizeAsync retourne un tableau d’objets de l’émotion. Chaque émotion dans le tableau stocke émotions détectées sur un type unique d’une image. En supposant que l’image sélectionnée a qu’une seule image, le code récupère le premier élément du tableau. Le type émotion expose une propriété appelée Scores, qui contient une liste de noms de huit émotions et leur valeur approximative. Plus précisément, vous obtenez un IEnumerable < string, float >. En appelant sa méthode ToRankedList, vous pouvez obtenir une liste triée d’émotions détectées. Les API ne peut pas détecter une émotion unique avec précision. Au lieu de cela, ils détectent un nombre d’émotions possibles. La valeur la plus élevée retournée est environ l’émotion réelle sur la face, mais il existe toujours des autres valeurs qui a pu être vérifiées.  La valeur la plus élevée dans cette liste représente l’émotion au plus haut niveau de probabilité estimée, ce qui est probablement l’émotion réelle sur une face. Pour mieux comprendre, considérez ce qui suit la liste d’émotions de classement récupérées à l’aide des DataTips du débogueur, qui est basé sur l’exemple d’image indiqué dans Figure 1:

[0] = {[Happiness, 1]}
[1] = {[Neutral, 1.089301E-09]}
[2] = {[Surprise, 7.085784E-10]}
[3] = {[Sadness, 9.352855E-11]}
[4] = {[Disgust, 4.52789E-11]}
[5] = {[Contempt, 1.431213E-11]}
[6] = {[Anger, 1.25112E-11]}
[7] = {[Fear, 5.629648E-14]}

Comme vous pouvez le voir, bonheur a la valeur 1, ce qui est le plus élevé dans la liste et la probabilité estimée de l’émotion réelle. L’étape suivante détecte les attributs de police. La classe FaceServiceClient expose la méthode DetectAsync, qui est très puissante. Non seulement il récupérer face attributs telles que le sexe, l’âge et sourire, mais il peut également reconnaître des personnes, retourner le rectangle de face (la zone de l’image où l’image a été détectée) et des points de repère face 27 qui permettent à une application d’identifier les informations telles que la position de nez, bouche, oreilles et d’yeux sur l’image. DetectAsync possède la signature suivante :

Task<Contract.Face[]> DetectAsync(Stream imageStream,
  bool returnFaceId = true, bool returnFaceLandmarks = false,
  IEnumerable<FaceAttributeType> returnFaceAttributes = null);

Dans son appel plus simple, DetectAsync requiert un flux pointant vers une image ou d’une URL et retourne que le rectangle de face, bien que les paramètres facultatifs returnFaceId et returnFaceLandmarks, respectivement, vous permettre d’identifier une personne et retourner des repères de face. Les API Face vous permettent de créer des groupes d’utilisateurs et affecter un id à chaque personne afin que vous pouvez facilement effectuer la reconnaissance. Face repères sont utiles identifier les caractéristiques d’une face et seront disponibles via la propriété FaceLandmarks de l’objet de police. Identification et points d’intérêt sont présentées dans cet article, mais vous pouvez trouver plus d’informations sur ces sujets à bit.ly/2adPvoP et bit.ly/2ai9WjV, respectivement. De même, je ne vous montrer comment utiliser les repères de face, mais ceux-ci sont stockés dans la propriété FaceLandmarks de l’objet de police. Dans l’exemple de scénario en cours, l’objectif est de récupérer les attributs de police. La première chose que vous avez besoin est un tableau de l’énumération FaceAttributeType, qui définit la liste des attributs que vous souhaitez récupérer :

// Create a list of face attributes that the
// app will need to retrieve
var requiredFaceAttributes = new FaceAttributeType[] {
  FaceAttributeType.Age,
  FaceAttributeType.Gender,
  FaceAttributeType.Smile,
  FaceAttributeType.FacialHair,
  FaceAttributeType.HeadPose,
  FaceAttributeType.Glasses
  };

Ensuite, appelez DetectAsync, en passant le flux d’image et la liste d’attributs de police. Les arguments returnFaceId et returnFaceLandmarks ont la valeur false, car les informations associées ne sont pas nécessaire à ce stade. L’appel de méthode ressemble à ceci :

// Get a list of faces in a picture
var faces = await faceServiceClient.DetectAsync(inputFile.GetStream(),
  false, false, requiredFaceAttributes);
// Assuming there is only one face, store its attributes
var faceAttributes = faces[0]?.FaceAttributes;

DetectAsync retourne un tableau d’objets de Face, chacun représentant une face de l’image. Le code est le premier élément du tableau, ce qui représente un type unique et récupère ses attributs face. Notez comment la dernière ligne utilise l’opérateur conditionnel null ( ?), introduite avec c# 6, qui retourne la valeur null si le premier élément du tableau est également null au lieu de lever une exception NullReferenceException. Plus d’informations sur cet opérateur, consultez bit.ly/2bc8VZ3. Maintenant que vous disposez des informations de face et émotion, vous pouvez créer une instance de la classe FaceEmotionDetection et remplir ses propriétés, comme illustré dans le code suivant :

FaceEmotionDetection faceEmotionDetection = new FaceEmotionDetection();
faceEmotionDetection.Age = faceAttributes.Age;
faceEmotionDetection.Emotion = faceEmotion.FirstOrDefault().Key;
faceEmotionDetection.Glasses = faceAttributes.Glasses.ToString();
faceEmotionDetection.Smile = faceAttributes.Smile;
faceEmotionDetection.Gender = faceAttributes.Gender;
faceEmotionDetection.Moustache = faceAttributes.FacialHair.Moustache;
faceEmotionDetection.Beard = faceAttributes.FacialHair.Beard;

Quelques considérations à ce stade :

  • La valeur la plus élevée dans la liste d’émotions est effectuée en appelant FirstOrDefault sur le résultat de l’appel à la méthode Scores.ToRankedList, qui renvoie un IEnumerable < string, float >.
  • La valeur retournée par FirstOrDefault ici est un objet de type KeyValuePair < string, float > et la clé de type chaîne stocke le nom de l’émotion dans un texte lisible qui sera affiché dans l’interface Utilisateur.
  • LUNETTES est une énumération qui spécifie si la face détectée porte des lunettes et quel type. Le code appelle ToString par souci de simplicité, mais vous pouvez absolument implémenter un convertisseur de mise en forme de chaîne différentes.

Le bloc final dans le corps de la méthode retourne l’instance de la classe FaceEmotionDetection et implémente la gestion des exceptions :

return faceEmotionDetection;
  }
  catch (Exception ex)
  {
    await DisplayAlert("Error", ex.Message, "OK");
    return null;
  }
}

La dernière chose que vous avez à faire est d’appeler la méthode DetectFaceAndEmotionAsync personnalisée. Vous pouvez effectuer cela dans les deux gestionnaires d’événements Clicked, juste avant la définition des propriétés IsRunning et IsVisible du contrôle ActivityIndicator sur false :

FaceEmotionDetection theData = await DetectFaceAndEmotionsAsync(file);
this.BindingContext = theData;
this.Indicator1.IsRunning = false;
this.Indicator1.IsVisible = false;

La propriété BindingContext de la page reçoit une instance de la classe FaceEmotionDetection comme source de données et les contrôles liés aux données enfants affiche automatiquement les informations associées. Avec les modèles tels que Model-View-ViewModel, encapsulent le résultat avec une classe ViewModel. Après avoir beaucoup de travail, vous êtes prêt à tester l’application.

Test de l'application

Sélectionnez la plateforme de votre choix, puis appuyez sur F5. Si vous utilisez les émulateurs de Microsoft, vous pouvez tirer parti des outils émulateur pour sélectionner une webcam physique de prendre des photos et vous pouvez simuler une carte SD pour télécharger des fichiers. Figure 1 montre le résultat de la détection d’une image de me, sur un appareil Android et Windows 10 en mode bureau.

Le type et l’émotion API a une tâche parce que les valeurs retournées sont très proche de la vérité, bien que toujours approximatif. Il est intéressant de mentionner que la classe FaceEmotionDetection possède certaines propriétés de type double, telles que sourire, Beard et Moustache. Elles retournent des valeurs numériques, ce qui peuvent rendre pas beaucoup de sens pour l’utilisateur final dans une application réelle. Par conséquent, au cas où vous souhaitez convertir les valeurs numériques en chaînes explicites, vous pouvez envisager d’implémenter des convertisseurs de valeur et l’interface IValueConverter (bit.ly/2bZn01J).

L’implémentation de vérification de la connectivité réseau

Une application bien conçue qui doit accéder aux ressources sur Internet doit commencez toujours par vérifier pour la disponibilité de la connexion. Comme pour l’accès à la caméra et le système de fichiers, dans Xamarin.Forms vérifie la disponibilité de la connexion a besoin code spécifique à la plateforme. Heureusement, la connectivité plug-in est pour vous aider, offrant ainsi une méthode partagée pour effectuer cette vérification à partir du projet PCL directement. Le plug-in offre une classe appelée CrossConnectivity dont la propriété qui représente une instance singleton de la classe actuelle. Il expose une propriété bool appelée IsConnected renvoie simplement true si une connexion est disponible. Pour vérifier la disponibilité du réseau dans l’exemple d’application, placez simplement le code suivant après la déclaration de la méthode DetectFaceAndEmotionAsync :

private async Task<FaceEmotionDetection>
  DetectFaceAndEmotionsAsync(MediaFile inputFile)
{
  if(!CrossConnectivity.Current.IsConnected)
  {
    await DisplayAlert("Network error",
      "Please check your network connection and retry.", "OK");
    return null;
  }

La classe expose également les membres intéressants suivants :

  • ConnectivityChanged : Événement qui est déclenché lorsque l’état de connexion change. Vous pouvez vous abonner à cet événement et obtenir des informations sur l’état de la connectivité via un objet de type ConnectivityChangedEventArgs.
  • Bandes passantes : Une propriété qui retourne une liste des bandes passantes disponibles pour la plateforme actuelle.

Vous trouverez plus d’informations sur la connectivité plug-in à bit.ly/2bbU7wu.

Pour résumer

Microsoft Services cognitifs fournissent des services RESTful et des API riches basées sur l’apprentissage automatique qui vous permettre de créer la nouvelle génération d’applications. En combinant la puissance de ces services avec Xamarin, vous serez en mesure de mettre l’interaction utilisateur naturelle à vos applications interplateforme pour Android, iOS et Windows, offrant aux clients une expérience exceptionnelle.


Alessandro Del Sole est MVP Microsoft depuis 2008.  Promu MVP de l’année cinq fois, il est l’auteur de nombreux livres, livres, des vidéos et articles sur le développement .NET avec Visual Studio. DEL unique fonctionne comme un expert de développeur de solutions pour cerveau-Sys (cerveau-sys.it), la mise au point sur le développement .NET, formation et de Conseil. Vous pouvez le suivre sur Twitter : @progalex.

Merci aux experts techniques suivants d'avoir relu cet article : James McCaffrey et James Montemagno