HoloLens (1ère génération) et Azure 304 : Reconnaissance faciale


Notes

Les tutoriels Mixed Reality Academy ont été conçus pour les appareils HoloLens (1re génération) et les casques immersifs de réalité mixte. Nous estimons qu’il est important de laisser ces tutoriels à la disposition des développeurs qui recherchent encore des conseils pour développer des applications sur ces appareils. Notez que ces tutoriels ne sont pas mis à jour avec les derniers ensembles d’outils ou interactions utilisés pour HoloLens 2. Ils sont fournis dans le but de fonctionner sur les appareils pris en charge. Il y aura une nouvelle série de tutoriels qui seront publiés à l’avenir qui démontreront comment développer pour HoloLens 2. Cet avis sera mis à jour avec un lien vers ces tutoriels lorsqu’ils sont publiés.


outcome of completing this course

Dans ce cours, vous allez apprendre à ajouter des fonctionnalités de reconnaissance faciale à une application de réalité mixte, à l’aide d’Azure Cognitive Services, avec l’API Microsoft Face.

L’API Visage Azure est un service Microsoft, qui fournit aux développeurs les algorithmes de visage les plus avancés, tous dans le cloud. L’API Visage a deux fonctions principales : la détection des visages avec des attributs et la reconnaissance faciale. Cela permet aux développeurs de définir simplement un ensemble de groupes pour les visages, puis d’envoyer des images de requête au service plus tard, pour déterminer à qui appartient un visage. Pour plus d’informations, consultez la page Reconnaissance faciale Azure.

Après avoir terminé ce cours, vous aurez une application de réalité mixte HoloLens, qui sera en mesure d’effectuer les opérations suivantes :

  1. Utilisez un mouvement d’appui pour lancer la capture d’une image à l’aide de l’appareil photo HoloLens à bord.
  2. Envoyez l’image capturée au service d’API Visage Azure .
  3. Recevez les résultats de l’algorithme d’API Visage .
  4. Utilisez une interface utilisateur simple pour afficher le nom des personnes mises en correspondance.

Cela vous apprend à obtenir les résultats du service API Visage dans votre application de réalité mixte Basée sur Unity.

Dans votre application, il vous suffit de savoir comment intégrer les résultats à votre conception. Ce cours est conçu pour vous apprendre à intégrer un service Azure à votre Project Unity. Il s’agit de votre travail d’utiliser les connaissances que vous obtenez de ce cours pour améliorer votre application de réalité mixte.

Prise en charge des appareils

Cours HoloLens Casques immersifs
Réalité mixte - Azure - Cours 304 : Reconnaissance faciale ✔️ ✔️

Notes

Bien que ce cours se concentre principalement sur HoloLens, vous pouvez également appliquer ce que vous apprenez dans ce cours à Windows Mixed Reality casques immersifs (VR). Étant donné que les casques immersifs (VR) n’ont pas de caméras accessibles, vous aurez besoin d’une caméra externe connectée à votre PC. À mesure que vous suivez le cours, vous verrez des notes sur les modifications que vous devrez peut-être utiliser pour prendre en charge les casques immersifs (VR).

Prérequis

Notes

Ce didacticiel est conçu pour les développeurs qui ont une expérience de base avec Unity et C#. Sachez également que les prérequis et les instructions écrites de ce document représentent ce qui a été testé et vérifié au moment de l’écriture (mai 2018). Vous êtes libre d’utiliser le logiciel le plus récent, comme indiqué dans l’article d’installation des outils , mais il ne doit pas être supposé que les informations de ce cours correspondent parfaitement à ce que vous trouverez dans un logiciel plus récent que ce qui est répertorié ci-dessous.

Nous vous recommandons le matériel et le logiciel suivants pour ce cours :

Avant de commencer

  1. Pour éviter de rencontrer des problèmes de création de ce projet, il est fortement suggéré de créer le projet mentionné dans ce didacticiel dans un dossier racine ou proche (des chemins d’accès de dossier longs peuvent provoquer des problèmes au moment de la build).
  2. Configurez et testez votre HoloLens. Si vous avez besoin de support pour configurer votre HoloLens, veillez à consulter l’article de configuration HoloLens.
  3. Il est judicieux d’effectuer le réglage de l’étalonnage et du capteur lors du développement d’une nouvelle application HoloLens (parfois, il peut aider à effectuer ces tâches pour chaque utilisateur).

Pour obtenir de l’aide sur l’étalonnage, suivez ce lien vers l’article HoloLens Étalonnage.

Pour obtenir de l’aide sur le réglage du capteur, suivez ce lien vers l’article HoloLens Paramétrage du capteur.

Chapitre 1 - Portail Azure

Pour utiliser le service d’API Visage dans Azure, vous devez configurer une instance du service à rendre disponible pour votre application.

  1. Tout d’abord, connectez-vous au portail Azure.

    Notes

    Si vous n’avez pas encore de compte Azure, vous devez en créer un. Si vous suivez ce tutoriel dans une situation de salle de classe ou de laboratoire, demandez à votre instructeur ou à l’un des spécialistes de l’aide pour configurer votre nouveau compte.

  2. Une fois connecté, cliquez sur Nouveau dans le coin supérieur gauche, puis recherchez l’API Visage, appuyez sur Entrée.

    search for face api

    Notes

    Le mot Nouveau peut avoir été remplacé par Créer une ressource, dans des portails plus récents.

  3. La nouvelle page fournit une description du service API Visage . En bas à gauche de cette invite, sélectionnez le bouton Créer pour créer une association avec ce service.

    face api information

  4. Une fois que vous avez cliqué sur Créer :

    1. Insérez votre nom souhaité pour cette instance de service.

    2. Sélectionnez un abonnement.

    3. Sélectionnez le niveau tarifaire approprié pour vous, si c’est la première fois que vous créez un service d’API Visage, un niveau gratuit (nommé F0) doit être disponible pour vous.

    4. Choisissez un groupe de ressources ou créez-en un. Un groupe de ressources permet de surveiller, de contrôler l’accès, de provisionner et de gérer la facturation pour une collection de ressources Azure. Il est recommandé de conserver tous les services Azure associés à un seul projet (par exemple, ces laboratoires) sous un groupe de ressources commun.

      Si vous souhaitez en savoir plus sur les groupes de ressources Azure, consultez l’article du groupe de ressources.

    5. L’application UWP, Person Maker, que vous utilisez ultérieurement, nécessite l’utilisation de « USA Ouest » pour l’emplacement.

    6. Vous devrez également confirmer que vous avez compris les conditions générales appliquées à ce service.

    7. Sélectionnez Créer.*

      create face api service

  5. Une fois que vous avez cliqué sur Créer,* vous devrez attendre que le service soit créé, cela peut prendre une minute.

  6. Une notification s’affiche dans le portail une fois l’instance de service créée.

    service creation notification

  7. Cliquez sur les notifications pour explorer votre nouvelle instance de service.

    go to resource notification

  8. Lorsque vous êtes prêt, cliquez sur Bouton Accéder à la ressource dans la notification pour explorer votre nouvelle instance de service.

    access face api keys

  9. Dans ce tutoriel, votre application doit effectuer des appels à votre service, ce qui est effectué à l’aide de la « clé » de votre service. À partir de la page de démarrage rapide , de votre service API Visage , le premier point est le numéro 1 pour récupérer vos clés.

  10. Dans la page Service , sélectionnez le lien hypertexte des clés bleues (si dans la page de démarrage rapide) ou le lien Clés dans le menu de navigation des services (à gauche, indiqué par l’icône « clé »), pour révéler vos clés.

    Notes

    Notez l’une des clés et protégez-la, car vous en aurez besoin plus tard.

Chapitre 2 - Utilisation de l’application UWP « Person Maker »

Veillez à télécharger l’application UWP prédéfinie appelée Person Maker. Cette application n’est pas le produit final de ce cours, mais simplement un outil pour vous aider à créer vos entrées Azure, dont le projet ultérieur s’appuiera.

Person Maker vous permet de créer des entrées Azure, associées à des personnes et à des groupes de personnes. L’application place toutes les informations nécessaires dans un format qui peut ensuite être utilisé par FaceAPI, afin de reconnaître les visages des personnes que vous avez ajoutées.

[IMPORTANT] Person Maker utilise une limitation de base pour vous assurer que vous ne dépassez pas le nombre d’appels de service par minute pour le niveau d’abonnement gratuit. Le texte vert en haut passe en rouge et à mettre à jour en tant que « ACTIVE » lorsque la limitation se produit ; s’il s’agit du cas, attendez simplement l’application (elle attendra qu’elle puisse continuer à accéder au service visage, mise à jour en tant que « IN-ACTIVE » lorsque vous pouvez l’utiliser à nouveau).

Cette application utilise les bibliothèques Microsoft.ProjectOxford.Face , ce qui vous permettra d’utiliser pleinement l’API Visage. Cette bibliothèque est disponible gratuitement en tant que package NuGet. Pour plus d’informations sur ce problème et les API similaires, veillez à consulter l’article de référence sur les API.

Notes

Il s’agit simplement des étapes requises, des instructions pour savoir comment effectuer ces opérations sont plus loin dans le document. L’application Person Maker vous permettra de :

  • Créez un groupe de personnes, qui est un groupe composé de plusieurs personnes que vous souhaitez associer. Avec votre compte Azure, vous pouvez héberger plusieurs groupes de personnes.

  • Créez une personne, qui est membre d’un groupe de personnes. Chaque personne dispose d’un certain nombre d’images Visage associées.

  • Affectez des images de visage à une personne pour permettre à votre service d’API Visage Azure de reconnaître une personne par le visage correspondant.

  • Entraîner votre service d’API Visage Azure.

Sachez que pour entraîner cette application pour reconnaître les personnes, vous aurez besoin de dix (10) photos de close-up de chaque personne que vous souhaitez ajouter à votre groupe de personnes. L’application cam Windows 10 peut vous aider à les prendre. Vous devez vous assurer que chaque photo est claire (évitez de flouter, d’obscurcir ou d’être trop loin, du sujet), disposez de la photo au format de fichier jpg ou png, avec la taille du fichier image n’étant pas supérieure à 4 Mo, et pas moins de 1 Ko.

Notes

Si vous suivez ce tutoriel, n’utilisez pas votre propre visage pour l’entraînement, comme lorsque vous placez le HoloLens sur, vous ne pouvez pas vous regarder vous-même. Utilisez le visage d’un collègue ou d’un étudiant.

Exécution de Person Maker :

  1. Ouvrez le dossier PersonMaker et double-cliquez sur la solution PersonMaker pour l’ouvrir avec Visual Studio.

  2. Une fois la solution PersonMaker ouverte, assurez-vous que :

    1. La configuration de la solution est définie sur Débogage.

    2. La plateforme de solutions est définie sur x86

    3. La plateforme cible est une machine locale.

    4. Vous devrez peut-être également restaurer NuGet packages (cliquez avec le bouton droit sur la solution, puis sélectionnez Restaurer NuGet packages).

  3. Cliquez sur Ordinateur local et l’application démarre. N’oubliez pas que, sur les écrans plus petits, tout le contenu peut ne pas être visible, bien que vous puissiez faire défiler plus loin vers le bas pour l’afficher.

    person maker user interface

  4. Insérez votre clé d’authentification Azure, dont vous devez disposer, à partir de votre service d’API Visage dans Azure.

  5. Insérer :

    1. ID que vous souhaitez affecter au groupe de personnes. L’ID doit être en minuscules, sans espaces. Notez cet ID, car il sera nécessaire ultérieurement dans votre projet Unity.
    2. Nom que vous souhaitez affecter au groupe de personnes (peut avoir des espaces).
  6. Appuyez sur le bouton Créer un groupe de personnes . Un message de confirmation doit apparaître sous le bouton.

Notes

Si vous avez une erreur « Accès refusé », vérifiez l’emplacement défini pour votre service Azure. Comme indiqué ci-dessus, cette application est conçue pour « USA Ouest ».

Important

Vous remarquerez que vous pouvez également cliquer sur le bouton Récupérer un groupe connu : c’est pour cela que vous avez déjà créé un groupe de personnes et que vous souhaitez l’utiliser, plutôt que de le créer. N’oubliez pas que si vous cliquez sur Créer un groupe de personnes avec un groupe connu, cela récupère également un groupe.

  1. Insérez le nom de la personne que vous souhaitez créer.

    1. Cliquez sur le bouton Créer une personne .

    2. Un message de confirmation doit apparaître sous le bouton.

    3. Si vous souhaitez supprimer une personne que vous avez créée précédemment, vous pouvez écrire le nom dans la zone de texte et appuyer sur Supprimer la personne

  2. Assurez-vous que vous connaissez l’emplacement de dix (10) photos de la personne que vous souhaitez ajouter à votre groupe.

  3. Appuyez sur Créer et ouvrir le dossier pour ouvrir Windows Explorateur vers le dossier associé à la personne. Ajoutez les dix images (10) dans le dossier. Il doit s’agir du format de fichier JPG ou PNG .

  4. Cliquez sur Envoyer à Azure. Un compteur affiche l’état de la soumission, suivi d’un message lorsqu’il est terminé.

  5. Une fois le compteur terminé et qu’un message de confirmation a été affiché, cliquez sur Train pour entraîner votre service.

Une fois le processus terminé, vous êtes prêt à passer à Unity.

Chapitre 3 - Configurer le projet Unity

Voici une configuration classique pour le développement avec la réalité mixte, et par conséquent, est un bon modèle pour d’autres projets.

  1. Ouvrez Unity , puis cliquez sur Nouveau.

    Start new Unity project.

  2. Vous devez maintenant fournir un nom de Project Unity. Insérez MR_FaceRecognition. Vérifiez que le type de projet est défini sur 3D. Définissez l’emplacement sur un emplacement approprié pour vous (n’oubliez pas que les répertoires racines sont meilleurs). Ensuite, cliquez sur Créer un projet.

    Provide details for new Unity project.

  3. Avec Unity ouvert, il vaut la peine de vérifier que l’éditeur de script par défaut est défini sur Visual Studio. Accédez à Modifier > les préférences , puis à partir de la nouvelle fenêtre, accédez aux outils externes. Modifiez l’éditeur de script externeen Visual Studio 2017. Fermez la fenêtre Préférences .

    Update script editor preference.

  4. Ensuite, accédez à La génération de fichiers > Paramètres et basculez la plateforme vers plateforme Windows universelle, en cliquant sur le bouton Basculer la plateforme.

    Build Settings window, switch platform to UWP.

  5. Accédez à La build de fichiers > Paramètres et assurez-vous que :

    1. L’appareil cible est défini sur HoloLens

      Pour les casques immersifs, définissez l’appareil cible sur n’importe quel appareil.

    2. Le type de build est défini sur D3D

    3. Le Kit de développement logiciel (SDK) est défini sur La dernière version installée

    4. Visual Studio version est définie sur La dernière version installée

    5. La génération et l’exécution sont définies sur ordinateur local

    6. Enregistrez la scène et ajoutez-la à la build.

      1. Pour ce faire, sélectionnez Ajouter des scènes d’ouverture. Une fenêtre d’enregistrement s’affiche.

        Click add open scenes button

      2. Sélectionnez le bouton Nouveau dossier pour créer un dossier, nommez-le Scène.

        Create new scripts folder

      3. Ouvrez votre dossier Scènes nouvellement créé, puis dans le nom du fichier : champ de texte, tapez FaceRecScene, puis appuyez sur Enregistrer.

        Give new scene a name.

    7. Les paramètres restants, dans Build Paramètres, doivent être laissés comme valeur par défaut pour l’instant.

  6. Dans la fenêtre Build Paramètres, cliquez sur le bouton Lecteur Paramètres, ce qui ouvre le panneau associé dans l’espace où se trouve l’Inspecteur.

    Open player settings.

  7. Dans ce panneau, quelques paramètres doivent être vérifiés :

    1. Sous l’onglet Autres Paramètres :

      1. La version de ScriptingRuntime doit être expérimentale (équivalent.NET 4.6). La modification de ce paramètre déclenche une nécessité de redémarrer l’éditeur.

      2. Le serveur principal de script doit être .NET

      3. Le niveau de compatibilité de l’API doit être .NET 4.6

        Update other settings.

    2. Sous l’onglet Publication Paramètres, sous Fonctionnalités, cochez :

      • InternetClient

      • Webcam

        Updating publishing settings.

    3. Plus loin dans le panneau, dans XR Paramètres (trouvé ci-dessous Publier Paramètres), cochez Virtual Reality Pris en charge, vérifiez que le Kit de développement logiciel (SDK) Windows Mixed Reality est ajouté.

      Update the X R Settings.

  8. De retour dans Build Paramètres, Unity C# Projects n’est plus grisé ; cochez la case en regard de cela.

  9. Fermez la fenêtre Build Settings.

  10. Enregistrez votre scène et Project (>FILE SAVE SCENE / FILE > SAVE PROJECT).

Chapitre 4 - Configuration de la caméra principale

Important

Si vous souhaitez ignorer le composant De configuration Unity de ce cours et continuer directement dans le code, n’hésitez pas à télécharger ce .unitypackage et à l’importer dans votre projet en tant que package personnalisé. N’oubliez pas que ce package inclut également l’importation de la DLL Newtonsoft, couverte dans le chapitre 5. Avec cette importation, vous pouvez continuer à partir du chapitre 6.

  1. Dans le panneau Hiérarchie , sélectionnez l’appareil photo principal.

  2. Une fois sélectionné, vous pourrez voir tous les composants de la caméra principale dans le panneau Inspecteur.

    1. L’objet Camera doit être nommé Main Camera (notez l’orthographe !)

    2. La balise Main Camera doit être définie sur MainCamera (notez l’orthographe !)

    3. Vérifiez que la position de transformation est définie sur 0, 0, 0

    4. Définir des indicateurs d’effacement sur couleur unie

    5. Définissez la couleur d’arrière-plan du composant caméra sur Noir, Alpha 0 (Code hexadécimal : #00000000000)

      set up camera components

Chapitre 5 : Importer la bibliothèque Newtonsoft.Json

Important

Si vous avez importé le « .unitypackage » dans le dernier chapitre, vous pouvez ignorer ce chapitre.

Pour vous aider à désérialiser et sérialiser des objets reçus et envoyés au Bot Service vous devez télécharger la bibliothèque Newtonsoft.Json. Vous trouverez une version compatible déjà organisée avec la structure de dossiers Unity correcte dans ce fichier de package Unity.

Pour importer la bibliothèque :

  1. Téléchargez le package Unity.

  2. Cliquez sur Ressources, Importer un package, un package personnalisé.

    Import Newtonsoft.Json

  3. Recherchez le package Unity que vous avez téléchargé, puis cliquez sur Ouvrir.

  4. Vérifiez que tous les composants du package sont cochés et cliquez sur Importer.

    Import the Newtonsoft.Json assets

Chapitre 6 - Créer la classe FaceAnalysis

L’objectif de la classe FaceAnalysis est d’héberger les méthodes nécessaires pour communiquer avec votre service Azure Face Recognition.

  • Une fois que le service a envoyé une image de capture, il l’analyse et identifie les visages au sein d’une personne connue et détermine si un élément appartient à une personne connue.
  • Si une personne connue est trouvée, cette classe affiche son nom en tant que texte d’interface utilisateur dans la scène.

Pour créer la classe FaceAnalysis :

  1. Cliquez avec le bouton droit dans le dossier Ressources situé dans le volet Project, puis cliquez sur CreateFolder>. Appelez les scripts du dossier.

    Create the FaceAnalysis class.

  2. Double-cliquez sur le dossier créé, pour l’ouvrir.

  3. Cliquez avec le bouton droit dans le dossier, puis cliquez sur CreateC># Script. Appelez le script FaceAnalysis.

  4. Double-cliquez sur le nouveau script FaceAnalysis pour l’ouvrir avec Visual Studio 2017.

  5. Entrez les espaces de noms suivants au-dessus de la classe FaceAnalysis :

        using Newtonsoft.Json;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using System.Text;
        using UnityEngine;
        using UnityEngine.Networking;
    
  6. Vous devez maintenant ajouter tous les objets utilisés pour désérialiser. Ces objets doivent être ajoutés en dehors du script FaceAnalysis (sous le crochet inférieur).

        /// <summary>
        /// The Person Group object
        /// </summary>
        public class Group_RootObject
        {
            public string personGroupId { get; set; }
            public string name { get; set; }
            public object userData { get; set; }
        }
    
        /// <summary>
        /// The Person Face object
        /// </summary>
        public class Face_RootObject
        {
            public string faceId { get; set; }
        }
    
        /// <summary>
        /// Collection of faces that needs to be identified
        /// </summary>
        public class FacesToIdentify_RootObject
        {
            public string personGroupId { get; set; }
            public List<string> faceIds { get; set; }
            public int maxNumOfCandidatesReturned { get; set; }
            public double confidenceThreshold { get; set; }
        }
    
        /// <summary>
        /// Collection of Candidates for the face
        /// </summary>
        public class Candidate_RootObject
        {
            public string faceId { get; set; }
            public List<Candidate> candidates { get; set; }
        }
    
        public class Candidate
        {
            public string personId { get; set; }
            public double confidence { get; set; }
        }
    
        /// <summary>
        /// Name and Id of the identified Person
        /// </summary>
        public class IdentifiedPerson_RootObject
        {
            public string personId { get; set; }
            public string name { get; set; }
        }
    
  7. Les méthodes Start() et Update() ne seront pas utilisées. Par conséquent, supprimez-les maintenant.

  8. Dans la classe FaceAnalysis , ajoutez les variables suivantes :

        /// <summary>
        /// Allows this class to behave like a singleton
        /// </summary>
        public static FaceAnalysis Instance;
    
        /// <summary>
        /// The analysis result text
        /// </summary>
        private TextMesh labelText;
    
        /// <summary>
        /// Bytes of the image captured with camera
        /// </summary>
        internal byte[] imageBytes;
    
        /// <summary>
        /// Path of the image captured with camera
        /// </summary>
        internal string imagePath;
    
        /// <summary>
        /// Base endpoint of Face Recognition Service
        /// </summary>
        const string baseEndpoint = "https://westus.api.cognitive.microsoft.com/face/v1.0/";
    
        /// <summary>
        /// Auth key of Face Recognition Service
        /// </summary>
        private const string key = "- Insert your key here -";
    
        /// <summary>
        /// Id (name) of the created person group 
        /// </summary>
        private const string personGroupId = "- Insert your group Id here -";
    

    Notes

    Remplacez la clé et personGroupId par votre clé de service et l’ID du groupe que vous avez créé précédemment.

  9. Ajoutez la méthode Awake(), qui initialise la classe, en ajoutant la classe ImageCapture à la caméra principale et appelle la méthode de création Label :

        /// <summary>
        /// Initialises this class
        /// </summary>
        private void Awake()
        {
            // Allows this instance to behave like a singleton
            Instance = this;
    
            // Add the ImageCapture Class to this Game Object
            gameObject.AddComponent<ImageCapture>();
    
            // Create the text label in the scene
            CreateLabel();
        }
    
  10. Ajoutez la méthode CreateLabel(), qui crée l’objet Label pour afficher le résultat d’analyse :

        /// <summary>
        /// Spawns cursor for the Main Camera
        /// </summary>
        private void CreateLabel()
        {
            // Create a sphere as new cursor
            GameObject newLabel = new GameObject();
    
            // Attach the label to the Main Camera
            newLabel.transform.parent = gameObject.transform;
    
            // Resize and position the new cursor
            newLabel.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
            newLabel.transform.position = new Vector3(0f, 3f, 60f);
    
            // Creating the text of the Label
            labelText = newLabel.AddComponent<TextMesh>();
            labelText.anchor = TextAnchor.MiddleCenter;
            labelText.alignment = TextAlignment.Center;
            labelText.tabSize = 4;
            labelText.fontSize = 50;
            labelText.text = ".";       
        }
    
  11. Ajoutez la méthode DetectFacesFromImage() et GetImageAsByteArray(). L’ancien demande au service reconnaissance faciale de détecter tout visage possible dans l’image envoyée, tandis que celui-ci est nécessaire pour convertir l’image capturée en tableau d’octets :

        /// <summary>
        /// Detect faces from a submitted image
        /// </summary>
        internal IEnumerator DetectFacesFromImage()
        {
            WWWForm webForm = new WWWForm();
            string detectFacesEndpoint = $"{baseEndpoint}detect";
    
            // Change the image into a bytes array
            imageBytes = GetImageAsByteArray(imagePath);
    
            using (UnityWebRequest www = 
                UnityWebRequest.Post(detectFacesEndpoint, webForm))
            {
                www.SetRequestHeader("Ocp-Apim-Subscription-Key", key);
                www.SetRequestHeader("Content-Type", "application/octet-stream");
                www.uploadHandler.contentType = "application/octet-stream";
                www.uploadHandler = new UploadHandlerRaw(imageBytes);
                www.downloadHandler = new DownloadHandlerBuffer();
    
                yield return www.SendWebRequest();
                string jsonResponse = www.downloadHandler.text;
                Face_RootObject[] face_RootObject = 
                    JsonConvert.DeserializeObject<Face_RootObject[]>(jsonResponse);
    
                List<string> facesIdList = new List<string>();
                // Create a list with the face Ids of faces detected in image
                foreach (Face_RootObject faceRO in face_RootObject)
                {
                    facesIdList.Add(faceRO.faceId);
                    Debug.Log($"Detected face - Id: {faceRO.faceId}");
                }
    
                StartCoroutine(IdentifyFaces(facesIdList));
            }
        }
    
        /// <summary>
        /// Returns the contents of the specified file as a byte array.
        /// </summary>
        static byte[] GetImageAsByteArray(string imageFilePath)
        {
            FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream);
            return binaryReader.ReadBytes((int)fileStream.Length);
        }
    
  12. Ajoutez la méthode IdentifierFaces(), qui demande au service reconnaissance faciale d’identifier tout visage connu précédemment détecté dans l’image envoyée. La demande retourne un ID de la personne identifiée, mais pas le nom :

        /// <summary>
        /// Identify the faces found in the image within the person group
        /// </summary>
        internal IEnumerator IdentifyFaces(List<string> listOfFacesIdToIdentify)
        {
            // Create the object hosting the faces to identify
            FacesToIdentify_RootObject facesToIdentify = new FacesToIdentify_RootObject();
            facesToIdentify.faceIds = new List<string>();
            facesToIdentify.personGroupId = personGroupId;
            foreach (string facesId in listOfFacesIdToIdentify)
            {
                facesToIdentify.faceIds.Add(facesId);
            }
            facesToIdentify.maxNumOfCandidatesReturned = 1;
            facesToIdentify.confidenceThreshold = 0.5;
    
            // Serialize to Json format
            string facesToIdentifyJson = JsonConvert.SerializeObject(facesToIdentify);
            // Change the object into a bytes array
            byte[] facesData = Encoding.UTF8.GetBytes(facesToIdentifyJson);
    
            WWWForm webForm = new WWWForm();
            string detectFacesEndpoint = $"{baseEndpoint}identify";
    
            using (UnityWebRequest www = UnityWebRequest.Post(detectFacesEndpoint, webForm))
            {
                www.SetRequestHeader("Ocp-Apim-Subscription-Key", key);
                www.SetRequestHeader("Content-Type", "application/json");
                www.uploadHandler.contentType = "application/json";
                www.uploadHandler = new UploadHandlerRaw(facesData);
                www.downloadHandler = new DownloadHandlerBuffer();
    
                yield return www.SendWebRequest();
                string jsonResponse = www.downloadHandler.text;
                Debug.Log($"Get Person - jsonResponse: {jsonResponse}");
                Candidate_RootObject [] candidate_RootObject = JsonConvert.DeserializeObject<Candidate_RootObject[]>(jsonResponse);
    
                // For each face to identify that ahs been submitted, display its candidate
                foreach (Candidate_RootObject candidateRO in candidate_RootObject)
                {
                    StartCoroutine(GetPerson(candidateRO.candidates[0].personId));
    
                    // Delay the next "GetPerson" call, so all faces candidate are displayed properly
                    yield return new WaitForSeconds(3);
                }           
            }
        }
    
  13. Ajoutez la méthode GetPerson(). En fournissant l’ID de la personne, cette méthode demande ensuite au service reconnaissance faciale de retourner le nom de la personne identifiée :

        /// <summary>
        /// Provided a personId, retrieve the person name associated with it
        /// </summary>
        internal IEnumerator GetPerson(string personId)
        {
            string getGroupEndpoint = $"{baseEndpoint}persongroups/{personGroupId}/persons/{personId}?";
            WWWForm webForm = new WWWForm();
    
            using (UnityWebRequest www = UnityWebRequest.Get(getGroupEndpoint))
            {
                www.SetRequestHeader("Ocp-Apim-Subscription-Key", key);
                www.downloadHandler = new DownloadHandlerBuffer();
                yield return www.SendWebRequest();
                string jsonResponse = www.downloadHandler.text;
    
                Debug.Log($"Get Person - jsonResponse: {jsonResponse}");
                IdentifiedPerson_RootObject identifiedPerson_RootObject = JsonConvert.DeserializeObject<IdentifiedPerson_RootObject>(jsonResponse);
    
                // Display the name of the person in the UI
                labelText.text = identifiedPerson_RootObject.name;
            }
        }
    
  14. N’oubliez pas d’enregistrer les modifications avant de revenir à l’éditeur Unity.

  15. Dans l’Éditeur Unity, faites glisser le script FaceAnalysis du dossier Scripts dans Project panneau vers l’objet Appareil photo principal dans le panneau Hiérarchie. Le nouveau composant de script sera donc ajouté à la caméra principale.

Place FaceAnalysis onto the Main Camera

Chapitre 7 - Créer la classe ImageCapture

L’objectif de la classe ImageCapture est d’héberger les méthodes nécessaires pour communiquer avec votre service Azure Face Recognition pour analyser l’image que vous capturerez, identifier les visages dans celui-ci et déterminer s’il appartient à une personne connue. Si une personne connue est trouvée, cette classe affiche son nom en tant que texte d’interface utilisateur dans la scène.

Pour créer la classe ImageCapture :

  1. Cliquez avec le bouton droit dans le dossier Scripts que vous avez créé précédemment, puis cliquez sur Créer, script C#. Appelez le script ImageCapture.

  2. Double-cliquez sur le nouveau script ImageCapture pour l’ouvrir avec Visual Studio 2017.

  3. Entrez les espaces de noms suivants au-dessus de la classe ImageCapture :

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  4. Dans la classe ImageCapture , ajoutez les variables suivantes :

        /// <summary>
        /// Allows this class to behave like a singleton
        /// </summary>
        public static ImageCapture instance;
    
        /// <summary>
        /// Keeps track of tapCounts to name the captured images 
        /// </summary>
        private int tapsCount;
    
        /// <summary>
        /// PhotoCapture object used to capture images on HoloLens 
        /// </summary>
        private PhotoCapture photoCaptureObject = null;
    
        /// <summary>
        /// HoloLens class to capture user gestures
        /// </summary>
        private GestureRecognizer recognizer;
    
  5. Ajoutez les méthodes Awake() et Start() nécessaires pour initialiser la classe et autoriser les HoloLens à capturer les mouvements de l’utilisateur :

        /// <summary>
        /// Initialises this class
        /// </summary>
        private void Awake()
        {
            instance = this;
        }
    
        /// <summary>
        /// Called right after Awake
        /// </summary>
        void Start()
        {
            // Initialises user gestures capture 
            recognizer = new GestureRecognizer();
            recognizer.SetRecognizableGestures(GestureSettings.Tap);
            recognizer.Tapped += TapHandler;
            recognizer.StartCapturingGestures();
        }
    
  6. Ajoutez le TapHandler() qui est appelé lorsque l’utilisateur effectue un mouvement Tap :

        /// <summary>
        /// Respond to Tap Input.
        /// </summary>
        private void TapHandler(TappedEventArgs obj)
        {
            tapsCount++;
            ExecuteImageCaptureAndAnalysis();
        }
    
  7. Ajoutez la méthode ExecuteImageCaptureAndAnalysis(), qui démarre le processus de capture d’image :

        /// <summary>
        /// Begin process of Image Capturing and send To Azure Computer Vision service.
        /// </summary>
        private void ExecuteImageCaptureAndAnalysis()
        {
            Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending
                ((res) => res.width * res.height).First();
            Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
    
            PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
            {
                photoCaptureObject = captureObject;
    
                CameraParameters c = new CameraParameters();
                c.hologramOpacity = 0.0f;
                c.cameraResolutionWidth = targetTexture.width;
                c.cameraResolutionHeight = targetTexture.height;
                c.pixelFormat = CapturePixelFormat.BGRA32;
    
                captureObject.StartPhotoModeAsync(c, delegate (PhotoCapture.PhotoCaptureResult result)
                {
                    string filename = string.Format(@"CapturedImage{0}.jpg", tapsCount);
                    string filePath = Path.Combine(Application.persistentDataPath, filename);
    
                    // Set the image path on the FaceAnalysis class
                    FaceAnalysis.Instance.imagePath = filePath;
    
                    photoCaptureObject.TakePhotoAsync
                    (filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
                });
            });
        }
    
  8. Ajoutez les gestionnaires appelés lorsque le processus de capture photo a été terminé :

        /// <summary>
        /// Called right after the photo capture process has concluded
        /// </summary>
        void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
        {
            photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
        }
    
        /// <summary>
        /// Register the full execution of the Photo Capture. If successful, it will begin the Image Analysis process.
        /// </summary>
        void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
        {
            photoCaptureObject.Dispose();
            photoCaptureObject = null;
    
            // Request image caputer analysis
            StartCoroutine(FaceAnalysis.Instance.DetectFacesFromImage());
        }
    
  9. N’oubliez pas d’enregistrer les modifications avant de revenir à l’éditeur Unity.

Chapitre 8 - Création de la solution

Pour effectuer un test approfondi de votre application, vous devez le charger sur votre HoloLens.

Avant de procéder, assurez-vous que :

  • Tous les paramètres mentionnés dans le chapitre 3 sont correctement définis.
  • Le script FaceAnalysis est attaché à l’objet Main Camera.
  • La clé d’authentification et l’ID de groupe ont été définies dans le script FaceAnalysis.

Ce point vous êtes prêt à générer la solution. Une fois la solution générée, vous serez prêt à déployer votre application.

Pour commencer le processus de génération :

  1. Enregistrez la scène actuelle en cliquant sur Fichier, Enregistrer.

  2. Accédez à Fichier, Générer Paramètres, cliquez sur Ajouter des scènes d’ouverture.

  3. Veillez à cocher Les projets Unity C#.

    Deploy the Visual Studio solution

  4. Appuyez sur Build. Dans ce cas, Unity lance une fenêtre Explorateur de fichiers, où vous devez créer, puis sélectionner un dossier dans lequel générer l’application. Créez ce dossier maintenant, dans le projet Unity, puis appelez-le à l’application. Ensuite, avec le dossier d’application sélectionné, appuyez sur Sélectionner un dossier.

  5. Unity commence à créer votre projet dans le dossier Application.

  6. Une fois que Unity a terminé la génération (cela peut prendre un certain temps), elle ouvre une fenêtre de Explorateur de fichiers à l’emplacement de votre build.

    Deploy the solution from Visual Studio

  7. Ouvrez votre dossier Application, puis ouvrez la nouvelle solution Project (comme indiqué ci-dessus, MR_FaceRecognition.sln).

Chapitre 9 - Déploiement de votre application

Pour déployer sur HoloLens :

  1. Vous aurez besoin de l’adresse IP de votre HoloLens (pour le déploiement à distance) et de vous assurer que votre HoloLens est en mode développeur. Pour ce faire :

    1. Tout en portant votre HoloLens, ouvrez le Paramètres.
    2. Accédez à Network & Internet > Wi-Fi > Options avancées
    3. Notez l’adresse IPv4 .
    4. Ensuite, revenez à Paramètres, puis à Mettre à jour & la sécurité > pour les développeurs
    5. Définissez le mode développeur activé.
  2. Accédez à votre nouvelle build Unity (dossier d’application) et ouvrez le fichier solution avec Visual Studio.

  3. Dans la configuration de la solution, sélectionnez Déboguer.

  4. Dans la plateforme de solution, sélectionnez x86, Ordinateur distant.

    Change the solution configuration

  5. Accédez au menu Générer, puis cliquez sur Déployer la solution pour charger une version test de l’application sur votre HoloLens.

  6. Votre application doit maintenant apparaître dans la liste des applications installées sur votre HoloLens, prêtes à être lancées !

Notes

Pour effectuer un déploiement sur un casque immersif, définissez la plateforme de solution sur Ordinateur local et définissez la configuration sur Déboguer, avec x86 comme plateforme. Ensuite, déployez sur l’ordinateur local, à l’aide du menu Générer, en sélectionnant Déployer la solution.

Chapitre 10 - Utilisation de l’application

  1. Porter le HoloLens, lancer l’application.

  2. Examinez la personne que vous avez inscrite auprès de l’API Visage. Vérifiez que :

    • Le visage de la personne n’est pas trop distant et clairement visible
    • L’éclairage de l’environnement n’est pas trop sombre
  3. Utilisez le mouvement d’appui pour capturer l’image de la personne.

  4. Attendez que l’application envoie la demande d’analyse et reçoive une réponse.

  5. Si la personne a été reconnue avec succès, le nom de la personne apparaît sous forme de texte de l’interface utilisateur.

  6. Vous pouvez répéter le processus de capture à l’aide du mouvement d’appui toutes les quelques secondes.

Votre application API Visage Azure terminée

Félicitations, vous avez créé une application de réalité mixte qui tire parti du service Reconnaissance faciale Azure pour détecter les visages au sein d’une image et identifier les visages connus.

outcome of completing this course

Exercices bonus

Exercice 1

L’API Visage Azure est suffisamment puissante pour détecter jusqu’à 64 visages dans une seule image. Étendez l’application pour qu’elle puisse reconnaître deux ou trois visages, parmi de nombreuses autres personnes.

Exercice 2

L’API Visage Azure est également en mesure de fournir toutes sortes d’informations d’attribut. Intégrez-le à l’application. Cela pourrait être encore plus intéressant, lorsqu’il est associé à l’API Émotion.