HoloLens (primera generación) y Azure 302: Computer Vision


Nota

Los tutoriales de Mixed Reality Academy se han diseñado teniendo en cuenta HoloLens (1.ª generación) y los cascos envolventes de realidad mixta. Por lo tanto, creemos que es importante conservar estos tutoriales para los desarrolladores que sigan buscando instrucciones sobre el desarrollo para esos dispositivos. Estos tutoriales no se actualizarán con los conjuntos de herramientas o las interacciones más recientes que se usan para HoloLens 2. Se mantendrán para que sigan funcionando en los dispositivos compatibles. Habrá una nueva serie de tutoriales que se publicarán en el futuro que demostrarán cómo desarrollar para HoloLens 2. Este aviso se actualizará con un vínculo a esos tutoriales cuando se publiquen.


En este curso, aprenderá a reconocer el contenido visual dentro de una imagen proporcionada mediante las funcionalidades de Azure Computer Vision en una aplicación de realidad mixta.

Los resultados del reconocimiento se mostrarán como etiquetas descriptivas. Puede usar este servicio sin necesidad de entrenar un modelo de Machine Learning. Si la implementación requiere el entrenamiento de un modelo de Machine Learning, consulte MR y Azure 302b.

resultado del laboratorio

Microsoft Computer Vision es un conjunto de API diseñadas para proporcionar a los desarrolladores procesamiento y análisis de imágenes (con información de devolución), mediante algoritmos avanzados, todo desde la nube. Los desarrolladores cargan una imagen o una dirección URL de imagen, y los algoritmos de la API de Microsoft Computer Vision analizan el contenido visual, en función de las entradas elegidas por el usuario, que luego pueden devolver información, como identificar el tipo y la calidad de una imagen, detectar caras humanas (devolver sus coordenadas) y etiquetar o clasificar imágenes. Para más información, visite la página de api de Azure Computer Vision.

Después de completar este curso, tendrá una aplicación holoLens de realidad mixta, que podrá hacer lo siguiente:

  1. Con el gesto Pulsar, la cámara de HoloLens capturará una imagen.
  2. La imagen se enviará al servicio de API de Azure Computer Vision.
  3. Los objetos reconocidos se mostrarán en un grupo de interfaz de usuario simple situado en la escena de Unity.

En la aplicación, dependerá de usted cómo integrará los resultados con el diseño. Este curso está diseñado para enseñar a integrar un servicio de Azure con el proyecto de Unity. Es su trabajo usar los conocimientos que obtiene de este curso para mejorar la aplicación de realidad mixta.

Compatibilidad con dispositivos

Curso HoloLens Cascos envolventes
Realidad mixta y Azure (302): Computer Vision ✔️ ✔️

Nota

Aunque este curso se centra principalmente en HoloLens, también puede aplicar lo que aprende en este curso para Windows Mixed Reality cascos envolventes (VR). Dado que los cascos envolventes (VR) no tienen cámaras accesibles, necesitará una cámara externa conectada a su PC. A medida que siga con el curso, verá notas sobre los cambios que es posible que deba emplear para admitir cascos envolventes (VR).

Requisitos previos

Nota:

Este tutorial está diseñado para desarrolladores que tienen experiencia básica con Unity y C#. Tenga en cuenta también que los requisitos previos y las instrucciones escritas dentro de este documento representan lo que se ha probado y comprobado en el momento de la escritura (mayo de 2018). Puede usar el software más reciente, como se muestra en el artículo sobre la instalación de las herramientas , aunque no debe asumirse que la información de este curso coincidirá perfectamente con lo que encontrará en el software más reciente que lo que se muestra a continuación.

Se recomienda el siguiente hardware y software para este curso:

Antes de empezar

  1. Para evitar encontrar problemas al compilar este proyecto, se recomienda encarecidamente crear el proyecto mencionado en este tutorial en una carpeta raíz o casi raíz (las rutas de acceso de carpetas largas pueden causar problemas en tiempo de compilación).
  2. Configure y pruebe holoLens. Si necesita soporte técnico para configurar HoloLens, asegúrese de visitar el artículo configuración de HoloLens.
  3. Es una buena idea realizar la calibración y la optimización del sensor al empezar a desarrollar una nueva aplicación holoLens (a veces puede ayudar a realizar esas tareas para cada usuario).

Para obtener ayuda sobre calibración, siga este vínculo al artículo Calibración de HoloLens.

Para obtener ayuda sobre la optimización de sensores, siga este vínculo al artículo Optimización de sensores de HoloLens.

Capítulo 1: Azure Portal

Para usar el servicio de API de Computer Vision en Azure, deberá configurar una instancia del servicio para que esté disponible para la aplicación.

  1. En primer lugar, inicie sesión en Azure Portal.

    Nota

    Si aún no tiene una cuenta de Azure, deberá crear una. Si sigue este tutorial en una situación de clase o laboratorio, pida a su instructor o a uno de los proctores que le ayuden a configurar la nueva cuenta.

  2. Una vez que haya iniciado sesión, haga clic en Nuevo en la esquina superior izquierda y busque Computer Vision API y haga clic en Entrar.

    Creación de un nuevo recurso en Azure

    Nota

    Es posible que la palabra New se haya reemplazado por Create a resource (Crear un recurso) en portales más recientes.

  3. La nueva página proporcionará una descripción del servicio de API de Computer Vision. En la parte inferior izquierda de esta página, seleccione el botón Crear para crear una asociación con este servicio.

    Acerca del servicio computer vision API

  4. Una vez que haya hecho clic en Crear:

    1. Inserte el nombre deseado para esta instancia de servicio.

    2. Seleccione una opción en Suscripción.

    3. Seleccione el plan de tarifa adecuado para usted, si es la primera vez que crea un servicio de API de Computer Vision, debe estar disponible un nivel gratuito (denominado F0).

    4. Elija un grupo de recursos o cree uno nuevo. Un grupo de recursos proporciona una manera de supervisar, controlar el acceso, aprovisionar y administrar la facturación de una colección de recursos de Azure. Se recomienda mantener todos los servicios de Azure asociados a un único proyecto (por ejemplo, estos laboratorios) en un grupo de recursos común).

      Si desea obtener más información sobre los grupos de recursos de Azure, visite el artículo sobre el grupo de recursos.

    5. Determine la ubicación del grupo de recursos (si va a crear un nuevo grupo de recursos). La ubicación ideal sería en la región donde se ejecutaría la aplicación. Algunos recursos de Azure solo están disponibles en determinadas regiones.

    6. También deberá confirmar que ha comprendido los Términos y Condiciones aplicados a este Servicio.

    7. Haga clic en Crear.

      Información de creación del servicio

  5. Una vez que haya hecho clic en Crear, tendrá que esperar a que se cree el servicio, esto puede tardar un minuto.

  6. Una notificación aparecerá en el portal una vez creada la instancia de servicio.

    Consulte la nueva notificación para el nuevo servicio.

  7. Haga clic en la notificación para explorar la nueva instancia de servicio.

    Seleccione el botón Ir al recurso.

  8. Haga clic en el botón Ir al recurso en la notificación para explorar la nueva instancia de servicio. Se le llevará a la nueva instancia del servicio de API de Computer Vision.

    Nueva imagen del servicio de API de Computer Vision

  9. En este tutorial, la aplicación tendrá que realizar llamadas al servicio, que se realiza mediante el uso de la clave de suscripción del servicio.

  10. En la página Inicio rápido, del servicio de API de Computer Vision, vaya al primer paso, Grabe las claves y haga clic en Claves (también puede hacerlo haciendo clic en el hipervínculo azul Claves, que se encuentra en el menú de navegación de servicios, indicado por el icono de clave). Esto revelará las claves de servicio.

  11. Realice una copia de una de las claves mostradas, ya que lo necesitará más adelante en el proyecto.

  12. Volver a la página Inicio rápido y, desde allí, capture el punto de conexión. Tenga en cuenta que el suyo puede ser diferente, en función de la región (que, si es así, deberá realizar un cambio en el código más adelante). Realice una copia de este punto de conexión para usarlo más adelante:

    El nuevo servicio de API de Computer Vision

    Sugerencia

    Puede comprobar cuáles son los distintos puntos de conexión AQUÍ.

Capítulo 2: Configuración del proyecto de Unity

A continuación se muestra una configuración típica para desarrollar con realidad mixta y, como tal, es una buena plantilla para otros proyectos.

  1. Abra Unity y haga clic en Nuevo.

    Inicie el nuevo proyecto de Unity.

  2. Ahora tendrá que proporcionar un nombre de proyecto de Unity. Inserte MR_ComputerVision. Asegúrese de que el tipo de proyecto está establecido en 3D. Establezca la ubicación en un lugar adecuado para usted (recuerde, más cerca de los directorios raíz es mejor). A continuación, haga clic en Crear proyecto.

    Proporcione detalles para el nuevo proyecto de Unity.

  3. Con Unity abierto, vale la pena comprobar que el Editor de scripts predeterminado está establecido en Visual Studio. Vaya a Editar > preferencias y, a continuación, en la nueva ventana, vaya a Herramientas externas. Cambie el Editor de scripts externos a Visual Studio 2017. Cierre la ventana Preferencias.

    Actualice la preferencia del editor de scripts.

  4. A continuación, vaya a Configuración de > compilación de archivos y seleccione Plataforma universal de Windows y haga clic en el botón Cambiar plataforma para aplicar la selección.

    Ventana Configuración de compilación, cambie la plataforma a UWP.

  5. Mientras sigue en configuración de compilación de archivos > y asegúrese de que:

    1. El dispositivo de destino se establece en HoloLens.

      Para los cascos envolventes, establezca Dispositivo de destino en Cualquier dispositivo.

    2. El tipo de compilación se establece en D3D.

    3. El SDK se establece en Latest installed (Más reciente instalado)

    4. La versión de Visual Studio se establece en Latest installed (Versión más reciente instalada)

    5. Build and Run (Compilación y ejecución ) está establecido en Local Machine (Máquina local).

    6. Guarde la escena y agréguela a la compilación.

      1. Para ello, seleccione Agregar escenas abiertas. Aparecerá una ventana de guardado.

        Haga clic en el botón Agregar escenas abiertas.

      2. Cree una nueva carpeta para esto y cualquier escena futura y, a continuación, seleccione el botón Nueva carpeta para crear una nueva carpeta, asígnela el nombre Escenas.

        Creación de una carpeta de scripts

      3. Abra la carpeta Escenas recién creada y, a continuación, en el campo Nombre de archivo: texto, escriba MR_ComputerVisionScene y haga clic en Guardar.

        Asigne un nombre a la nueva escena.

        Tenga en cuenta que debe guardar las escenas de Unity en la carpeta Assets , ya que deben estar asociadas al proyecto de Unity. La creación de la carpeta de escenas (y otras carpetas similares) es una forma típica de estructurar un proyecto de Unity.

    7. La configuración restante, en Configuración de compilación, debe dejarse como predeterminada por ahora.

  6. En la ventana Configuración de compilación, haga clic en el botón Configuración del reproductor ; se abrirá el panel relacionado en el espacio donde se encuentra el Inspector .

    Abra la configuración del reproductor.

  7. En este panel, es necesario comprobar algunas opciones de configuración:

    1. En la pestaña Otras configuraciones :

      1. La versión del entorno de ejecución de scripting debe ser estable (equivalente a .NET 3.5).

      2. El back-end de scripting debe ser .NET

      3. El nivel de compatibilidad de API debe ser .NET 4.6

        Actualice otras opciones de configuración.

    2. En la pestaña Configuración de publicación, en Funcionalidades, active:

      1. InternetClient

      2. Cámara web

        Actualización de la configuración de publicación.

    3. Más abajo en el panel, en Configuración de XR (que se encuentra a continuación de Configuración de publicación), marque Virtual Reality Supported (Compatible con Realidad virtual), asegúrese de que se agrega el SDK de Windows Mixed Reality.

      Actualice la configuración de X R.

  8. De nuevo en Build SettingsUnity C# Projects ya no está atenuado; marque la casilla situada junto a esto.

  9. Cierre la ventana Build Settings (Configuración de compilación).

  10. Guarde la escena y el proyecto (ARCHIVO > SAVE SCENE /FILE > SAVE PROJECT).

Capítulo 3: Configuración de la cámara principal

Importante

Si desea omitir el componente Set up de Unity de este curso y continuar directamente en el código, no dude en descargar este paquete .unitypackage, importarlo en el proyecto como paquete personalizado y continuar desde el capítulo 5.

  1. En el Panel de jerarquía, seleccione la Cámara principal.

  2. Una vez seleccionado, podrá ver todos los componentes de la cámara principal en el panel inspector.

    1. El objeto Camera debe denominarse Cámara principal (tenga en cuenta la ortografía).

    2. La etiqueta de cámara principal debe establecerse en MainCamera (tenga en cuenta la ortografía).

    3. Asegúrese de que la posición de transformación está establecida en 0, 0, 0

    4. Establezca Borrar marcas en Color sólido (omita esto para cascos envolventes).

    5. Establezca el color de fondo del componente de cámara en Negro, Alfa 0 (código hexadecimal: #00000000) (omita esto para casco envolvente).

      Actualizar componentes de cámara.

  3. A continuación, tendrá que crear un objeto "Cursor" simple adjunto a la cámara principal, que le ayudará a colocar la salida del análisis de imágenes cuando se ejecuta la aplicación. Este cursor determinará el punto central del foco de la cámara.

Para crear el cursor:

  1. En el Panel de jerarquía, haga clic con el botón derecho en la cámara principal. En Objeto 3D, haga clic en Sphere.

    Seleccione el objeto cursor.

  2. Cambie el nombre de Sphere a Cursor (haga doble clic en el objeto Cursor o presione el botón de teclado "F2" con el objeto seleccionado) y asegúrese de que se encuentra como elemento secundario de la cámara principal.

  3. En el Panel jerarquía, haga clic con el botón izquierdo en el cursor. Con el cursor seleccionado, ajuste las siguientes variables en el Panel inspector:

    1. Establezca la posición de transformación en 0, 0, 5

    2. Establezca la escala en 0.02, 0.02, 0.02

      Actualice la posición y la escala de transformación.

Capítulo 4: Configuración del sistema de etiquetas

Una vez que haya capturado una imagen con la cámara de HoloLens, esa imagen se enviará a la instancia del servicio de API de Azure Computer Vision para su análisis.

Los resultados de ese análisis serán una lista de objetos reconocidos denominados Tags.

Usará etiquetas (como texto 3D en el espacio mundial) para mostrar estas etiquetas en la ubicación en la que se tomó la foto.

En los pasos siguientes se muestra cómo configurar el objeto Label .

  1. Haga clic con el botón derecho en cualquier parte del Panel de jerarquía (la ubicación no importa en este momento), en Objeto 3D, agregue un texto 3D. Asígnelo el nombre LabelText.

    Crea un objeto 3D Text.

  2. En el Panel jerarquía, haga clic con el botón izquierdo en LabelText. Con labelText seleccionado, ajuste las siguientes variables en el Panel inspector:

    1. Establezca la posición en 0,0,0
    2. Establezca la escala en 0.01, 0.01, 0.01
    3. En el componente Text Mesh:
    4. Reemplace todo el texto de Text por "..."
    5. Establecer el delimitador en centro central
    6. Establecer la alineación en El centro
    7. Establezca el tamaño de tabulación en 4.
    8. Establezca el tamaño de fuente en 50.
    9. Establezca el coloren #FFFFFFFF

    Componente de texto

  3. Arrastre LabelText desde el Panel de jerarquía, a la carpeta de recursos, en el panel proyecto. Esto hará que LabelText sea un objeto prefabricado para que se pueda crear una instancia en el código.

    Cree un objeto prefabricado del objeto LabelText.

  4. Debe eliminar LabelText del Panel de jerarquía para que no se muestre en la escena de apertura. Como ahora es un objeto prefabricado, al que llamará para instancias individuales de la carpeta Assets, no es necesario mantenerlo dentro de la escena.

  5. La estructura de objetos final del Panel de jerarquía debe ser similar a la que se muestra en la imagen siguiente:

    Estructura final del panel de jerarquía.

Capítulo 5: Crear la clase ResultsLabel

El primer script que necesita crear es la clase ResultsLabel , que es responsable de lo siguiente:

  • Crear las etiquetas en el espacio mundial adecuado, en relación con la posición de la cámara.
  • Mostrar las etiquetas de Image Anaysis.

Para crear esta clase:

  1. Haga clic con el botón derecho en el Panel del proyecto y, a continuación, en Crear > carpeta. Asigne un nombre a la carpeta Scripts.

    Cree la carpeta scripts.

  2. Con la carpeta Scripts creada, haga doble clic en ella para abrirla. A continuación, dentro de esa carpeta, haga clic con el botón derecho y seleccione Crear > y, después , Script de C#. Asigne al script el nombre ResultsLabel.

  3. Haga doble clic en el nuevo script ResultsLabel para abrirlo con Visual Studio.

  4. Dentro de la clase, inserte el código siguiente en la clase 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. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

  6. De nuevo en el Editor de Unity, haga clic y arrastre la clase ResultsLabel desde la carpeta Scripts al objeto Cámara principal en el Panel de jerarquía.

  7. Haga clic en la cámara principal y mire el panel inspector.

Observará que en el script que acaba de arrastrar a la cámara, hay dos campos: Cursor y Label Prefab.

  1. Arrastre el objeto denominado Cursor desde el Panel de jerarquía hasta la ranura denominada Cursor, como se muestra en la imagen siguiente.

  2. Arrastre el objeto denominado LabelText desde la carpeta Assets del Panel de proyectos hasta la ranura denominada Label Prefab, como se muestra en la imagen siguiente.

    Establezca los destinos de referencia en Unity.

Capítulo 6: Creación de la clase ImageCapture

La clase siguiente que va a crear es la clase ImageCapture . Esta clase es responsable de:

  • Capturar una imagen mediante la cámara holoLens y almacenarla en la carpeta de la aplicación.
  • Captura de gestos de pulsación del usuario.

Para crear esta clase:

  1. Vaya a la carpeta Scripts que creó anteriormente.

  2. Haga clic con el botón derecho dentro de la carpeta Crear > script de C#. Llame al script ImageCapture.

  3. Haga doble clic en el nuevo script ImageCapture para abrirlo con Visual Studio.

  4. Agregue los siguientes espacios de nombres a la parte superior del archivo:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. A continuación, agregue las siguientes variables dentro de la clase ImageCapture, encima del método Start():

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

La variable tapsCount almacenará el número de gestos de pulsación capturados por el usuario. Este número se usa en la nomenclatura de las imágenes capturadas.

  1. Ahora es necesario agregar código para los métodos Awake() e Start(). Se llamará a estos cuando se inicialice la clase :

        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 un controlador al que se llamará cuando se produzca un gesto de pulsar.

        /// <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();
            }
        }
    

El método TapHandler() incrementa el número de pulsaciones capturadas por el usuario y usa la posición actual del cursor para determinar dónde colocar una nueva etiqueta.

A continuación, este método llama al método ExecuteImageCaptureAndAnalysis() para comenzar la funcionalidad principal de esta aplicación.

  1. Una vez que se ha capturado y almacenado una imagen, se llamará a los siguientes controladores. Si el proceso se realiza correctamente, el resultado se pasa al VisionManager (que aún no se va a crear) para su análisis.

        /// <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. A continuación, agregue el método que usa la aplicación para iniciar el proceso de captura de imágenes y almacenar la imagen.

        /// <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;
                });   
            });    
        }
    

Advertencia

En este momento, observará un error que aparece en el Panel de consola del Editor de Unity. Esto se debe a que el código hace referencia a la clase VisionManager que creará en el siguiente capítulo.

Capítulo 7: Llamada a Azure y análisis de imágenes

El último script que necesita crear es la clase VisionManager .

Esta clase es responsable de:

  • Cargando la imagen más reciente capturada como una matriz de bytes.
  • Envío de la matriz de bytes a la instancia del servicio de API de Azure Computer Vision para su análisis.
  • Recepción de la respuesta como una cadena JSON.
  • Deserializar la respuesta y pasar las etiquetas resultantes a la clase ResultsLabel .

Para crear esta clase:

  1. Haga doble clic en la carpeta Scripts para abrirla.

  2. Haga clic con el botón derecho en la carpeta Scripts y haga clic en Crear > script de C#. Asigne al script el nombre VisionManager.

  3. Haga doble clic en el nuevo script para abrirlo con Visual Studio.

  4. Actualice los espacios de nombres para que sean los mismos que los siguientes, en la parte superior de la clase VisionManager :

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. En la parte superior del script, dentro de la clase VisionManager (encima del método Start(), ahora debe crear dos clases que representarán la respuesta JSON deserializada de 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;
        }
    

    Nota

    Las clases TagData y AnalysedObject deben tener agregado el atributo [System.Serializable] antes de que la declaración pueda deserializarse con las bibliotecas de Unity.

  6. En la clase VisionManager, debe agregar las siguientes variables:

        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;
    

    Advertencia

    Asegúrese de insertar la clave de autenticación en la variable authorizationKey . Habrá anotado su clave de autenticación al principio de este curso, capítulo 1.

    Advertencia

    La variable visionAnalysisEndpoint puede diferir de la especificada en este ejemplo. El oeste de ee. UU . hace referencia estrictamente a las instancias de servicio creadas para la región Oeste de EE. UU. Actualícelo con la dirección URL del punto de conexión; estos son algunos ejemplos de lo que podría tener este aspecto:

    • Oeste de Europa: 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
    • Este de Australia: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. Ahora es necesario agregar código para Awake.

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. A continuación, agregue la corrutina (con el método de secuencia estática debajo), que obtendrá los resultados del análisis de la imagen capturada por la clase 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. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

  10. De nuevo en el Editor de Unity, haga clic y arrastre las clases VisionManager e ImageCapture desde la carpeta Scripts al objeto Cámara principal en el Panel de jerarquía.

Capítulo 8: Antes de la construcción

Para realizar una prueba exhaustiva de la aplicación, deberá transferirla localmente a HoloLens. Antes de hacerlo, asegúrese de que:

  • Todas las configuraciones mencionadas en el capítulo 2 se establecen correctamente.
  • Todos los scripts se adjuntan al objeto Cámara principal .
  • Todos los campos del Panel inspector de cámara principal se asignan correctamente.
  • Asegúrese de insertar la clave de autenticación en la variable authorizationKey .
  • Asegúrese de que también ha comprobado el punto de conexión en el script de VisionManager y que se alinea con su región (este documento usa west-us de forma predeterminada).

Capítulo 9: Compilar la solución para UWP y transferir localmente la aplicación

Todo lo necesario para la sección Unity de este proyecto se ha completado, por lo que es el momento de compilarlo desde Unity.

  1. Vaya a Build SettingsFile Build Settings... (Configuración de compilación del archivo > de configuración de compilación). -

  2. En la ventana Configuración de compilación , haga clic en Compilar.

    Creación de la aplicación desde Unity

  3. Si aún no es así, marque Proyectos de C# de Unity.

  4. Haga clic en Generar. Unity iniciará una ventana de Explorador de archivos, donde debe crear y, a continuación, seleccionará una carpeta en la que compilará la aplicación. Cree esa carpeta ahora y asígnela el nombre App. A continuación, con la carpeta Aplicación seleccionada, presione Seleccionar carpeta.

  5. Unity comenzará a compilar el proyecto en la carpeta Aplicación .

  6. Una vez que Unity haya terminado de compilar (es posible que tarde algún tiempo), abrirá una ventana de Explorador de archivos en la ubicación de la compilación (compruebe la barra de tareas, ya que puede que no siempre aparezca encima de las ventanas, pero le notificará la adición de una nueva ventana).

Capítulo 10: Implementación en HoloLens

Para implementar en HoloLens:

  1. Necesitará la dirección IP de HoloLens (para implementación remota) y para asegurarse de que HoloLens está en modo de desarrollador. Para ello, siga estos pasos:

    1. Mientras llevas tu HoloLens, abre la configuración.
    2. Vaya a Network & Internet > Wi-Fi > Opciones avanzadas.
    3. Anote la dirección IPv4 .
    4. A continuación, vuelva a Configuración y, después, a Actualizar & Seguridad > para desarrolladores.
    5. Establezca el modo de desarrollador activado.
  2. Vaya a la nueva compilación de Unity (la carpeta Aplicación ) y abra el archivo de solución con Visual Studio.

  3. En Configuración de la solución, seleccione Depurar.

  4. En la Plataforma de soluciones, seleccione x86, Máquina remota.

    Implemente la solución desde Visual Studio.

  5. Vaya al menú Compilar y haga clic en Implementar solución para transferir localmente la aplicación a HoloLens.

  6. La aplicación ahora debería aparecer en la lista de aplicaciones instaladas en HoloLens, lista para iniciarse.

Nota

Para realizar la implementación en cascos envolventes, establezca la Plataforma de soluciones en Equipo local y establezca la configuración en Depurar, con x86 como plataforma. A continuación, implemente en la máquina local mediante el menú Compilar y seleccione Implementar solución.

La aplicación de API de Computer Vision finalizada

Enhorabuena, ha creado una aplicación de realidad mixta que aprovecha la API de Azure Computer Vision para reconocer objetos reales y mostrar la confianza de lo que se ha visto.

resultado del laboratorio

Ejercicios extra

Ejercicio 1

Al igual que ha usado el parámetro Tags (como se ha evidenciado en el punto de conexión usado en visionManager), extienda la aplicación para detectar otra información; examine qué otros parámetros tiene acceso a HERE.

Ejercicio 2

Muestre los datos de Azure devueltos, de una manera más conversacional y legible, tal vez ocultando los números. Como si un bot pudiera estar hablando con el usuario.