HoloLens (prima generazione) e Azure 302: Visione artificiale


Nota

Le esercitazioni di Mixed Reality Academy sono state progettate in base a HoloLens (prima generazione) e ai visori VR immersive di realtà mista. Pertanto, riteniamo importante lasciarle a disposizione degli sviluppatori a cui serve ancora materiale sussidiario per lo sviluppo di questi dispositivi. Queste esercitazioni non verranno aggiornate con i set di strumenti o le interazioni più recenti usati per HoloLens 2. Rimarranno invariate per consentire di continuare a lavorare sui dispositivi supportati. Ci sarà una nuova serie di esercitazioni che verranno pubblicate in futuro che dimostreranno come sviluppare per HoloLens 2. Questo avviso verrà aggiornato con un collegamento a tali esercitazioni quando vengono pubblicate.


In questo corso si apprenderà come riconoscere il contenuto visivo all'interno di un'immagine fornita, usando le funzionalità di Azure Visione artificiale in un'applicazione di realtà mista.

I risultati del riconoscimento verranno visualizzati come tag descrittivi. È possibile usare questo servizio senza dover eseguire il training di un modello di Machine Learning. Se l'implementazione richiede il training di un modello di Machine Learning, vedere MR e Azure 302b.

risultato del lab

Microsoft Visione artificiale è un set di API progettate per offrire agli sviluppatori l'elaborazione e l'analisi delle immagini (con informazioni restituite), usando algoritmi avanzati, tutti dal cloud. Gli sviluppatori caricano un'immagine o un URL di immagine e gli algoritmi dell'API Microsoft Visione artificiale analizzano il contenuto visivo, in base agli input scelti dall'utente, che possono quindi restituire informazioni, tra cui, identificare il tipo e la qualità di un'immagine, rilevare i visi umani (restituendo le coordinate) e contrassegnare o categorizzare le immagini. Per altre informazioni, visitare la pagina api di Azure Visione artificiale.

Dopo aver completato questo corso, si avrà un'applicazione HoloLens di realtà mista, che sarà in grado di eseguire le operazioni seguenti:

  1. Usando il movimento Tap, la fotocamera di HoloLens acquisirà un'immagine.
  2. L'immagine verrà inviata al servizio API Visione artificiale di Azure.
  3. Gli oggetti riconosciuti verranno elencati in un semplice gruppo di interfaccia utente posizionato nella scena unity.

Nell'applicazione spetta all'utente come integrare i risultati con la progettazione. Questo corso è progettato per illustrare come integrare un servizio di Azure con il progetto Unity. È il tuo compito usare le conoscenze acquisite da questo corso per migliorare l'applicazione di realtà mista.

Supporto di dispositivi

Corso HoloLens Visori VR immersive
MR e Azure 302: Visione artificiale ✔️ ✔️

Nota

Anche se questo corso è incentrato principalmente su HoloLens, puoi anche applicare ciò che impari in questo corso ai visori VR immersive di Windows Realtà mista. Poiché i visori VR immersive non hanno fotocamere accessibili, è necessaria una fotocamera esterna connessa al PC. Mentre segui il corso, vedrai le note su eventuali modifiche che potresti dover usare per supportare visori VR immersive.

Prerequisiti

Nota

Questa esercitazione è progettata per gli sviluppatori che hanno esperienza di base con Unity e C#. Tenere presente anche che i prerequisiti e le istruzioni scritte all'interno di questo documento rappresentano ciò che è stato testato e verificato al momento della scrittura (maggio 2018). Sei libero di usare il software più recente, come elencato all'interno dell'articolo installare gli strumenti , anche se non si deve presumere che le informazioni in questo corso corrispondano perfettamente a ciò che troverai nel software più recente rispetto a quello elencato di seguito.

Per questo corso è consigliabile usare l'hardware e il software seguenti:

Prima di iniziare

  1. Per evitare di riscontrare problemi durante la compilazione di questo progetto, è consigliabile creare il progetto menzionato in questa esercitazione in una cartella radice o quasi radice (i percorsi delle cartelle lunghe possono causare problemi in fase di compilazione).
  2. Configurare e testare HoloLens. Se hai bisogno di supporto per configurare HoloLens, assicurati di visitare l'articolo configurazione di HoloLens.
  3. È consigliabile eseguire la calibrazione e l'ottimizzazione dei sensori quando si inizia a sviluppare una nuova app HoloLens (a volte può essere utile per eseguire tali attività per ogni utente).

Per informazioni su Calibrazione, seguire questo collegamento all'articolo Calibrazione di HoloLens.

Per informazioni sull'ottimizzazione dei sensori, seguire questo collegamento all'articolo Ottimizzazione del sensore HoloLens.

Capitolo 1: Portale di Azure

Per usare il servizio API Visione artificiale in Azure, è necessario configurare un'istanza del servizio da rendere disponibile per l'applicazione.

  1. Accedere prima di tutto al portale di Azure.

    Nota

    Se non si ha già un account Azure, è necessario crearne uno. Se si segue questa esercitazione in una classe o in una situazione di laboratorio, chiedere all'insegnante o a uno dei prottori di assistenza per configurare il nuovo account.

  2. Dopo aver eseguito l'accesso, fare clic su Nuovo nell'angolo superiore sinistro e cercare Visione artificiale API e fare clic su INVIO.

    Creare una nuova risorsa in Azure

    Nota

    La parola New potrebbe essere stata sostituita con Crea una risorsa, nei portali più recenti.

  3. La nuova pagina fornirà una descrizione del servizio API Visione artificiale. Nella parte inferiore sinistra di questa pagina selezionare il pulsante Crea per creare un'associazione con questo servizio.

    Informazioni sul servizio API Visione artificiale

  4. Dopo aver fatto clic su Crea:

    1. Inserire il nome desiderato per questa istanza del servizio.

    2. Selezionare una Sottoscrizione.

    3. Selezionare il piano tariffario appropriato, se questa è la prima volta che si crea un servizio API Visione artificiale, sarà disponibile un livello gratuito (denominato F0).

    4. Scegliere un gruppo di risorse o crearne uno nuovo. Un gruppo di risorse consente di monitorare, controllare l'accesso, effettuare il provisioning e gestire la fatturazione per una raccolta di asset di Azure. È consigliabile mantenere tutti i servizi di Azure associati a un singolo progetto (ad esempio, questi lab) in un gruppo di risorse comune.

      Per altre informazioni sui gruppi di risorse di Azure, vedere l'articolo relativo al gruppo di risorse.

    5. Determinare la località per il gruppo di risorse (se si sta creando un nuovo gruppo di risorse). La posizione si trova idealmente nell'area in cui verrà eseguita l'applicazione. Alcuni asset di Azure sono disponibili solo in determinate aree.

    6. Sarà anche necessario verificare di aver compreso le condizioni e le condizioni applicate al servizio.

    7. Cliccare su Crea.

      Informazioni sulla creazione del servizio

  5. Dopo aver fatto clic su Crea, è necessario attendere che il servizio venga creato, l'operazione potrebbe richiedere un minuto.

  6. Una notifica verrà visualizzata nel portale dopo la creazione dell'istanza del servizio.

    Visualizzare la nuova notifica per il nuovo servizio

  7. Fare clic sulla notifica per esplorare la nuova istanza del servizio.

    Selezionare il pulsante Vai alla risorsa.

  8. Fare clic sul pulsante Vai alla risorsa nella notifica per esplorare la nuova istanza del servizio. Verrà visualizzata la nuova istanza del servizio API Visione artificiale.

    Nuova immagine del servizio API Visione artificiale

  9. In questa esercitazione, l'applicazione dovrà effettuare chiamate al servizio, che viene eseguita usando la chiave di sottoscrizione del servizio.

  10. Nella pagina Avvio rapido del servizio API di Visione artificiale passare al primo passaggio, Afferrare le chiavi e fare clic su Chiavi.È anche possibile ottenere questo risultato facendo clic sul collegamento ipertestuale blu, che si trova nel menu di spostamento dei servizi, indicato dall'icona della chiave. Verranno visualizzate le chiavi del servizio.

  11. Prendere una copia di una delle chiavi visualizzate, perché sarà necessario più avanti nel progetto.

  12. Tornare alla pagina Avvio rapido e, da questa posizione, recuperare l'endpoint. Tenere presente che i dati potrebbero essere diversi, a seconda dell'area geografica( in caso affermativo, sarà necessario apportare una modifica al codice in un secondo momento). Eseguire una copia di questo endpoint per usarlo in un secondo momento:

    Il nuovo servizio API Visione artificiale

    Suggerimento

    È possibile controllare quali sono i vari endpoint QUI.

Capitolo 2: Configurare il progetto Unity

Di seguito è riportata una configurazione tipica per lo sviluppo con la realtà mista e, di conseguenza, è un modello valido per altri progetti.

  1. Aprire Unity e fare clic su Nuovo.

    Avviare un nuovo progetto Unity.

  2. Sarà ora necessario specificare un nome di progetto Unity. Inserisci MR_ComputerVision. Assicurarsi che il tipo di progetto sia impostato su 3D. Impostare La posizione su un punto appropriato per l'utente (tenere presente che più vicino alle directory radice è preferibile). Fare quindi clic su Crea progetto.

    Specificare i dettagli per il nuovo progetto Unity.

  3. Con Unity aperto, vale la pena verificare che l'editor di script predefinito sia impostato su Visual Studio. Passare a Modifica > preferenze e quindi dalla nuova finestra passare a Strumenti esterni. Modificare l'editor di script esterni in Visual Studio 2017. Chiudere la finestra Preferenze .

    Aggiornare le preferenze dell'editor di script.

  4. Passare quindi a Impostazioni compilazione file > e selezionare piattaforma UWP (Universal Windows Platform), quindi fare clic sul pulsante Cambia piattaforma per applicare la selezione.

    Finestra Impostazioni di compilazione, passare dalla piattaforma alla piattaforma UWP.

  5. Mentre ancora in Impostazioni di compilazione file > e assicurarsi che:

    1. Il dispositivo di destinazione è impostato su HoloLens

      Per i visori VR immersive, impostare Dispositivo di destinazione su Qualsiasi dispositivo.

    2. Il tipo di compilazione è impostato su D3D

    3. L'SDK è impostato su Latest installed (Versione più recente installata)

    4. La versione di Visual Studio è impostata su Versione più recente installata

    5. Compilazione ed esecuzione è impostata su Computer locale

    6. Salvare la scena e aggiungerla alla compilazione.

      1. A tale scopo, selezionare Aggiungi scene aperte. Verrà visualizzata una finestra di salvataggio.

        Fare clic sul pulsante Aggiungi scene aperte

      2. Creare una nuova cartella per questa cartella e qualsiasi scena futura, quindi selezionare il pulsante Nuova cartella per creare una nuova cartella, denominarla Scene.

        Creare una nuova cartella di script

      3. Aprire la cartella Scene appena creata, quindi nel campo Nome file: testo digitare MR_ComputerVisionScene, quindi fare clic su Salva.

        Assegnare un nome alla nuova scena.

        Tenere presente che è necessario salvare le scene di Unity all'interno della cartella Assets , perché devono essere associate al progetto Unity. La creazione della cartella scene (e altre cartelle simili) è un modo tipico di strutturare un progetto Unity.

    7. Le impostazioni rimanenti, in Impostazioni di compilazione, devono essere lasciate come predefinite per il momento.

  6. Nella finestra Impostazioni di compilazione fare clic sul pulsante Impostazioni lettore per aprire il pannello correlato nello spazio in cui si trova il controllo.

    Aprire le impostazioni del lettore.

  7. In questo pannello è necessario verificare alcune impostazioni:

    1. Nella scheda Altre impostazioni :

      1. La versione del runtime di scripting deve essere stabile (equivalente a .NET 3.5).

      2. Il back-end di scripting deve essere .NET

      3. Il livello di compatibilità api deve essere .NET 4.6

        Aggiornare altre impostazioni.

    2. Nella scheda Impostazioni di pubblicazione, in Funzionalità selezionare:

      1. InternetClient

      2. Webcam

        Aggiornamento delle impostazioni di pubblicazione.

    3. Più avanti nel pannello, in Impostazioni XR (disponibili sotto Impostazioni di pubblicazione), selezionare Realtà virtuale supportata, assicurarsi che Windows Realtà mista SDK sia stato aggiunto.

      Aggiornare le impostazioni X R.

  8. Tornare in Build Settings Unity C# Projects (Impostazioni di compilazione) I progetti C# non sono più disattivati. Selezionare la casella di controllo accanto a questa opzione.

  9. Chiudere la finestra Build Settings (Impostazioni di compilazione).

  10. Salvare la scena e il progetto (FILE > SAVE SCENE/FILE > SAVE PROJECT).

Capitolo 3 - Configurazione della fotocamera principale

Importante

Se si vuole ignorare il componente Di configurazione di Unity di questo corso e continuare direttamente nel codice, è possibile scaricare questo pacchetto unitypackage, importarlo nel progetto come pacchetto personalizzato e quindi continuare dal capitolo 5.

  1. Nel pannello Gerarchia selezionare la fotocamera principale.

  2. Dopo aver selezionato, sarà possibile visualizzare tutti i componenti della fotocamera principale nel pannello di controllo.

    1. L'oggetto Camera deve essere denominato Fotocamera principale (si noti l'ortografia!)

    2. Il tag della fotocamera principale deve essere impostato su MainCamera (si noti l'ortografia!)

    3. Assicurarsi che la posizione di trasformazione sia impostata su 0, 0, 0

    4. Impostare Clear Flags (Cancella flag) su Solid Color (ignorare questo valore per il visore VR immersivo).

    5. Impostare il colore di sfondo del componente fotocamera su Nero, Alfa 0 (codice esadecimale: #00000000) (ignorarlo per il visore VR immersivo).

      Aggiornare i componenti della fotocamera.

  3. Successivamente, sarà necessario creare un semplice oggetto "Cursore" collegato alla fotocamera principale, che consentirà di posizionare l'output dell'analisi delle immagini quando l'applicazione è in esecuzione. Questo cursore determinerà il punto centrale dello stato attivo della fotocamera.

Per creare il cursore:

  1. Nel pannello Gerarchia fare clic con il pulsante destro del mouse sulla fotocamera principale. In Oggetto 3D fare clic su Sphere.

    Selezionare l'oggetto cursore.

  2. Rinominare Sphere in Cursor (fare doppio clic sull'oggetto Cursor o premere il pulsante della tastiera "F2" con l'oggetto selezionato) e assicurarsi che si trovi come figlio della fotocamera principale.

  3. Nel pannello Gerarchia fare clic con il pulsante sinistro del mouse sul cursore. Con il cursore selezionato, modificare le variabili seguenti nel pannello di controllo:

    1. Impostare La posizione di trasformazione su 0, 0, 5

    2. Impostare Scale su 0.02, 0.02, 0.02

      Aggiornare la posizione e la scala della trasformazione.

Capitolo 4 : Configurare il sistema label

Dopo aver acquisito un'immagine con la fotocamera holoLens, l'immagine verrà inviata all'istanza del servizio API di Azure Visione artificiale per l'analisi.

I risultati di tale analisi saranno un elenco di oggetti riconosciuti denominati Tag.

Userai Etichette (come testo 3D nello spazio globale) per visualizzare questi tag nella posizione in cui è stata scattata la foto.

La procedura seguente illustra come configurare l'oggetto Label .

  1. Fare clic con il pulsante destro del mouse in un punto qualsiasi del pannello gerarchia (la posizione non è importante a questo punto), in Oggetto 3D aggiungere un testo 3D. Denominarlo LabelText.

    Creare un oggetto Text 3D.

  2. Nel pannello Gerarchia fare clic con il pulsante sinistro del mouse su LabelText. Con l'opzione LabelText selezionata, modificare le variabili seguenti nel pannello di controllo:

    1. Impostare Posizione su 0,0,0
    2. Impostare Scala su 0.01, 0.01, 0.01
    3. Nella mesh di testo del componente:
    4. Sostituire tutto il testo all'interno di Text, con "..."
    5. Impostare l'ancoraggio sul centro centrale
    6. Impostare l'allineamento al centro
    7. Impostare dimensioni tabulazioni su 4
    8. Impostare la dimensione del carattere su 50
    9. Impostare Color su #FFFFFFFF

    Componente testo

  3. Trascinare LabelText dal pannello Gerarchia, nella cartella asset, all'interno del pannello del progetto. In questo modo labelText verrà creato un prefab, in modo che possa essere creata un'istanza nel codice.

    Creare un prefab dell'oggetto LabelText.

  4. È consigliabile eliminare LabelText dal pannello Gerarchia, in modo che non venga visualizzato nella scena di apertura. Poiché è ora un prefab, che verrà chiamato per singole istanze dalla cartella Assets, non è necessario mantenerlo all'interno della scena.

  5. La struttura dell'oggetto finale nel pannello gerarchia dovrebbe essere simile a quella illustrata nell'immagine seguente:

    Struttura finale del pannello della gerarchia.

Capitolo 5: Creare la classe ResultsLabel

Il primo script che è necessario creare è la classe ResultsLabel , responsabile per quanto segue:

  • Creazione delle etichette nello spazio globale appropriato, rispetto alla posizione della fotocamera.
  • Visualizzazione dei tag dall'immagine Anaysis.

Per creare questa classe:

  1. Fare clic con il pulsante destro del mouse nel pannello del progetto, quindi scegliere Crea > cartella. Denominare la cartella Scripts.

    Creare la cartella degli script.

  2. Con la cartella Scripts create, fare doppio clic su di esso per aprirlo. Quindi all'interno di tale cartella fare clic con il pulsante destro del mouse e scegliere Crea >e quindi Script C#. Assegnare allo script il nome ResultsLabel.

  3. Fare doppio clic sul nuovo script ResultsLabel per aprirlo con Visual Studio.

  4. All'interno della classe Inserire il codice seguente nella 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. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

  6. Nell'editor di Unity fare clic e trascinare la classe ResultsLabel dalla cartella Scripts all'oggetto Fotocamera principale nel pannello Gerarchia.

  7. Fare clic sulla fotocamera principale e osservare il Pannello di controllo.

Si noterà che dallo script appena trascinato nella fotocamera ci sono due campi: Cursore e Prefab etichetta.

  1. Trascinare l'oggetto denominato Cursor dal pannello Gerarchia allo slot denominato Cursor, come illustrato nell'immagine seguente.

  2. Trascinare l'oggetto denominato LabelText dalla cartella Assets nel pannello del progetto nello slot denominato Label Prefab, come illustrato nell'immagine seguente.

    Impostare le destinazioni di riferimento all'interno di Unity.

Capitolo 6: Creare la classe ImageCapture

La classe successiva che si intende creare è la classe ImageCapture . Questa classe è responsabile di:

  • Acquisizione di un'immagine tramite la fotocamera HoloLens e l'archiviazione nella cartella dell'app.
  • Acquisizione di movimenti di tocco dall'utente.

Per creare questa classe:

  1. Passare alla cartella Scripts creata in precedenza.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Crea > script C#. Chiamare lo script ImageCapture.

  3. Fare doppio clic sul nuovo script ImageCapture per aprirlo con Visual Studio.

  4. Aggiungere gli spazi dei nomi seguenti all'inizio del file:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. Aggiungere quindi le variabili seguenti all'interno della classe ImageCapture, sopra il metodo Start():

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

La variabile tapsCount archivierà il numero di movimenti di tocco acquisiti dall'utente. Questo numero viene usato nella denominazione delle immagini acquisite.

  1. È ora necessario aggiungere il codice per i metodi Awake() e Start(). Questi verranno chiamati quando la classe inizializza:

        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. Implementare un gestore che verrà chiamato quando si verifica un movimento tap.

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

Il metodo TapHandler() incrementa il numero di tap acquisiti dall'utente e usa la posizione corrente del cursore per determinare dove posizionare una nuova etichetta.

Questo metodo chiama quindi il metodo ExecuteImageCaptureAndAnalysis() per avviare la funzionalità di base di questa applicazione.

  1. Dopo l'acquisizione e l'archiviazione di un'immagine, verranno chiamati i gestori seguenti. Se il processo ha esito positivo, il risultato viene passato a VisionManager (che è ancora necessario creare) per l'analisi.

        /// <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. Aggiungere quindi il metodo usato dall'applicazione per avviare il processo di acquisizione di immagini e archiviare l'immagine.

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

Avviso

A questo punto si noterà un errore visualizzato nel pannello della console dell'editor di Unity. Questo perché il codice fa riferimento alla classe VisionManager che verrà creata nel capitolo successivo.

Capitolo 7 : Chiamata ad Analisi immagini e Azure

L'ultimo script da creare è la classe VisionManager .

Questa classe è responsabile di:

  • Caricamento dell'immagine più recente acquisita come matrice di byte.
  • Invio della matrice di byte all'istanza del servizio API di Azure Visione artificiale per l'analisi.
  • Ricezione della risposta come stringa JSON.
  • Deserializzazione della risposta e passaggio dei tag risultanti alla classe ResultsLabel .

Per creare questa classe:

  1. Fare doppio clic sulla cartella Scripts per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Scripts e scegliere Crea > script C#. Assegnare allo script il nome VisionManager.

  3. Fare doppio clic sul nuovo script per aprirlo con Visual Studio.

  4. Aggiornare gli spazi dei nomi in modo che corrispondano ai seguenti, nella parte superiore della classe VisionManager :

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Nella parte superiore dello script, all'interno della classe VisionManager (sopra il metodo Start(), è ora necessario creare due classi che rappresenteranno la risposta JSON deserializzata da 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

    Le classi TagData e AnalyzerdObject devono avere l'attributo [System.Serializable] aggiunto prima della dichiarazione per poter essere deserializzato con le librerie Unity.

  6. Nella classe VisionManager è necessario aggiungere le variabili seguenti:

        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;
    

    Avviso

    Assicurarsi di inserire la chiave di autenticazione nella variabile authorizationKey . La chiave di autenticazione sarà stata annotata all'inizio di questo corso, capitolo 1.

    Avviso

    La variabile visionAnalysisEndpoint può essere diversa da quella specificata in questo esempio. L'area Stati Uniti occidentali si riferisce esclusivamente alle istanze del servizio create per l'area Stati Uniti occidentali. Aggiornare questa opzione con l'URL dell'endpoint. Di seguito sono riportati alcuni esempi di ciò che potrebbe essere simile al seguente:

    • Europa occidentale: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Sud-est asiatico: https://southeastasia.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Australia orientale: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. Il codice per Il sveglio deve ora essere aggiunto.

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. Aggiungere quindi la coroutine (con il metodo di flusso statico sottostante), che otterrà i risultati dell'analisi dell'immagine acquisita dalla 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. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

  10. Nell'editor di Unity fare clic e trascinare le classi VisionManager e ImageCapture dalla cartella Scripts all'oggetto Camera principale nel pannello Gerarchia.

Capitolo 8 – Prima dell'edificio

Per eseguire un test approfondito dell'applicazione, è necessario trasferire localmente l'applicazione in HoloLens. Prima di procedere, assicurarsi che:

  • Tutte le impostazioni indicate nel capitolo 2 vengono impostate correttamente.
  • Tutti gli script sono collegati all'oggetto Main Camera .
  • Tutti i campi nel pannello Controllo fotocamera principale vengono assegnati correttamente.
  • Assicurarsi di inserire la chiave di autenticazione nella variabile authorizationKey .
  • Assicurarsi di aver controllato anche l'endpoint nello script VisionManager e che sia allineato all'area geografica (questo documento usa west-us per impostazione predefinita).

Capitolo 9: Creare la soluzione UWP e trasferire localmente l'applicazione

Tutto ciò che serve per la sezione Unity di questo progetto è stato completato, quindi è il momento di compilarlo da Unity.

  1. Passare a Impostazioni - di compilazione file > impostazioni di compilazione...

  2. Nella finestra Build Settings (Impostazioni compilazione) fare clic su Build (Compila).

    Compilazione dell'app da Unity

  3. Se non è già stato fatto, selezionare Progetti C# unity.

  4. Fare clic su Compila. Unity avvierà una finestra Esplora file, in cui è necessario creare e quindi selezionare una cartella in cui compilare l'app. Creare ora la cartella e denominarla App. Quindi, con la cartella App selezionata, premere Seleziona cartella.

  5. Unity inizierà a compilare il progetto nella cartella App .

  6. Una volta completata la compilazione di Unity (potrebbe essere necessario del tempo), verrà aperta una finestra Esplora file nella posizione della compilazione (controllare la barra delle applicazioni, perché potrebbe non essere sempre visualizzata sopra le finestre, ma invierà una notifica dell'aggiunta di una nuova finestra).

Capitolo 10 - Distribuire in HoloLens

Per eseguire la distribuzione in HoloLens:

  1. È necessario l'indirizzo IP di HoloLens (per la distribuzione remota) e assicurarsi che HoloLens sia in modalità sviluppatore. A questo scopo, è necessario:

    1. Mentre indossa HoloLens, apri le impostazioni.
    2. Vai a Rete e Internet > Wi-Fi > Opzioni avanzate
    3. Prendere nota dell'indirizzo IPv4 .
    4. Tornare quindi a Impostazioni e quindi a Aggiorna e sicurezza > per sviluppatori
    5. Impostare la modalità sviluppatore attivata.
  2. Passare alla nuova compilazione unity ( cartella App ) e aprire il file della soluzione con Visual Studio.

  3. Nella configurazione della soluzione selezionare Debug.

  4. Nella piattaforma della soluzione selezionare x86, Computer remoto.

    Distribuire la soluzione da Visual Studio.

  5. Passare al menu Compila e fare clic su Distribuisci soluzione per trasferire localmente l'applicazione in HoloLens.

  6. L'app dovrebbe ora essere visualizzata nell'elenco delle app installate in HoloLens, pronte per l'avvio.

Nota

Per eseguire la distribuzione in visore VR immersive, impostare Piattaforma soluzione su Computer locale e impostare Configurazione su Debug, con x86 come piattaforma. Eseguire quindi la distribuzione nel computer locale, usando il menu Compila, selezionando Distribuisci soluzione.

Applicazione API Visione artificiale completata

È stata creata un'app di realtà mista che sfrutta l'API di Azure Visione artificiale per riconoscere gli oggetti reali e visualizzare l'attendibilità di ciò che è stato visto.

risultato del lab

Esercizi aggiuntivi

Esercizio 1

Proprio come è stato usato il parametro Tags (come evidenziato all'interno dell'endpoint usato all'interno di VisionManager), estendere l'app per rilevare altre informazioni. Esaminare gli altri parametri a cui si ha accesso qui.

Esercizio 2

Visualizzare i dati di Azure restituiti, in modo più colloquiale e leggibile, nascondendo i numeri. Come se un bot potesse parlare con l'utente.