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


Observação

Os tutoriais do Mixed Reality Academy foram projetados com o HoloLens (1ª geração) e os headsets imersivos de realidade misturada em mente. Dessa forma, achamos que é importante continuar disponibilizando esses tutoriais para os desenvolvedores que ainda buscam obter diretrizes para o desenvolvimento visando esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas mais recentes nem com as interações usadas para o HoloLens 2. Eles serão mantidos para continuar funcionando nos dispositivos compatíveis. Haverá uma nova série de tutoriais que serão postados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem postados.


Resultado da conclusão deste curso

Neste curso, você aprenderá a adicionar recursos de reconhecimento facial a um aplicativo de realidade misturada, usando os Serviços Cognitivos do Azure, com a API de Detecção Facial da Microsoft.

A API de Detecção Facial do Azure é um serviço da Microsoft, que fornece aos desenvolvedores os algoritmos de detecção facial mais avançados, tudo na nuvem. A API de Detecção Facial tem duas funções principais: detecção facial 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 posteriormente, para determinar a quem um rosto pertence. Para obter mais informações, visite a página Reconhecimento Facial do Azure.

Depois de concluir este curso, você terá um aplicativo HoloLens de realidade misturada, que poderá fazer o seguinte:

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

Isso ensinará como obter os resultados do Serviço de API de Detecção Facial em seu aplicativo de realidade misturada baseado em Unity.

Em sua aplicação, cabe a você como integrará os resultados ao seu design. Este curso foi desenvolvido para ensinar como integrar um Serviço do Azure ao seu projeto do Unity. É seu trabalho usar o conhecimento adquirido com este curso para aprimorar seu aplicativo de realidade misturada.

Suporte a dispositivos

Curso HoloLens Headsets imersivos
MR e Azure 304: reconhecimento facial ✔️ ✔️

Observação

Embora este curso se concentre principalmente no HoloLens, você também pode aplicar o que aprendeu neste curso a headsets imersivos (VR) do Windows Mixed Reality. Como os headsets 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á notas sobre quaisquer alterações que possa precisar empregar para oferecer suporte a headsets imersivos (VR).

Pré-requisitos

Observação

Este tutorial foi desenvolvido para desenvolvedores que têm experiência básica com Unity e C#. Esteja ciente também de que os pré-requisitos e as 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 softwares mais recentes do que os listados abaixo.

Recomendamos o seguinte hardware e software para este curso:

Antes de começar

  1. Para evitar 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 no momento da compilação).
  2. Configure e teste 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 a calibração, siga este link para o artigo Calibração do HoloLens.

Para obter ajuda sobre o Ajuste do Sensor, siga este link para o artigo Ajuste do Sensor do HoloLens.

Capítulo 1 – O Portal do Azure

Para usar o serviço de API de Detecção Facial 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.

    Observação

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

  2. Depois de fazer login, clique em Novo no canto superior esquerdo e procure por Face API, pressione Enter.

    Pesquisar API de Detecção Facial

    Observação

    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 de API de Detecção Facial. Na parte inferior esquerda desse prompt, selecione o botão Criar para criar uma associação com esse serviço.

    Informações da API de Detecção Facial

  4. Depois de clicar em Criar:

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

    2. Selecione uma assinatura.

    3. Selecione o tipo de preço apropriado para você, se esta for a primeira vez que cria um serviço de API de Detecção Facial, um nível gratuito (chamado F0) deverá 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 você quiser 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 'Oeste dos EUA' para localização.

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

    7. Selecione Criar*.

      Criar serviço de API de Detecção Facial

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

  6. Uma notificação será exibida 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 o recurso na notificação para explorar sua nova instância de serviço.

    Acessar chaves de API de Detecção Facial

  9. Neste tutorial, seu aplicativo precisará fazer chamadas para seu serviço, o que é feito usando a 'chave' de assinatura do serviço. Na página Início rápido , do serviço de API de Detecção Facial, o primeiro ponto é o número 1, para Pegue 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 Chaves no menu de navegação de serviços (à esquerda, indicado pelo ícone de 'chave'), para revelar suas chaves.

    Observação

    Anote qualquer uma das chaves e proteja-a, pois você 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 deste curso, apenas uma ferramenta para ajudá-lo a criar suas entradas do Azure, das quais o projeto posterior dependerá.

O Person Maker permite que você crie entradas do Azure, que são associadas a pessoas e grupos de pessoas. O aplicativo colocará todas as informações necessárias em um formato que poderá ser usado posteriormente pelo FaceAPI, a fim de reconhecer os rostos das pessoas que você adicionou.

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

Este aplicativo usa as bibliotecas Microsoft.ProjectOxford.Face , que permitirão que você faça uso total da API de Detecção Facial. Essa biblioteca está disponível gratuitamente como um pacote NuGet. Para obter mais informações sobre isso e APIs semelhantes, visite o artigo de referência da API.

Observação

Estas são apenas as etapas necessárias, as instruções sobre como fazer essas coisas estão mais abaixo no documento. O aplicativo Person Maker permitirá que você:

  • 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 ela.

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

  • Treine seu Serviço de API de Detecção Facial do Azure.

Esteja ciente, para treinar este aplicativo para reconhecer pessoas, você precisará de dez (10) fotos em close-up de cada pessoa que gostaria de adicionar ao seu grupo de pessoas. O aplicativo Windows 10 Cam pode ajudá-lo a fazer isso. Você deve garantir que cada foto esteja nítida (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 que 4 MB e não inferior a 1 KB.

Observação

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

Criador de pessoas em execução:

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

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

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

    2. A Plataforma de Solução é definida como x86

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

    4. Talvez você também precise 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 serviço de API de Detecção Facial no Azure.

  5. Inserir:

    1. A ID que você deseja atribuir ao Grupo de Pessoas. O ID deve ser minúsculo, sem espaços. Anote essa ID, pois ela será necessária posteriormente em seu projeto do Unity.
    2. O Nome que você deseja atribuir ao Grupo de Pessoas (pode ter espaços).
  6. Pressione o botão Criar grupo de pessoas. Uma mensagem de confirmação deve aparecer abaixo do botão.

Observação

Se você tiver um erro de 'Acesso negado', verifique o local definido para o serviço do Azure. Como dito acima, este aplicativo foi projetado para 'Oeste dos EUA'.

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. Lembre-se de que, 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 você deseja criar.

    1. Clique no botão Criar pessoa .

    2. Uma mensagem de confirmação deve aparecer abaixo do botão.

    3. Se você deseja excluir uma pessoa que você criou anteriormente, você pode escrever o nome na caixa de texto e pressionar Excluir pessoa

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

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

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

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

Depois que o processo for concluído, você estará pronto para migrar para o Unity.

Capítulo 3 – Configurar o projeto do Unity

Veja a seguir uma configuração típica para desenvolvimento com realidade misturada e, como tal, é um bom modelo para outros projetos.

  1. Abra o Unity e clique em Novo.

    Inicie um novo projeto do Unity.

  2. Agora você precisará fornecer um nome de projeto do Unity. Insira MR_FaceRecognition. Certifique-se de que o tipo de projeto esteja definido como 3D. Defina o local para algum lugar apropriado para você (lembre-se, mais perto dos diretórios raiz é melhor). Em seguida, clique em Criar projeto.

    Forneça detalhes para o novo projeto do 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 Script 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 Build de Arquivo > e alterne a plataforma para Plataforma Universal do Windows, clicando no botão Alternar Plataforma.

    Janela Configurações de Build, alterne a plataforma para UWP.

  5. Vá para Configurações de Build de Arquivo > e certifique-se de que:

    1. O dispositivo de destino está definido como HoloLens

      Para os headsets imersivos, defina Dispositivo de destino como Qualquer dispositivo.

    2. O Tipo de Construção está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. A versão do Visual Studio está definida como Mais recente instalado

    5. Build and Run está definido como Computador Local

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

      1. Faça isso selecionando Adicionar cenas abertas. Uma janela de salvamento aparecerá.

        Clique no botão adicionar cenas abertas

      2. Selecione o botão Nova pasta , para criar uma nova pasta, nomeie-a como 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 Build, devem ser deixadas como padrão por enquanto.

  6. Na janela Configurações de construçã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 tempo de execução do script deve ser experimental (equivalente ao .NET 4.6). Alterar isso acionará a necessidade de reiniciar o Editor.

      2. O back-end de script 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, marque:

      • InternetClient

      • Webcam

        Atualizando as 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 com Suporte, verifique se o SDK do Windows Mixed Reality foi adicionado.

      Atualize as configurações do X R.

  8. De volta às Configurações de Build, os Projetos C# do Unity não estão mais esmaecidos; marque a caixa de seleção ao lado dela.

  9. Feche a janela Configurações de Build.

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

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

Importante

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

  1. No Painel de Hierarquia, selecione a Câmera Principal.

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

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

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

    3. Certifique-se de que a Posição de transformação esteja definida como 0, 0, 0

    4. Definir sinalizadores claros para cor sólida

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

      Configurar componentes da câmera

Capítulo 5 - Importe a biblioteca Newtonsoft.Json

Importante

Se você importou o '.unitypackage' no último capítulo, 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 correta do Unity neste arquivo de pacote do Unity.

Para importar a biblioteca:

  1. Baixe o pacote Unity.

  2. Clique em Ativos, Importar pacote, Pacote personalizado.

    Importar Newtonsoft.Json

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

  4. Certifique-se de que todos os componentes do pacote estejam marcados e clique em Importar.

    Importar os ativos Newtonsoft.Json

Capítulo 6 – Criar a classe FaceAnalysis

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

  • Depois de enviar ao serviço uma imagem de captura, ele a analisará e identificará os rostos dentro dela 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 Projeto e clique em Criar>pasta. Chame a pasta de 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 desserializar. Esses objetos precisam ser adicionados fora do script FaceAnalysis (abaixo da chave 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 -";
    

    Observação

    Substitua a chave e o personGroupId pela 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 de rótulo:

        /// <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 detectar qualquer rosto possível na imagem enviada, enquanto o último é 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 que o Serviço de reconhecimento facial identifique qualquer rosto conhecido detectado anteriormente na imagem enviada. A solicitação retornará 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 a ID da pessoa, esse método solicita que o Serviço de Reconhecimento Facial retorne 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 ao Editor do Unity.

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

Coloque o FaceAnalysis na câmera principal

Capítulo 7 – Criar a classe ImageCapture

A finalidade 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 clique em Criar, Script C#. Chame o script de 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 é 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 ao Editor do Unity.

Capítulo 8 - Construindo a solução

Para executar um teste completo do aplicativo, você precisará carregá-lo no HoloLens.

Antes de fazer isso, 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.
  • A chave de autenticação e a ID do grupo foram definidas no script FaceAnalysis.

Neste ponto, você está pronto para construir a solução. Depois que a solução for 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 construção, clique em Adicionar cenas abertas.

  3. Certifique-se de marcar Projetos C# do Unity.

    Implantar a solução do Visual Studio

  4. Pressione Construir. Ao fazer isso, o Unity iniciará uma janela do Explorador de Arquivos, onde você precisa criar e selecionar uma pasta para criar 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 (Selecionar pasta).

  5. O Unity começará a criar seu projeto, na pasta App.

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

    Implantar a solução do Visual Studio

  7. Abra a pasta Aplicativo 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 HoloLens (para implantação remota) e garantir que o HoloLens esteja no modo de desenvolvedor. Para fazer isso:

    1. Enquanto estiver usando seu HoloLens, abra as Configurações.
    2. Ir para Rede e Internet > Wi-Fi > Opções avançadas
    3. Observe o endereço IPv4 .
    4. Em seguida, navegue de volta para Configurações e, em seguida, para Atualização e segurança > para desenvolvedores
    5. Ative o modo de desenvolvedor.
  2. Navegue até o novo build do 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ções, selecione x86, Computador Remoto.

    Alterar a configuração da solução

  5. Vá para o menu Compilar e clique em Implantar Solução para fazer o sideload do aplicativo no HoloLens.

  6. Seu aplicativo agora deve aparecer na lista de aplicativos instalados em seu HoloLens, pronto para ser iniciado!

Observação

Para implantar no headset imersivo, defina a Plataforma de Solução como Computador Local e defina a Configuração como Depurar, com x86 como a Plataforma. Em seguida, implante no computador local, usando o menu Compilar, selecionando Implantar Solução.

Capítulo 10 - Usando o aplicativo

  1. Usando o HoloLens, inicie o aplicativo.

  2. Olhe para a pessoa que você registrou com a API de Detecção Facial. Verifique se:

    • O rosto da pessoa não está muito distante e claramente visível
    • A iluminação do ambiente não é muito escura
  3. Use o gesto de tocar para capturar a foto 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 êxito, 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 misturada que aproveita o serviço de Reconhecimento Facial do Azure para detectar rostos em uma imagem e identificar rostos conhecidos.

Resultado da conclusão deste curso

Exercícios de bônus

Exercício 1

A API de Detecção Facial do Azure é poderosa o suficiente para detectar até 64 rostos em uma única imagem. Estenda o aplicativo, para que ele possa reconhecer dois ou três rostos, entre muitas outras pessoas.

Exercício 2

A API de Detecção Facial do Azure também é capaz de fornecer todos os tipos de informações de atributo. Integre isso ao aplicativo. Isso pode ser ainda mais interessante, quando combinado com a API de Emoção.