Compartilhar via


HoloLens (1ª geração) e Azure 302: Pesquisa Visual computacional


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.


Neste curso, você aprenderá a reconhecer o conteúdo visual em uma imagem fornecida, usando os recursos da Pesquisa Visual Computacional do Azure em um aplicativo de realidade misturada.

Os resultados do reconhecimento serão exibidos como tags descritivas. Você pode usar esse serviço sem precisar treinar um modelo de aprendizado de máquina. Se sua implementação exigir o treinamento de um modelo de aprendizado de máquina, consulte MR e Azure 302b.

Resultado do laboratório

A Pesquisa Visual Computacional da Microsoft é um conjunto de APIs projetadas para fornecer aos desenvolvedores processamento e análise de imagens (com informações de retorno), usando algoritmos avançados, tudo a partir da nuvem. Os desenvolvedores carregam uma imagem ou URL de imagem e os algoritmos da API da Pesquisa Visual Computacional da Microsoft analisam o conteúdo visual, com base nas entradas escolhidas pelo usuário, que podem retornar informações, incluindo a identificação do tipo e da qualidade de uma imagem, detectar rostos humanos (retornando suas coordenadas) e marcar ou categorizar imagens. Para obter mais informações, visite a página da API da Pesquisa Visual Computacional do Azure.

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

  1. Usando o gesto Tap, a câmera do HoloLens capturará uma imagem.
  2. A imagem será enviada para o Serviço de API da Pesquisa Visual Computacional do Azure.
  3. Os objetos reconhecidos serão listados em um grupo de interface do usuário simples posicionado na cena do 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 302: Pesquisa Visual Computacional ✔️ ✔️

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 da Pesquisa Visual Computacional 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, procure por API de Pesquisa Visual Computacional e clique em Enter.

    Criar um novo recurso no Azure

    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 Pesquisa Visual Computacional. Na parte inferior esquerda desta página, selecione o botão Criar para criar uma associação com este serviço.

    Sobre o serviço de API de Pesquisa Visual Computacional

  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 Pesquisa Visual Computacional, 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. Determine o Local do seu grupo de recursos (se você estiver criando um novo Grupo de Recursos). O local seria idealmente na região onde o aplicativo seria executado. Alguns ativos do Azure só estão disponíveis em determinadas regiões.

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

    7. Clique em Criar.

      Informações de criação de serviço

  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 será exibida no portal assim que a instância de serviço for criada.

    Ver a nova notificação do novo serviço

  7. Clique na notificação para explorar sua nova instância de serviço.

    Selecione o botão Ir para o recurso.

  8. Clique no botão Ir para o recurso na notificação para explorar sua nova instância de serviço. Você será levado para sua nova instância de serviço da API de Pesquisa Visual Computacional.

    Sua nova imagem de serviço da API de Pesquisa Visual Computacional

  9. Neste tutorial, seu aplicativo precisará fazer chamadas para seu serviço, o que é feito usando a Chave de Assinatura do serviço.

  10. Na página Início rápido do serviço de API da Pesquisa Visual Computacional, navegue até a primeira etapa, Pegue suas chaves e clique em Chaves (você também pode fazer isso clicando no hiperlink azul Chaves, localizado no menu de navegação de serviços, indicado pelo ícone de chave). Isso revelará suas chaves de serviço.

  11. Faça uma cópia de uma das chaves exibidas, pois você precisará dela mais tarde em seu projeto.

  12. Volte para a página Início rápido e, a partir daí, busque seu endpoint. Esteja ciente de que o seu pode ser diferente, dependendo da sua região (que, se for, você precisará fazer uma alteração no seu código posteriormente). Faça uma cópia desse ponto de extremidade para uso posterior:

    Seu novo serviço de API de Pesquisa Visual Computacional

    Dica

    Você pode verificar quais são os vários endpoints AQUI.

Capítulo 2 – Configurar o projeto 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_ComputerVision. 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 compilação de arquivo > e selecione Plataforma Universal do Windows e clique no botão Alternar plataforma para aplicar sua seleção.

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

  5. Enquanto ainda estiver nas configurações de compilação 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. Crie uma nova pasta para esta e qualquer cena futura e, em seguida, 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 MR_ComputerVisionScene e clique em Salvar.

        Dê um nome à nova cena.

        Lembre-se de que você deve salvar suas cenas do Unity na pasta Ativos , pois elas devem estar associadas ao Projeto do Unity. Criar a pasta scenes (e outras pastas semelhantes) é uma maneira típica de estruturar um projeto do Unity.

    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 de script deve ser estável (equivalente ao .NET 3.5).

      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:

      1. InternetClient

      2. 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 compilação Os projetos do Unity C# 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 3 - 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, importá-lo para o seu projeto como um pacote personalizado e continuar a partir do Capítulo 5.

  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. Defina Clear Flags como Solid Color (ignore isso para headset imersivo).

    5. Defina a Cor de Fundo do Componente da Câmera como Preto, Alfa 0 (Código Hexadecimal: #00000000) (ignore isso para headset imersivo).

      Atualize os componentes da câmera.

  3. Em seguida, você terá que criar um objeto "Cursor" simples anexado à câmera principal, que o ajudará a posicionar a saída da análise de imagem quando o aplicativo estiver em execução. Este cursor determinará o ponto central do foco da câmera.

Para criar o cursor:

  1. No Painel de Hierarquia, clique com o botão direito do mouse na Câmera Principal. Em Objeto 3D, clique em Esfera.

    Selecione o objeto Cursor.

  2. Renomeie a esfera para Cursor (clique duas vezes no objeto Cursor ou pressione o botão do teclado 'F2' com o objeto selecionado) e certifique-se de que ela esteja localizada como filho da câmera principal.

  3. No Painel de Hierarquia, clique com o botão esquerdo do mouse no Cursor. Com o Cursor selecionado, ajuste as seguintes variáveis no Painel Inspetor:

    1. Defina a posição de transformação como 0, 0, 5

    2. Defina a escala para 0,02, 0,02, 0,02

      Atualize a posição e a escala da transformação.

Capítulo 4 - Configurar o sistema de etiquetas

Depois de capturar uma imagem com a câmera do HoloLens, essa imagem será enviada para a instância do Serviço de API da Pesquisa Visual Computacional do Azure para análise.

Os resultados dessa análise serão uma lista de objetos reconhecidos chamados Tags.

Você usará rótulos (como um texto 3D no espaço do mundo) para exibir essas etiquetas no local em que a foto foi tirada.

As etapas a seguir mostrarão como configurar o objeto Label .

  1. Clique com o botão direito do mouse em qualquer lugar no Painel de Hierarquia (a localização não importa neste momento), em Objeto 3D, adicione um Texto 3D. Nomeie-o como LabelText.

    Crie um objeto de texto 3D.

  2. No Painel de Hierarquia, clique com o botão esquerdo do mouse no LabelText. Com o LabelText selecionado, ajuste as seguintes variáveis no Painel Inspetor:

    1. Defina a posição como 0,0,0
    2. Defina a escala para 0,01, 0,01, 0,01
    3. No componente Text Mesh:
    4. Substitua todo o texto dentro do Texto, por "..."
    5. Definir a âncora para o centro do meio
    6. Definir o alinhamento para o centro
    7. Defina o tamanho da guia para 4
    8. Defina o tamanho da fonte como 50
    9. Defina a cor como #FFFFFFFF

    Componente de texto

  3. Arraste o LabelText do Painel de Hierarquia para a Pasta de Ativos, dentro do Painel de Projeto. Isso tornará o LabelText um Prefab, para que ele possa ser instanciado no código.

    Crie um pré-fabricado do objeto LabelText.

  4. Você deve excluir o LabelText do Painel de Hierarquia, para que ele não seja exibido na cena de abertura. Como agora é um pré-fabricado, que você chamará para instâncias individuais da pasta Assets, não há necessidade de mantê-lo dentro da cena.

  5. A estrutura final do objeto no Painel de Hierarquia deve ser como a mostrada na imagem abaixo:

    Estrutura final do painel de hierarquia.

Capítulo 5 – Criar a classe ResultsLabel

O primeiro script que você precisa criar é a classe ResultsLabel , que é responsável pelo seguinte:

  • Criando os rótulos no espaço do mundo apropriado, em relação à posição da câmera.
  • Exibindo as tags da análise de imagem.

Para criar essa classe:

  1. Clique com o botão direito do mouse no painel Projeto e, em seguida, em Criar > pasta. Nomeie a pasta Scripts.

    Criar pasta de scripts.

  2. Com a pasta Scripts create, clique duas vezes nela para abri-la. Em seguida, dentro dessa pasta, clique com o botão direito do mouse e selecione Criar >e, em seguida, Script C#. Nomeie o script ResultsLabel.

  3. Clique duas vezes no novo script ResultsLabel para abri-lo com o Visual Studio.

  4. Dentro da classe, insira o seguinte código na classe ResultsLabel :

        using System.Collections.Generic;
        using UnityEngine;
    
        public class ResultsLabel : MonoBehaviour
        {	
            public static ResultsLabel instance;
    
            public GameObject cursor;
    
            public Transform labelPrefab;
    
            [HideInInspector]
            public Transform lastLabelPlaced;
    
            [HideInInspector]
            public TextMesh lastLabelPlacedText;
    
            private void Awake()
            {
                // allows this instance to behave like a singleton
                instance = this;
            }
    
            /// <summary>
            /// Instantiate a Label in the appropriate location relative to the Main Camera.
            /// </summary>
            public void CreateLabel()
            {
                lastLabelPlaced = Instantiate(labelPrefab, cursor.transform.position, transform.rotation);
    
                lastLabelPlacedText = lastLabelPlaced.GetComponent<TextMesh>();
    
                // Change the text of the label to show that has been placed
                // The final text will be set at a later stage
                lastLabelPlacedText.text = "Analysing...";
            }
    
            /// <summary>
            /// Set the Tags as Text of the last Label created. 
            /// </summary>
            public void SetTagsToLastLabel(Dictionary<string, float> tagsDictionary)
            {
                lastLabelPlacedText = lastLabelPlaced.GetComponent<TextMesh>();
    
                // At this point we go through all the tags received and set them as text of the label
                lastLabelPlacedText.text = "I see: \n";
    
                foreach (KeyValuePair<string, float> tag in tagsDictionary)
                {
                    lastLabelPlacedText.text += tag.Key + ", Confidence: " + tag.Value.ToString("0.00 \n");
                }    
            }
        }
    
  5. Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.

  6. De volta ao Editor do Unity, clique e arraste a classe ResultsLabel da pasta Scripts para o objeto Main Camera no Painel de Hierarquia.

  7. Clique na Câmera Principal e olhe para o Painel do Inspetor.

Você notará que, a partir do script que acabou de arrastar para a câmera, há dois campos: Cursor e Label Prefab.

  1. Arraste o objeto chamado Cursor do Painel de Hierarquia para o slot chamado Cursor, conforme mostrado na imagem abaixo.

  2. Arraste o objeto chamado LabelText da pasta Assets no painel Projeto para o slot chamado Label Prefab, conforme mostrado na imagem abaixo.

    Defina os destinos de referência no Unity.

Capítulo 6 – Criar a classe ImageCapture

A próxima classe que você criará é a classe ImageCapture . Esta classe é responsável por:

  • Capturar uma imagem usando a câmera do HoloLens e armazená-la na pasta do aplicativo.
  • Capturando gestos de toque do usuário.

Para criar essa classe:

  1. Vá para a pasta Scripts que você criou anteriormente.

  2. Clique com o botão direito do mouse dentro da pasta, Criar > Script C#. Chame o script de ImageCapture.

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

  4. Adicione os seguintes namespaces à parte superior do arquivo:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. Em seguida, adicione as seguintes variáveis dentro da classe ImageCapture, acima do método Start():

        public static ImageCapture instance; 
        public int tapsCount;
        private PhotoCapture photoCaptureObject = null;
        private GestureRecognizer recognizer;
        private bool currentlyCapturing = false;
    

A variável tapsCount armazenará o número de gestos de toque capturados do usuário. Esse número é usado na nomenclatura das imagens capturadas.

  1. O código para os métodos Awake() e Start() agora precisa ser adicionado. Eles serão chamados quando a classe for inicializada:

        private void Awake()
        {
            // Allows this instance to behave like a singleton
            instance = this;
        }
    
        void Start()
        {
            // subscribing to the HoloLens API gesture recognizer to track user gestures
            recognizer = new GestureRecognizer();
            recognizer.SetRecognizableGestures(GestureSettings.Tap);
            recognizer.Tapped += TapHandler;
            recognizer.StartCapturingGestures();
        }
    
  2. Implemente um manipulador que será chamado quando ocorrer um gesto de toque.

        /// <summary>
        /// Respond to Tap Input.
        /// </summary>
        private void TapHandler(TappedEventArgs obj)
        {
            // Only allow capturing, if not currently processing a request.
            if(currentlyCapturing == false)
            {
                currentlyCapturing = true;
    
                // increment taps count, used to name images when saving
                tapsCount++;
    
                // Create a label in world space using the ResultsLabel class
                ResultsLabel.instance.CreateLabel();
    
                // Begins the image capture and analysis procedure
                ExecuteImageCaptureAndAnalysis();
            }
        }
    

O método TapHandler() incrementa o número de toques capturados do usuário e usa a posição atual do Cursor para determinar onde posicionar um novo Label.

Em seguida, esse método chama o método ExecuteImageCaptureAndAnalysis() para iniciar a funcionalidade principal desse aplicativo.

  1. Depois que uma imagem for capturada e armazenada, os manipuladores a seguir serão chamados. Se o processo for bem-sucedido, o resultado será passado para o VisionManager (que você ainda não criou) para análise.

        /// <summary>
        /// Register the full execution of the Photo Capture. If successful, it will begin 
        /// the Image Analysis process.
        /// </summary>
        void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
        {
            // Call StopPhotoMode once the image has successfully captured
            photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
        }
    
        void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
        {
            // Dispose from the object in memory and request the image analysis 
            // to the VisionManager class
            photoCaptureObject.Dispose();
            photoCaptureObject = null;
            StartCoroutine(VisionManager.instance.AnalyseLastImageCaptured()); 
        }
    
  2. Em seguida, adicione o método que o aplicativo usa para iniciar o processo de captura de imagem e armazenar a imagem.

        /// <summary>    
        /// Begin process of Image Capturing and send To Azure     
        /// Computer Vision service.   
        /// </summary>    
        private void ExecuteImageCaptureAndAnalysis()  
        {    
            // Set the camera resolution to be the highest possible    
            Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();    
    
            Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
    
            // Begin capture process, set the image format    
            PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)    
            {    
                photoCaptureObject = captureObject;    
                CameraParameters camParameters = new CameraParameters();    
                camParameters.hologramOpacity = 0.0f;    
                camParameters.cameraResolutionWidth = targetTexture.width;    
                camParameters.cameraResolutionHeight = targetTexture.height;    
                camParameters.pixelFormat = CapturePixelFormat.BGRA32;
    
                // Capture the image from the camera and save it in the App internal folder    
                captureObject.StartPhotoModeAsync(camParameters, delegate (PhotoCapture.PhotoCaptureResult result)
                {    
                    string filename = string.Format(@"CapturedImage{0}.jpg", tapsCount);
    
                    string filePath = Path.Combine(Application.persistentDataPath, filename);
    
                    VisionManager.instance.imagePath = filePath;
    
                    photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
    
                    currentlyCapturing = false;
                });   
            });    
        }
    

Aviso

Neste ponto, você notará um erro aparecendo no painel do console do Unity Editor. Isso ocorre porque o código faz referência à classe VisionManager que você criará no próximo capítulo.

Capítulo 7 – Chamada para o Azure e Análise de Imagem

O último script que você precisa criar é a classe VisionManager .

Esta classe é responsável por:

  • Carregando a imagem mais recente capturada como uma matriz de bytes.
  • Enviar a matriz de bytes para a instância do Serviço de API da Pesquisa Visual Computacional do Azure para análise.
  • Recebendo a resposta como uma cadeia de caracteres JSON.
  • Desserializando a resposta e passando as Tags resultantes para a classe ResultsLabel .

Para criar essa classe:

  1. Clique duas vezes na pasta Scripts para abri-la.

  2. Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar > Script C#. Nomeie o script como VisionManager.

  3. Clique duas vezes no novo script para abri-lo com o Visual Studio.

  4. Atualize os namespaces para que sejam iguais aos seguintes, na parte superior da classe VisionManager :

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Na parte superior do script, dentro da classe VisionManager (acima do método Start()), agora você precisa criar duas classes que representarão a resposta JSON desserializada do Azure:

        [System.Serializable]
        public class TagData
        {
            public string name;
            public float confidence;
        }
    
        [System.Serializable]
        public class AnalysedObject
        {
            public TagData[] tags;
            public string requestId;
            public object metadata;
        }
    

    Observação

    As classes TagData e AnalysedObject precisam ter o atributo [System.Serializable] adicionado antes da declaração para poderem ser desserializadas com as bibliotecas do Unity.

  6. Na classe VisionManager, você deve adicionar as seguintes variáveis:

        public static VisionManager instance;
    
        // you must insert your service key here!    
        private string authorizationKey = "- Insert your key here -";    
        private const string ocpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key";
        private string visionAnalysisEndpoint = "https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags";   // This is where you need to update your endpoint, if you set your location to something other than west-us.
    
        internal byte[] imageBytes;
    
        internal string imagePath;
    

    Aviso

    Certifique-se de inserir sua chave de autenticação na variável authorizationKey. Você terá anotado sua chave de autenticação no início deste curso, Capítulo 1.

    Aviso

    A variável visionAnalysisEndpoint pode ser diferente daquela especificada neste exemplo. O west-us refere-se estritamente às instâncias de serviço criadas para a região Oeste dos EUA. Atualize isso com o URL do seu endpoint; aqui estão alguns exemplos de como isso pode ser:

    • Europa Ocidental: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Sudeste Asiático: https://southeastasia.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Leste da Austrália: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. O código para Awake agora precisa ser adicionado.

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. Em seguida, adicione a corrotina (com o método de fluxo estático abaixo dela), que obterá os resultados da análise da imagem capturada pela classe ImageCapture .

        /// <summary>
        /// Call the Computer Vision Service to submit the image.
        /// </summary>
        public IEnumerator AnalyseLastImageCaptured()
        {
            WWWForm webForm = new WWWForm();
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Post(visionAnalysisEndpoint, webForm))
            {
                // gets a byte array out of the saved image
                imageBytes = GetImageAsByteArray(imagePath);
                unityWebRequest.SetRequestHeader("Content-Type", "application/octet-stream");
                unityWebRequest.SetRequestHeader(ocpApimSubscriptionKeyHeader, authorizationKey);
    
                // the download handler will help receiving the analysis from Azure
                unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
    
                // the upload handler will help uploading the byte array with the request
                unityWebRequest.uploadHandler = new UploadHandlerRaw(imageBytes);
                unityWebRequest.uploadHandler.contentType = "application/octet-stream";
    
                yield return unityWebRequest.SendWebRequest();
    
                long responseCode = unityWebRequest.responseCode;     
    
                try
                {
                    string jsonResponse = null;
                    jsonResponse = unityWebRequest.downloadHandler.text;
    
                    // The response will be in Json format
                    // therefore it needs to be deserialized into the classes AnalysedObject and TagData
                    AnalysedObject analysedObject = new AnalysedObject();
                    analysedObject = JsonUtility.FromJson<AnalysedObject>(jsonResponse);
    
                    if (analysedObject.tags == null)
                    {
                        Debug.Log("analysedObject.tagData is null");
                    }
                    else
                    {
                        Dictionary<string, float> tagsDictionary = new Dictionary<string, float>();
    
                        foreach (TagData td in analysedObject.tags)
                        {
                            TagData tag = td as TagData;
                            tagsDictionary.Add(tag.name, tag.confidence);                            
                        }
    
                        ResultsLabel.instance.SetTagsToLastLabel(tagsDictionary);
                    }
                }
                catch (Exception exception)
                {
                    Debug.Log("Json exception.Message: " + exception.Message);
                }
    
                yield return null;
            }
        }
    
        /// <summary>
        /// Returns the contents of the specified file as a byte array.
        /// </summary>
        private 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);
        }  
    
  9. Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.

  10. De volta ao Editor do Unity, clique e arraste as classes VisionManager e ImageCapture da pasta Scripts para o objeto Main Camera no Painel de Hierarquia.

Capítulo 8 – Antes de construir

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 2 estão definidas corretamente.
  • Todos os scripts são anexados ao objeto Main Camera .
  • Todos os campos no Painel Inspetor de Câmera Principal são atribuídos corretamente.
  • Certifique-se de inserir sua chave de autenticação na variável authorizationKey.
  • Certifique-se de que você também tenha verificado seu endpoint em seu script do VisionManager e que ele esteja alinhado à sua região (este documento usa west-us por padrão).

Capítulo 9 – Criar a solução UWP e fazer sideload do aplicativo

Tudo o que é necessário para a seção Unity deste projeto foi concluído, então é hora de construí-lo a partir do Unity.

  1. Navegue até Arquivo > de configurações - de compilação Configurações de compilação...

  2. Na janela Configurações de Compilação, clique em Compilar.

    Criando o aplicativo do Unity

  3. Se ainda não estiver, marque Projetos C# do Unity.

  4. Clique em Compilar. O Unity abrirá uma janela do Explorador de Arquivos, onde você precisa criar e selecionar uma pasta para criar o aplicativo. Crie essa pasta agora e nomeie-a como 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 compilar (pode levar algum tempo), ele abrirá uma janela do Explorador de Arquivos no local da compilação (verifique a barra de tarefas, pois nem sempre ela aparece acima das janelas, mas notificará você sobre a adição de uma nova janela).

Capítulo 10 – Implantar no HoloLens

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.

    Implante a solução do Visual Studio.

  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.

Seu aplicativo de API de Pesquisa Visual Computacional concluído

Parabéns, você criou um aplicativo de realidade misturada que aproveita a API da Pesquisa Visual Computacional do Azure para reconhecer objetos do mundo real e exibir a confiança do que foi visto.

Resultado do laboratório

Exercícios de bônus

Exercício 1

Assim como você usou o parâmetro Tags (conforme evidenciado no endpoint usado no VisionManager), estenda o aplicativo para detectar outras informações; dê uma olhada em quais outros parâmetros você tem acesso AQUI.

Exercício 2

Exiba os dados retornados do Azure, de uma maneira mais coloquial e legível, talvez ocultando os números. Como se um bot pudesse estar falando com o usuário.