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 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, todos na nuvem. A API de Detecção Facial tem duas funções main: 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 pertence um rosto. 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 do HoloLens a bordo.
  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 do Usuário simples para exibir o nome das pessoas correspondentes.

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

Em seu aplicativo, cabe a você como integrar os resultados ao seu design. Este curso foi projetado para ensinar como integrar um Serviço do Azure ao seu Projeto do Unity. É seu trabalho usar o conhecimento obtido 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 aprender neste curso para Windows Mixed Reality headsets imersivos (VR). Como os headsets imersivos (VR) não têm câmeras acessíveis, você precisará de uma câmera externa conectada ao computador. Ao acompanhar o curso, você verá anotações sobre as alterações que talvez precise empregar para dar suporte a headsets imersivos (VR).

Pré-requisitos

Observação

Este tutorial foi projetado para desenvolvedores que têm experiência básica com Unity e C#. Lembre-se também de que os pré-requisitos e as instruções escritas neste documento representam o que foi testado e verificado no momento da gravação (maio de 2018). Você está livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não se presuma que as informações neste curso corresponderão perfeitamente ao que você encontrará no software mais recente do que o listado 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 longa podem causar problemas no tempo de build).
  2. Configure e teste o HoloLens. Se você precisar de suporte para configurar o HoloLens, visite o artigo de configuração do HoloLens.
  3. É uma boa ideia executar a Calibragem 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 Calibragem, siga este link para o artigo Calibragem do HoloLens.

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

Capítulo 1 – 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 para 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 situação de sala de aula ou laboratório, peça ajuda ao instrutor ou a um dos supervisores para configurar sua nova conta.

  2. Depois de fazer logon, clique em Novo no canto superior esquerdo e pesquise API de Detecção Facial, pressione Enter.

    pesquisar a 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 criar um Serviço de API de Detecção Facial, uma camada gratuita (chamada 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, Criador de Pessoas, que você usa posteriormente, 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 aguardar a criação do serviço, isso pode levar um minuto.

  6. Uma notificação será exibida no portal depois 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 a 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 por meio do uso da "chave" da 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 Pegar suas chaves.

  10. Na página Serviço , selecione o hiperlink teclas azul (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 'chave'), para revelar suas chaves.

    Observação

    Anote uma das chaves e proteja-a, pois você precisará dela mais tarde.

Capítulo 2 – Usando o aplicativo UWP 'Criador de Pessoas'

Baixe o aplicativo UWP predefinido chamado Criador de Pessoas. 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 Criador de Pessoas 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 pode ser usado posteriormente pela 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 a camada de assinatura gratuita. O texto verde na parte superior será alterado para vermelho e será atualizado como "ATIVO" quando a limitação estiver acontecendo; se esse for o caso, basta aguardar o aplicativo (ele aguardará até que ele possa continuar acessando o serviço de detecção facial, atualizando como 'IN-ACTIVE' quando você puder usá-lo novamente).

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

Observação

Essas são apenas as etapas necessárias, as instruções de 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 várias imagens de Detecção Facial associadas a ela.

  • Atribua imagens faciais a uma Pessoa para permitir que seu 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.

Lembre-se de que, para treinar este aplicativo para reconhecer pessoas, você precisará de dez (10) fotos de close-up de cada pessoa que você gostaria de adicionar ao seu Grupo de Pessoas. O aplicativo Windows 10 Cam pode ajudá-lo a tomá-los. Você deve garantir que cada foto esteja clara (evite desfocar, ocultar ou estar 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 4 MB e nada menos que 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.

Executando o Person Maker:

  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, verifique se:

    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 é o Computador 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 Computador Local e o aplicativo será iniciado. Lembre-se de que, em telas menores, todo o conteúdo pode não estar visível, embora você possa rolar mais para baixo para exibi-lo.

    interface do usuário do criador de pessoas

  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. A ID deve ser minúscula, 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 'Acesso Negado', marcar o local definido para o serviço do Azure. Conforme indicado acima, este aplicativo foi projetado para 'Oeste dos EUA'.

Importante

Você observará 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ê quiser excluir uma pessoa que criou anteriormente, poderá escrever o nome na caixa de texto e pressionar Excluir Pessoa

  2. Verifique se você sabe o local de dez (dez) fotos da pessoa que deseja adicionar ao seu grupo.

  3. Pressione Criar e Abrir Pasta para abrir o Windows Explorer à 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. Depois que o contador for concluído 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 o desenvolvimento com realidade misturada e, como tal, é um bom modelo para outros projetos.

  1. Abra o Unity e clique em Novo.

    Inicie o novo projeto do Unity.

  2. Agora você precisará fornecer um nome de projeto do Unity. Inserir MR_FaceRecognition. Verifique se o tipo de projeto está definido como 3D. Defina o Local como um lugar apropriado para você (lembre-se, mais próximo 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, em seguida, na nova janela, navegue até Ferramentas Externas. Altere o Editor de Script Externo para o Visual Studio 2017. Feche a janela Preferências.

    Atualizar a preferência do editor de script.

  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 verifique se:

    1. O dispositivo de destino está definido como HoloLens

      Para os headsets imersivos, defina Dispositivo de Destino como Qualquer Dispositivo.

    2. O Tipo de Build é definido como D3D

    3. O SDK está definido como Mais recente instalado

    4. A versão do Visual Studio está definida como Mais Recente instalada

    5. Compilar e Executar é definido como Computador Local

    6. Salve a cena e adicione-a ao build.

      1. Faça isso selecionando Adicionar Cenas Abertas. Uma janela de salvamento será exibida.

        Clique no botão Adicionar cenas abertas

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

        Criar pasta de scripts

      3. Abra a pasta Cenas recém-criada e, em seguida, no campo Nome do arquivo: texto, 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 Build, clique no botão Configurações do Player , isso abrirá o painel relacionado no espaço em que 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 de runtimede script deve ser experimental (equivalente ao .NET 4.6). Alterar isso disparará 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, marcar:

      • InternetClient

      • Webcam

        Atualizando as configurações de publicação.

    3. Mais abaixo no painel, em Configurações de XR (encontradas abaixo de Configurações de Publicação), marque Com suporte à Realidade Virtual, 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 disso.

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

  10. Salve a Cena e o Projeto (FILE > SAVE SCENE/FILE > SAVE PROJECT).

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

Importante

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

  1. No Painel hierarquia , selecione a Câmera Principal.

  2. Depois de selecionado, você poderá ver todos os componentes da Câmera Principal no Painel do Inspetor.

    1. O objeto Câmera deve ser nomeado Câmera Principal (observe a ortografia!)

    2. A Marca 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 Desmarcados como Cor Sólida

    5. Defina a Cor da Tela de Fundo do Componente da Câmera como Preto, Alfa 0 (Código Hex: #000000000)

      configurar componentes da câmera

Capítulo 5 – Importar a biblioteca Newtonsoft.Json

Importante

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

Para importar a biblioteca:

  1. Baixe o Pacote do 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. 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

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, ela a analisará e identificará os rostos dentro e determinará se alguma 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 de Projeto e clique em Criar>Pasta. Chame a pasta Scripts.

    Crie a classe FaceAnalysis.

  2. Clique duas vezes na pasta que acabou de ser 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 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 usados para desserializar. 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 -";
    

    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á que o Serviço de Reconhecimento Facial detecte 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 IdentifiFaces(), que solicita ao Serviço de Reconhecimento Facial para identificar qualquer rosto conhecido detectado anteriormente na imagem enviada. A solicitação retornará uma 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 para o 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.

Colocar 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á, identificar rostos nela e determinar 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 na pasta Scripts que você criou anteriormente e clique em Criarscript 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 tiver sido 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 do Unity.

Capítulo 8 – Criando a solução

Para executar um teste completo do aplicativo, você precisará fazer sideload dele no HoloLens.

Antes disso, verifique se:

  • Todas as configurações mencionadas no Capítulo 3 são definidas corretamente.
  • O script FaceAnalysis está anexado ao objeto Câmera Principal.
  • A Chave de Autenticação e a ID do Grupo foram definidas no script FaceAnalysis .

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

Para iniciar o processo de build:

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

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

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

    Implantar a solução do Visual Studio

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

  5. O Unity começará a compilar seu projeto, na pasta Aplicativo.

  6. Depois que o Unity terminar de compilar (pode levar algum tempo), ele abrirá uma janela Explorador de Arquivos no local do build.

    Implantar a solução no Visual Studio

  7. Abra a pasta Aplicativo e 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 para garantir que o HoloLens esteja no Modo de Desenvolvedor. Para fazer isso:

    1. Ao usar o HoloLens, abra as Configurações.
    2. Vá para Opções Avançadas de Wi-Fi da Internet & > de Rede >
    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 Modo de Desenvolvedor Ativado.
  2. Navegue até o novo build do Unity (a pasta Aplicativo ) 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, Computador Remoto.

    Alterar a configuração da solução

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

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

Observação

Para implantar no headset imersivo, defina a Plataforma de Soluções como Computador Local e defina a Configuração como Depuração, 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. Examine a pessoa que você registrou com a API de Detecção Facial. Certifique-se de que:

    • O rosto da pessoa não é muito distante e claramente visível
    • A iluminação do ambiente não está 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 ê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 de Detecção Facial do Azure 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 duas ou três faces, entre muitas outras pessoas.

Exercício 2

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