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. Saranno disponibili nuove serie di esercitazioni che verranno pubblicate in futuro che mostreranno come sviluppare per HoloLens 2. Questo avviso verrà aggiornato con un collegamento a tali esercitazioni quando vengono pubblicati.


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 fornire 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 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 volti 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 acquisisce un'immagine.
  2. L'immagine verrà inviata al servizio API di Azure Visione artificiale.
  3. Gli oggetti riconosciuti verranno elencati in un semplice gruppo di interfaccia utente posizionato nella scena Unity.

Nell'applicazione è possibile integrare i risultati con la progettazione. Questo corso è progettato per insegnare come integrare un servizio di Azure con il progetto Unity. È il tuo lavoro per 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 si concentra principalmente su HoloLens, è anche possibile applicare ciò che si impara in questo corso per Windows Mixed Reality visori VR (Immersive). Poiché i visori vr (VR) immersivi non dispongono di fotocamere accessibili, sarà 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 immersivi.

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). Si è liberi di usare il software più recente, come elencato nell'articolo degli strumenti di installazione , anche se non dovrebbe essere considerato che le informazioni in questo corso corrisponderanno perfettamente a ciò che troverete 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 problemi durante la compilazione di questo progetto, è consigliabile creare il progetto menzionato in questa esercitazione in una cartella radice o quasi radice (i percorsi di cartelle lunghe possono causare problemi in fase di compilazione).
  2. Configurare e testare HoloLens. Se è necessario supportare la configurazione di HoloLens, assicurarsi di visitare l'articolo relativo alla configurazione di HoloLens.
  3. È consigliabile eseguire l'ottimizzazione della calibrazione e del sensore quando si inizia a sviluppare una nuova app HoloLens (a volte può aiutare a eseguire queste attività per ogni utente).

Per informazioni sulla calibrazione, seguire questo collegamento all'articolo Di calibrazione HoloLens.

Per informazioni sull'ottimizzazione del sensore, 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. Per prima cosa, accedere al portale di Azure.

    Nota

    Se non si dispone già di un account Azure, sarà necessario crearne uno. Se si segue questa esercitazione in una classe o in una situazione del lab, chiedere all'insegnante o a uno dei proctor di 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 fornisce una descrizione del servizio API di 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 per l'utente, se si tratta della prima volta che si crea un servizio API Visione artificiale, deve essere disponibile un piano gratuito (denominato F0).

    4. Scegliere un gruppo di risorse o crearne uno nuovo. Un gruppo di risorse consente di monitorare, controllare l'accesso, 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 del gruppo di risorse.

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

    6. Dovrai anche confermare che hai capito le Condizioni e le condizioni applicate al servizio.

    7. Fare clic su Crea.

      Informazioni sulla creazione del servizio

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

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

    Vedere la nuova notifica per il nuovo servizio

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

    Selezionare il pulsante Vai a risorsa.

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

    Nuova immagine del servizio API Visione artificiale

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

  10. Nella pagina Avvio rapido del servizio API 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, nel menu di spostamento dei servizi, denotato dall'icona della chiave). In questo modo verranno rivelate le chiavi del servizio.

  11. Eseguire una copia di una delle chiavi visualizzate, perché sarà necessario in un secondo momento nel progetto.

  12. Indietro alla pagina di avvio rapido e da lì recuperare l'endpoint. Tenere presente che i tuoi utenti potrebbero essere diversi, a seconda dell'area (che, se è, sarà necessario apportare una modifica al codice in un secondo momento). Eseguire una copia di questo endpoint per l'uso in un secondo momento:

    Il nuovo servizio API Visione artificiale

    Suggerimento

    È possibile verificare quali sono i vari endpoint QUI.

Capitolo 2: Configurare il progetto Unity

Di seguito è riportato un tipico set up 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. A questo momento sarà necessario specificare un nome di progetto Unity. Inserire 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. Sempre 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 Più recente installato

    4. La versione di Visual Studio è impostata su 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 Scenes appena creata e quindi nel campo Nome file: 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 Build Settings (Impostazioni compilazione) fare clic sul pulsante Player Settings (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à dell'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 (disponibile sotto Impostazioni di pubblicazione), selezionare Virtual Reality Supported (Realtà virtuale supportata), assicurarsi che sia stato aggiunto Windows Mixed Reality SDK.

      Aggiornare le impostazioni X R.

  8. In Build SettingsUnity C# Projects (Impostazioni di compilazione) I progetti C# non sono più disattivati; selezionare la casella di controllo accanto a questa.

  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 Configura Unity di questo corso e continuare direttamente nel codice, è possibile scaricare questo pacchetto unitypackage, importarlo nel progetto come pacchetto personalizzato e 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 Main Camera (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 Cancella flag suColore a tinta unita (ignorare questo valore per il visore VR immersive).

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

      Aggiornare i componenti della fotocamera.

  3. Successivamente, sarà necessario creare un semplice oggetto "Cursor" 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 elemento 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 etichetta

Dopo aver acquisito un'immagine con la fotocamera di HoloLens, tale 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 Tags.

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 Scale 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'ancoraggiosul centro centrale
    6. Impostare l'allineamento al centro
    7. Impostare Dimensioni tabulazioni su 4
    8. Impostare Dimensioni caratteresu 50
    9. Impostare Colore su #FFFFFFFF

    Componente di 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. È necessario eliminare LabelText dal pannello gerarchia, in modo che non venga visualizzato nella scena di apertura. Come è ora un prefab, che verrà chiamato per singole istanze dalla cartella Asset, non è necessario tenerlo all'interno della scena.

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

    Struttura finale del pannello gerarchia.

Capitolo 5 : Creare la classe ResultsLabel

Il primo script da creare è la classe ResultsLabel , responsabile delle operazioni seguenti:

  • Creazione delle etichette nello spazio mondiale 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 creare > cartella. Assegnare un nome alla cartella Script.

    Creare una cartella script.

  2. Con la cartella Script create, fare doppio clic su di esso per aprire. Quindi all'interno di tale cartella fare clic con il pulsante destro del mouse e selezionare Crea > quindi script C#. Assegnare un nome allo script 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. Tornare all'editor di Unity, fare clic e trascinare la classe ResultsLabel dalla cartella Script all'oggetto Main Camera nel pannello gerarchia.

  7. Fare clic sulla fotocamera principale e guardare il pannello di controllo.

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

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

  2. Trascinare l'oggetto denominato LabelText dalla cartella Asset nel pannello di progetto nello slot denominato Etichetta 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 tap dall'utente.

Per creare questa classe:

  1. Passare alla cartella Script creata in precedenza.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella, Creare > 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. Il codice per i metodi Awake() e Start() deve ora essere aggiunto. 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 del cursore corrente per determinare dove posizionare una nuova etichetta.

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

  1. Dopo aver acquisito e archiviato un'immagine, verranno chiamati i gestori seguenti. Se il processo ha esito positivo, il risultato viene passato a VisionManager (che non è ancora stato creato) 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 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 console dell'editor di Unity. Questo perché il codice fa riferimento alla classe VisionManager che verrà creata nel capitolo successivo.

Capitolo 7 : Chiamata ad Azure e analisi delle immagini

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 Script per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Script , fare clic su Crea > script C#. Assegnare un nome allo script 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 rappresentano 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 . Si avrà annotato la chiave di autenticazione all'inizio di questo corso, capitolo 1.

    Avviso

    La variabile visionAnalysisEndpoint può essere diversa da quella specificata in questo esempio. L'utente occidentale si riferisce strettamente alle istanze di servizio create per l'area Stati Uniti occidentali. Aggiornare questa operazione con l'URL dell'endpoint; ecco alcuni esempi di ciò che potrebbe essere simile al seguente:

    • Europa occidentale: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Asia sud-orientale: 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 Awake 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 sotto di essa), 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. Tornare all'editor di Unity, fare clic e trascinare le classi VisionManager e ImageCapture dalla cartella Script all'oggetto Main Camera nel pannello gerarchia.

Capitolo 8 - Prima dell'edificio

Per eseguire un test approfondito dell'applicazione, è necessario eseguirne il sideload sul dispositivo HoloLens. Prima di eseguire, assicurarsi che:

  • Tutte le impostazioni indicate nel capitolo 2 sono impostate correttamente.
  • Tutti gli script sono collegati all'oggetto Main Camera .
  • Tutti i campi nel pannello controllo della fotocamera principale vengono assegnati correttamente.
  • Assicurarsi di inserire la chiave di autenticazione nella variabile authorizationKey .
  • Assicurarsi che l'endpoint sia stato controllato anche nello script VisionManager e che si allinea all'area (questo documento usa l'utente occidentale per impostazione predefinita).

Capitolo 9: compilare la soluzione UWP e scaricare sideload dell'applicazione

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

  1. Passare a Impostazionidi compilazione file > di compilazione delle impostazioni - di compilazione...

  2. Nella finestra Impostazioni di compilazione fare clic su Compila.

    Creazione dell'app da Unity

  3. In caso contrario, selezionare Progetti Unity C#.

  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 la cartella ora e denominarla App. Quindi, con la cartella App selezionata, premere Seleziona cartella.

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

  6. Dopo aver completato la compilazione di Unity (potrebbe richiedere qualche tempo), aprirà una finestra Esplora file nella posizione della compilazione (controllare la barra delle applicazioni, perché potrebbe non essere sempre visualizzata sopra le finestre, ma vi notifica l'aggiunta di una nuova finestra).

Capitolo 10 - Distribuire in HoloLens

Per distribuire in HoloLens:

  1. Sarà necessario l'indirizzo IP di HoloLens (per la distribuzione remota) e assicurarsi che HoloLens sia in modalità sviluppatore. Per eseguire questa operazione:

    1. Mentre indossa il tuo HoloLens, apri le impostazioni.
    2. Passare a Rete & Internet > Wi-Fi > Opzioni avanzate
    3. Si noti l'indirizzo IPv4 .
    4. Tornare quindi a Impostazioni e quindi aggiornare & sicurezza > per sviluppatori
    5. Impostare la modalità sviluppatore su.
  2. Passare alla nuova compilazione di Unity (cartella App ) e aprire il file di soluzione con Visual Studio.

  3. Nella configurazione della soluzione selezionare Debug.

  4. Nella piattaforma della soluzione selezionare x86, Remote Machine.

    Distribuire la soluzione da Visual Studio.

  5. Passare al menu Compila e fare clic su Distribuisci soluzione per caricare sideload dell'applicazione in HoloLens.

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

Nota

Per distribuire in visore vr immersivo, impostare La piattaforma soluzione su Computer locale e impostare Configurazione su Debug, con x86 come piattaforma. Quindi distribuire nel computer locale, usando il menu Build, selezionando Distribuisci soluzione.

Applicazione API Visione artificiale completata

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

risultato del lab

Esercizi aggiuntivi

Esercizio 1

Proprio come è stato usato il parametro Tag (come evidenziato all'interno dell'endpoint usato all'interno di VisionManager), estendere l'app per rilevare altre informazioni; esaminare gli altri parametri a cui è possibile accedere a HERE.

Esercizio 2

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