Partilhar via


HoloLens (1.ª geração) e Azure 304: Reconhecimento facial


Nota

Os tutoriais da Academia de Realidade Mista foram projetados com HoloLens (1ª geração) e Headsets Imersivos de Realidade Mista em mente. Como tal, sentimos que é importante deixar estes tutoriais no lugar para desenvolvedores que ainda estão procurando orientação no desenvolvimento para esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas ou interações mais recentes que estão sendo usados para o HoloLens 2. Eles serão mantidos para continuar trabalhando nos dispositivos suportados. Haverá uma nova série de tutoriais que serão publicados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem publicados.


Resultado da conclusão deste curso

Neste curso, você aprenderá como adicionar recursos de reconhecimento facial a um aplicativo de realidade mista, usando os Serviços Cognitivos do Azure, com a API do Microsoft Face.

A API do Azure Face é um serviço da Microsoft que fornece aos programadores os algoritmos faciais mais avançados, tudo na nuvem. A API Face tem duas funções principais: deteção de rosto com atributos e reconhecimento facial. Isso permite que os desenvolvedores simplesmente definam um conjunto de grupos para rostos e, em seguida, enviem imagens de consulta para o serviço mais tarde, para determinar a quem um rosto pertence. Para obter mais informações, visite a página Reconhecimento Facial do Azure.

Tendo concluído este curso, você terá um aplicativo HoloLens de realidade mista, que será capaz de fazer o seguinte:

  1. Use um gesto de toque para iniciar a captura de uma imagem usando a câmera HoloLens integrada.
  2. Envie a imagem capturada para o serviço de API do Azure Face.
  3. Receba os resultados do algoritmo da API do Face.
  4. Use uma interface de usuário simples, para exibir o nome das pessoas correspondentes.

Isso ensinará como obter os resultados do Face API Service em seu aplicativo de realidade mista baseado em Unity.

Na sua aplicação, cabe-lhe a si decidir como irá integrar os resultados com o seu design. Este curso foi criado para ensiná-lo a integrar um Serviço do Azure ao seu Projeto Unity. É seu trabalho usar o conhecimento que você ganha com este curso para melhorar sua aplicação de realidade mista.

Suporte de dispositivos

Curso HoloLens Auriculares imersivos
MR e Azure 304: Reconhecimento facial ✔️ ✔️

Nota

Embora este curso se concentre principalmente no HoloLens, você também pode aplicar o que aprendeu neste curso aos fones de ouvido imersivos (VR) do Windows Mixed Reality. Como os fones de ouvido imersivos (VR) não têm câmeras acessíveis, você precisará de uma câmera externa conectada ao seu PC. Ao acompanhar o curso, você verá anotações sobre quaisquer alterações que talvez precise empregar para suportar fones de ouvido imersivos (VR).

Pré-requisitos

Nota

Este tutorial foi projetado para desenvolvedores que têm experiência básica com Unity e C#. Por favor, esteja ciente de que os pré-requisitos e instruções escritas neste documento representam o que foi testado e verificado no momento da redação (maio de 2018). Você é livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não se deva presumir que as informações neste curso corresponderão perfeitamente ao que você encontrará em software mais recente do que o listado abaixo.

Recomendamos o seguinte hardware e software para este curso:

Antes de começar

  1. Para evitar encontrar problemas ao criar este projeto, é altamente recomendável que você crie o projeto mencionado neste tutorial em uma pasta raiz ou quase raiz (caminhos de pasta longos podem causar problemas em tempo de compilação).
  2. Configure e teste o seu HoloLens. Se você precisar de suporte para configurar seu HoloLens, visite o artigo de configuração do HoloLens.
  3. É uma boa ideia executar a calibração e o ajuste do sensor ao começar a desenvolver um novo aplicativo HoloLens (às vezes, pode ajudar a executar essas tarefas para cada usuário).

Para obter ajuda sobre calibração, siga este link para o artigo Calibração HoloLens.

Para obter ajuda sobre o ajuste do sensor, siga este link para o artigo HoloLens Sensor Tuning.

Capítulo 1 - O Portal do Azure

Para usar o serviço de API do Face no Azure, você precisará configurar uma instância do serviço a ser disponibilizada para seu aplicativo.

  1. Primeiro, faça logon no Portal do Azure.

    Nota

    Se ainda não tiver uma conta do Azure, terá de criar uma. Se você estiver seguindo este tutorial em uma situação de sala de aula ou laboratório, peça ajuda ao seu instrutor ou a um dos proctors para configurar sua nova conta.

  2. Depois de iniciar sessão, clique em Novo no canto superior esquerdo e procure por Face API, prima Enter.

    Procurar API do Face

    Nota

    A palavra Novo pode ter sido substituída por Criar um recurso, em portais mais recentes.

  3. A nova página fornecerá uma descrição do serviço Face API . No canto inferior esquerdo deste prompt, selecione o botão Criar para criar uma associação com este serviço.

    Informações da API do Face

  4. Depois de clicar em Criar:

    1. Insira o nome desejado para esta instância de serviço.

    2. Selecione uma subscrição.

    3. Selecione o nível de preço apropriado para você, se esta for a primeira vez criando um serviço de API do Face, um nível gratuito (chamado F0) deve estar disponível para você.

    4. Escolha um Grupo de Recursos ou crie um novo. Um grupo de recursos fornece uma maneira de monitorar, controlar o acesso, provisionar e gerenciar a cobrança de uma coleção de ativos do Azure. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, como esses laboratórios) em um grupo de recursos comum).

      Se desejar ler mais sobre os Grupos de Recursos do Azure, visite o artigo do grupo de recursos.

    5. O aplicativo UWP, Person Maker, que você usa mais tarde, requer o uso de 'West US' para localização.

    6. Você também precisará confirmar que compreendeu os Termos e Condições aplicados a este Serviço.

    7. Selecione Criar.*

      Criar serviço de API do Face

  5. Depois de clicar em Criar,* você terá que esperar que o serviço seja criado, isso pode levar um minuto.

  6. Uma notificação aparecerá no portal assim que a instância de serviço for criada.

    Notificação de criação de serviço

  7. Clique nas notificações para explorar sua nova instância de serviço.

    Ir para Notificação de Recursos

  8. Quando estiver pronto, clique no botão Ir para recurso na notificação para explorar sua nova instância de serviço.

    Acessar chaves de API do Face

  9. Dentro deste tutorial, seu aplicativo precisará fazer chamadas para o seu serviço, o que é feito usando a 'chave' de assinatura do seu serviço. Na página Início rápido , do seu serviço Face API , o primeiro ponto é o número 1, para Pegar suas chaves.

  10. Na página Serviço, selecione o hiperlink azul Chaves (se estiver na página Início rápido) ou o link Teclas no menu de navegação de serviços (à esquerda, indicado pelo ícone 'chave'), para revelar suas chaves.

    Nota

    Tome nota de qualquer uma das chaves e guarde-a, pois precisará dela mais tarde.

Capítulo 2 - Usando o aplicativo UWP 'Person Maker'

Certifique-se de baixar o aplicativo UWP pré-criado chamado Person Maker. Este aplicativo não é o produto final para este curso, apenas uma ferramenta para ajudá-lo a criar suas entradas do Azure, nas quais o projeto posterior confiará.

O Person Maker permite que você crie entradas do Azure, que são associadas a pessoas e grupos de pessoas. A aplicação colocará toda a informação necessária num formato que poderá depois ser utilizado pela FaceAPI, de forma a reconhecer os rostos das pessoas que adicionou.

[IMPORTANTE] O Person Maker usa algumas limitações básicas para ajudar a garantir que você não exceda o número de chamadas de serviço por minuto para a camada de assinatura gratuita. O texto verde na parte superior mudará para vermelho e será atualizado como 'ATIVO' quando a limitação estiver acontecendo; se este for o caso, basta esperar pelo aplicativo (ele aguardará até que possa continuar acessando o serviço presencial, atualizando como 'IN-ACTIVE' quando você puder usá-lo novamente).

Esta aplicação utiliza as bibliotecas Microsoft.ProjectOxford.Face , o que lhe permitirá fazer pleno uso da API Face. Esta biblioteca está disponível gratuitamente como um pacote NuGet. Para obter mais informações sobre essas APIs e similares, visite o artigo de referência da API.

Nota

Estes são apenas os passos necessários, instruções de como fazer essas coisas está mais abaixo no documento. A aplicação Person Maker permite-lhe:

  • Crie um Grupo de Pessoas, que é um grupo composto por várias pessoas que você deseja associar a ele. Com sua conta do Azure, você pode hospedar vários Grupos de Pessoas.

  • Crie uma Pessoa, que é membro de um Grupo de Pessoas. Cada pessoa tem um número de imagens de rosto associadas a ele.

  • Atribua imagens de rosto a uma Pessoa, para permitir que o Serviço de API do Azure Face reconheça uma Pessoa pelo rosto correspondente.

  • Treine seu Serviço de API do Azure Face.

Esteja ciente, então para treinar este aplicativo para reconhecer pessoas, você precisará de dez (10) fotos em close-up de cada pessoa que você gostaria de adicionar ao seu Grupo de Pessoas. O Windows 10 Cam App pode ajudá-lo a levá-los. Você deve garantir que cada foto seja clara (evite desfocar, obscurecer ou ficar muito longe do assunto), ter a foto no formato de arquivo jpg ou png, com o tamanho do arquivo de imagem não sendo maior de 4 MB e não inferior a 1 KB.

Nota

Se você está seguindo este tutorial, não use seu próprio rosto para treinar, pois quando você coloca o HoloLens, você não pode olhar para si mesmo. Use o rosto de um colega ou colega.

Criador de Pessoa em Execução:

  1. Abra a pasta PersonMaker e clique duas vezes na solução PersonMaker para abri-la com o Visual Studio.

  2. Quando a solução PersonMaker estiver aberta, certifique-se de que:

    1. A Configuração da Solução está definida como Depurar.

    2. A plataforma de solução está definida como x86

    3. A plataforma de destino é a máquina local.

    4. Também pode ser necessário Restaurar Pacotes NuGet (clique com o botão direito do mouse na Solução e selecione Restaurar Pacotes NuGet).

  3. Clique em Máquina Local e o aplicativo será iniciado. Esteja ciente de que, em telas menores, todo o conteúdo pode não estar visível, embora você possa rolar mais para baixo para visualizá-lo.

    Interface de usuário do Person Maker

  4. Insira sua Chave de Autenticação do Azure, que você deve ter, do seu serviço de API do Face no Azure.

  5. Insert:

    1. A ID que você deseja atribuir ao Grupo de Pessoas. O ID deve ser minúsculo, sem espaços. Anote esse ID, pois ele será exigido posteriormente em seu projeto Unity.
    2. O Nome que pretende atribuir ao Grupo de Pessoas (pode ter espaços).
  6. Pressione o botão Create Person Group (Criar grupo de pessoas ). Deve aparecer uma mensagem de confirmação por baixo do botão.

Nota

Se você tiver um erro 'Acesso negado', verifique o local definido para seu serviço do Azure. Como dito acima, este aplicativo é projetado para 'West US'.

Importante

Você notará que também pode clicar no botão Buscar um grupo conhecido: isso é para se você já criou um grupo de pessoas e deseja usá-lo, em vez de criar um novo. Esteja ciente, se você clicar em Criar um grupo de pessoas com um grupo conhecido, isso também buscará um grupo.

  1. Insira o Nome da Pessoa que pretende criar.

    1. Clique no botão Criar pessoa .

    2. Deve aparecer uma mensagem de confirmação por baixo do botão.

    3. Se desejar eliminar uma pessoa que criou anteriormente, pode escrever o nome na caixa de texto e premir Eliminar Pessoa

  2. Certifique-se de saber a localização de dez (10) fotos da pessoa que você gostaria de adicionar ao seu grupo.

  3. Prima Criar e Abrir Pasta para abrir o Explorador do Windows na pasta associada à pessoa. Adicione as dez (10) imagens na pasta. Estes devem ser de formato de arquivo JPG ou PNG .

  4. Clique em Enviar para o Azure. Um contador mostrará o estado do envio, seguido de uma mensagem quando ele for concluído.

  5. Quando o contador terminar e uma mensagem de confirmação for exibida, clique em Treinar para treinar seu serviço.

Quando o processo for concluído, você estará pronto para entrar em Unity.

Capítulo 3 - Configurar o projeto Unity

O seguinte é uma configuração típica para desenvolver com realidade mista e, como tal, é um bom modelo para outros projetos.

  1. Abra o Unity e clique em Novo.

    Inicie um novo projeto Unity.

  2. Agora você precisará fornecer um nome de Projeto Unity. Inserir MR_FaceRecognition. Verifique se o tipo de projeto está definido como 3D. Defina o Local para algum lugar apropriado para você (lembre-se, mais perto de diretórios raiz é melhor). Em seguida, clique em Criar projeto.

    Forneça detalhes para o novo projeto Unity.

  3. Com o Unity aberto, vale a pena verificar se o Editor de Scripts padrão está definido como Visual Studio. Vá para Editar > Preferências e, na nova janela, navegue até Ferramentas Externas. Altere o Editor de Scripts Externo para Visual Studio 2017. Feche a janela Preferências .

    Atualize a preferência do editor de scripts.

  4. Em seguida, vá para Configurações de compilação de arquivos > e mude a plataforma para a Plataforma Universal do Windows, clicando no botão Alternar plataforma.

    Janela Configurações de compilação, mude a plataforma para UWP.

  5. Vá para Configurações de compilação de arquivo > e certifique-se de que:

    1. O dispositivo alvo está definido como HoloLens

      Para os auriculares imersivos, defina Target Device como Any Device.

    2. O tipo de compilação está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. Versão do Visual Studio está definida como A versão mais recente instalada

    5. Build and Run está definido como Máquina Local

    6. Salve a cena e adicione-a à compilação.

      1. Faça isso selecionando Adicionar cenas abertas. Será exibida uma janela de salvamento.

        Clique no botão adicionar cenas abertas

      2. Selecione o botão Nova pasta , para criar uma nova pasta, nomeie-a Cenas.

        Criar nova pasta de scripts

      3. Abra a pasta Cenas recém-criada e, no campo de texto Nome do arquivo:, digite FaceRecScene e pressione Salvar.

        Dê um nome à nova cena.

    7. As configurações restantes, em Configurações de compilação, devem ser deixadas como padrão por enquanto.

  6. Na janela Configurações de compilação, clique no botão Configurações do player, isso abrirá o painel relacionado no espaço onde o inspetor está localizado.

    Abra as configurações do player.

  7. Neste painel, algumas configurações precisam ser verificadas:

    1. Na guia Outras configurações:

      1. A versão do Scripting Runtime deve ser experimental (equivalente ao .NET 4.6). Alterar isso desencadeará a necessidade de reiniciar o Editor.

      2. O back-end de scripts deve ser .NET

      3. O nível de compatibilidade da API deve ser .NET 4.6

        Atualize outras configurações.

    2. Na guia Configurações de publicação , em Recursos, verifique:

      • InternetClient

      • Webcam

        Atualização das configurações de publicação.

    3. Mais abaixo no painel, em Configurações XR (encontradas abaixo de Configurações de publicação), marque Realidade Virtual suportada, verifique se o SDK de realidade mista do Windows foi adicionado.

      Atualize as configurações do X R.

  8. De volta às Configurações de compilação, o Unity C# Projects não está mais acinzentado, marque a caixa de seleção ao lado disso.

  9. Feche a janela Configurações de compilação.

  10. Salve sua cena e projeto (FILE > SAVE SCENE / FILE > SAVE PROJECT).

Capítulo 4 - Configuração da câmara principal

Importante

Se você deseja pular o componente Unity set deste curso e continuar direto no código, sinta-se à vontade para baixar este .unitypackage e importá-lo para seu projeto como um pacote personalizado. Esteja ciente de que este pacote também inclui a importação da DLL, abordada no Capítulo 5. Com isso importado, você pode continuar a partir do Capítulo 6.

  1. No Painel Hierarquia, selecione a Câmara Principal.

  2. Uma vez selecionado, você será capaz de ver todos os componentes da câmera principal no painel do inspetor.

    1. O objeto Camera deve ser chamado Main Camera (observe a ortografia!)

    2. A tag da câmera principal deve ser definida como MainCamera (observe a ortografia!)

    3. Verifique se a Posição de transformação está definida como 0, 0, 0

    4. Definir sinalizadores transparentes como cor sólida

    5. Defina a cor de fundo do componente da câmera para preto, alfa 0 (código hexadecimal: #00000000)

      Configurar componentes da câmara

Capítulo 5 – Importar a biblioteca Newtonsoft.Json

Importante

Se você importou o '.unitypackage' no último capítulo, você pode pular este capítulo.

Para ajudá-lo a desserializar e serializar objetos recebidos e enviados para o Serviço de Bot, você precisa baixar a biblioteca Newtonsoft.Json . Você encontrará uma versão compatível já organizada com a estrutura de pastas Unity correta neste arquivo de pacote Unity.

Para importar a biblioteca:

  1. Faça o download do pacote Unity.

  2. Clique em Ativos, Importar Pacote, Pacote Personalizado.

    Importação Newtonsoft.Json

  3. Procure o Pacote Unity que você baixou e clique em Abrir.

  4. Verifique se todos os componentes do pacote estão marcados e clique em Importar.

    Importar os ativos Newtonsoft.Json

Capítulo 6 - Criar a classe FaceAnalysis

O objetivo da classe FaceAnalysis é hospedar os métodos necessários para se comunicar com seu Serviço de Reconhecimento Facial do Azure.

  • Depois de enviar ao serviço uma imagem de captura, ele irá analisá-la e identificar os rostos dentro, e determinar se algum pertence a uma pessoa conhecida.
  • Se uma pessoa conhecida for encontrada, essa classe exibirá seu nome como texto da interface do usuário na cena.

Para criar a classe FaceAnalysis :

  1. Clique com o botão direito do mouse na Pasta Ativos localizada no Painel do Projeto e clique em Criar>Pasta. Chame a pasta Scripts.

    Crie a classe FaceAnalysis.

  2. Clique duas vezes na pasta recém-criada, para abri-la.

  3. Clique com o botão direito do mouse dentro da pasta e clique em Criar>script C#. Chame o script de FaceAnalysis.

  4. Clique duas vezes no novo script FaceAnalysis para abri-lo com o Visual Studio 2017.

  5. Insira os seguintes namespaces acima da classe FaceAnalysis :

        using Newtonsoft.Json;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using System.Text;
        using UnityEngine;
        using UnityEngine.Networking;
    
  6. Agora você precisa adicionar todos os objetos que são usados para desseriar. Esses objetos precisam ser adicionados fora do script FaceAnalysis (abaixo do colchete inferior).

        /// <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. Os métodos Start() e Update() não serão usados, portanto, exclua-os agora.

  8. Dentro da classe FaceAnalysis , adicione as seguintes variáveis:

        /// <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 -";
    

    Nota

    Substitua a chave e o personGroupId pela sua Chave de Serviço e pela Id do grupo que você criou anteriormente.

  9. Adicione o método Awake(), que inicializa a classe, adicionando a classe ImageCapture à câmera principal e chama o método de criação 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. Adicione o método CreateLabel(), que cria o objeto Label para exibir o resultado da análise:

        /// <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. Adicione o método DetectFacesFromImage() e GetImageAsByteArray(). O primeiro solicitará ao Serviço de Reconhecimento Facial para detetar qualquer rosto possível na imagem enviada, enquanto o segundo é necessário para converter a imagem capturada em uma matriz de bytes:

        /// <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. Adicione o método IdentifyFaces(), que solicita ao Serviço de Reconhecimento Facial que identifique qualquer rosto conhecido detetado anteriormente na imagem enviada. O pedido devolverá um id da pessoa identificada, mas não o nome:

        /// <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. Adicione o método GetPerson(). Ao fornecer o ID da pessoa, este método solicita que o Serviço de Reconhecimento Facial devolva o nome da pessoa identificada:

        /// <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. Lembre-se de salvar as alterações antes de voltar para o Editor Unity.

  15. No Editor Unity, arraste o script FaceAnalysis da pasta Scripts no painel Projeto para o objeto Câmara Principal no painel Hierarquia. O novo componente de script será assim adicionado à câmera principal.

Coloque o FaceAnalysis na câmara principal

Capítulo 7 - Criar a classe ImageCapture

O objetivo da classe ImageCapture é hospedar os métodos necessários para se comunicar com o Serviço de Reconhecimento Facial do Azure para analisar a imagem que você capturará, identificando rostos nela e determinando se ela pertence a uma pessoa conhecida. Se uma pessoa conhecida for encontrada, essa classe exibirá seu nome como texto da interface do usuário na cena.

Para criar a classe ImageCapture :

  1. Clique com o botão direito do mouse dentro da pasta Scripts que você criou anteriormente e, em seguida, clique em Criar, Script C#. Chame o script ImageCapture.

  2. Clique duas vezes no novo script ImageCapture para abri-lo com o Visual Studio 2017.

  3. Insira os seguintes namespaces acima da classe ImageCapture:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  4. Dentro da classe ImageCapture , adicione as seguintes variáveis:

        /// <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. Adicione os métodos Awake() e Start() necessários para inicializar a classe e permitir que o HoloLens capture os gestos do usuário:

        /// <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. Adicione o TapHandler() que é chamado quando o usuário executa um gesto de toque:

        /// <summary>
        /// Respond to Tap Input.
        /// </summary>
        private void TapHandler(TappedEventArgs obj)
        {
            tapsCount++;
            ExecuteImageCaptureAndAnalysis();
        }
    
  7. Adicione o método ExecuteImageCaptureAndAnalysis(), que iniciará o processo de captura de imagem:

        /// <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. Adicione os manipuladores que são chamados quando o processo de captura de fotos for concluído:

        /// <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. Lembre-se de salvar as alterações antes de voltar para o Editor Unity.

Capítulo 8 - Construindo a solução

Para realizar um teste completo do seu aplicativo, você precisará fazer o sideload dele em seu HoloLens.

Antes de o fazer, certifique-se de que:

  • Todas as configurações mencionadas no Capítulo 3 estão definidas corretamente.
  • O script FaceAnalysis é anexado ao objeto Main Camera.
  • Tanto a Chave de Autenticação quanto a ID do Grupo foram definidas dentro do script do FaceAnalysis.

Neste ponto, você está pronto para criar a Solução. Depois que a Solução tiver sido criada, você estará pronto para implantar seu aplicativo.

Para iniciar o processo de compilação:

  1. Salve a cena atual clicando em Arquivo, Salvar.

  2. Vá para Arquivo, Configurações de Compilação, clique em Adicionar Cenas Abertas.

  3. Certifique-se de marcar Unity C# Projects.

    Implantar a solução Visual Studio

  4. Pressione Build. Ao fazer isso, Unity iniciará uma janela do Explorador de Arquivos, onde você precisa criar e, em seguida, selecionar uma pasta para construir o aplicativo. Crie essa pasta agora, dentro do projeto Unity, e chame-a de App. Em seguida, com a pasta App selecionada, pressione Select Folder.

  5. Unity começará a construir seu projeto, para a pasta App.

  6. Quando o Unity terminar de construir (pode levar algum tempo), ele abrirá uma janela do Explorador de Arquivos no local da sua compilação.

    Implantar a solução do Visual Studio

  7. Abra a pasta App e, em seguida, abra a nova Solução de Projeto (como visto acima, MR_FaceRecognition.sln).

Capítulo 9 - Implantando seu aplicativo

Para implantar no HoloLens:

  1. Você precisará do endereço IP do seu HoloLens (para implantação remota) e para garantir que seu HoloLens esteja no modo de desenvolvedor. Para tal:

    1. Enquanto estiver a usar o HoloLens, abra as Definições.
    2. Ir para Rede & Opções Avançadas de Wi-Fi > da Internet >
    3. Observe o endereço IPv4 .
    4. Em seguida, navegue de volta para Configurações e, em seguida, para Atualizar & Segurança > para desenvolvedores
    5. Defina o modo de desenvolvedor ativado.
  2. Navegue até sua nova compilação Unity (a pasta App) e abra o arquivo de solução com o Visual Studio.

  3. Na Configuração da Solução, selecione Depurar.

  4. Na Plataforma de Solução, selecione x86, Máquina Remota.

    Alterar a configuração da solução

  5. Vá para o menu Build e clique em Deploy Solution, para fazer sideload do aplicativo para o seu HoloLens.

  6. Seu aplicativo agora deve aparecer na lista de aplicativos instalados no seu HoloLens, pronto para ser lançado!

Nota

Para implantar no fone de ouvido imersivo, defina a Plataforma de Solução como Máquina Local e defina a Configuração como Depurar, com x86 como Plataforma. Em seguida, implante na máquina local, usando o menu Compilar, selecionando Implantar solução.

Capítulo 10 - Utilização da aplicação

  1. Usando o HoloLens, inicie o aplicativo.

  2. Olhe para a pessoa que você registrou com a API Face. Certifique-se de que:

    • O rosto da pessoa não é muito distante e claramente visível
    • A iluminação do ambiente não é muito escura
  3. Use o gesto de toque para capturar a imagem da pessoa.

  4. Aguarde até que o aplicativo envie a solicitação de análise e receba uma resposta.

  5. Se a pessoa tiver sido reconhecida com sucesso, o nome da pessoa aparecerá como texto da interface do usuário.

  6. Você pode repetir o processo de captura usando o gesto de toque a cada poucos segundos.

Seu aplicativo de API do Azure Face concluído

Parabéns, você criou um aplicativo de realidade mista que aproveita o serviço de Reconhecimento Facial do Azure para detetar rostos em uma imagem e identificar rostos conhecidos.

Resultado da conclusão deste curso

Exercícios de bónus

Exercício 1

A API do Azure Face é poderosa o suficiente para detetar até 64 faces em uma única imagem. Estender a aplicação, para que possa reconhecer duas ou três faces, entre muitas outras pessoas.

Exercício 2

A API do Azure Face também é capaz de fornecer de volta todos os tipos de informações de atributo. Integre isso no aplicativo. Isso poderia ser ainda mais interessante, quando combinado com a API Emotion.