HoloLens (1. Generation) und Azure 302: Maschinelles Sehen


Hinweis

Die Tutorials der Mixed Reality Academy wurden im Hinblick auf HoloLens (1. Gen.) und immersive Mixed Reality-Headsets entworfen. Daher halten wir es für wichtig, diese Tutorials für Entwickler verfügbar zu halten, die noch nach Anleitung beim Entwickeln für diese Geräte suchen. Diese Tutorials werden nicht mit den neuesten Toolsets oder Interaktionen aktualisiert, die für HoloLens 2 verwendet werden. Sie werden gewartet, um weiterhin auf den unterstützten Geräten zu funktionieren. Es wird eine neue Reihe von Tutorials geben, die in Zukunft veröffentlicht werden, die veranschaulichen, wie für HoloLens 2 entwickelt werden kann. Dieser Hinweis wird mit einem Link zu diesen Tutorials aktualisiert, wenn sie veröffentlicht werden.


In diesem Kurs erfahren Sie, wie Sie visuelle Inhalte in einem bereitgestellten Bild mithilfe von Azure maschinelles Sehen-Funktionen in einer Mixed Reality-Anwendung erkennen.

Erkennungsergebnisse werden als beschreibende Tags angezeigt. Sie können diesen Dienst verwenden, ohne ein Machine Learning-Modell trainieren zu müssen. Wenn Ihre Implementierung das Trainieren eines Machine Learning-Modells erfordert, lesen Sie MR und Azure 302b.

Lab-Ergebnis

Der Microsoft maschinelles Sehen ist eine Reihe von APIs, die entwickelt wurden, um Entwicklern Bildverarbeitung und -analyse (mit Rückgabeinformationen) mit erweiterten Algorithmen aus der Cloud bereitzustellen. Entwickler laden eine Bild- oder Bild-URL hoch, und die Microsoft maschinelles Sehen-API-Algorithmen analysieren den visuellen Inhalt basierend auf den vom Benutzer ausgewählten Eingaben, die dann Informationen zurückgeben können, einschließlich der Identifizierung des Typs und der Qualität eines Bilds, erkennen von menschlichen Gesichtern (zurückgeben deren Koordinaten) und Markieren oder Kategorisieren von Bildern. Weitere Informationen finden Sie auf der Seite azure maschinelles Sehen API.

Nach Abschluss dieses Kurses verfügen Sie über eine Mixed Reality-HoloLens-Anwendung, die folgende Aufgaben ausführen kann:

  1. Mithilfe der Tippen-Geste erfasst die Kamera der HoloLens ein Bild.
  2. Das Image wird an den Azure maschinelles Sehen API-Dienst gesendet.
  3. Die erkannten Objekte werden in einer einfachen Benutzeroberflächengruppe aufgeführt, die in der Unity-Szene positioniert ist.

In Ihrer Anwendung liegt es an Ihnen, wie Sie die Ergebnisse in Ihr Design integrieren. In diesem Kurs erfahren Sie, wie Sie einen Azure-Dienst in Ihr Unity-Projekt integrieren. Es ist Ihre Aufgabe, das Wissen, das Sie aus diesem Kurs gewonnen haben, zu nutzen, um Ihre Mixed Reality-Anwendung zu verbessern.

Geräteunterstützung

Kurs HoloLens Immersive Headsets
MR und Azure 302: Maschinelles Sehen ✔️ ✔️

Hinweis

Während sich dieser Kurs hauptsächlich auf HoloLens konzentriert, können Sie das, was Sie in diesem Kurs gelernt haben, auch auf Windows Mixed Reality immersiven Headsets (VR) anwenden. Da immersive Headsets (VR) keine zugänglichen Kameras haben, benötigen Sie eine externe Kamera, die an Ihren PC angeschlossen ist. Während Sie dem Kurs folgen, werden Ihnen Notizen zu allen Änderungen angezeigt, die Sie möglicherweise zur Unterstützung von immersiven (VR)-Headsets verwenden müssen.

Voraussetzungen

Hinweis

Dieses Tutorial richtet sich an Entwickler, die über grundlegende Erfahrungen mit Unity und C# verfügen. Bitte beachten Sie auch, dass die Voraussetzungen und schriftlichen Anweisungen in diesem Dokument das darstellen, was zum Zeitpunkt des Schreibens (Mai 2018) getestet und überprüft wurde. Sie können die neueste Software verwenden, wie im Artikel Installieren der Tools aufgeführt, aber es sollte nicht davon ausgegangen werden, dass die Informationen in diesem Kurs perfekt dem entsprechen, was Sie in neuerer Software finden, als unten aufgeführt.

Wir empfehlen die folgende Hardware und Software für diesen Kurs:

Vorbereitung

  1. Um Probleme beim Erstellen dieses Projekts zu vermeiden, wird dringend empfohlen, dass Sie das in diesem Tutorial erwähnte Projekt in einem Stamm- oder Fast-Stammordner erstellen (lange Ordnerpfade können zur Buildzeit Zu Problemen führen).
  2. Richten Sie Ihre HoloLens ein und testen Sie sie. Wenn Sie Unterstützung beim Einrichten Ihrer HoloLens benötigen, lesen Sie den Artikel holoLens-Setup.
  3. Es ist eine gute Idee, Kalibrierung und Sensoroptimierung durchzuführen, wenn Sie mit der Entwicklung einer neuen HoloLens-App beginnen (manchmal kann dies helfen, diese Aufgaben für jeden Benutzer auszuführen).

Hilfe zur Kalibrierung finden Sie unter diesem Link zum Artikel HoloLens-Kalibrierung.

Hilfe zur Sensoroptimierung finden Sie unter diesem Link zum Artikel Zur HoloLens-Sensoroptimierung.

Kapitel 1: Das Azure-Portal

Um den maschinelles Sehen-API-Dienst in Azure verwenden zu können, müssen Sie eine instance des Diensts konfigurieren, der ihrer Anwendung zur Verfügung gestellt wird.

  1. Melden Sie sich zunächst beim Azure-Portal an.

    Hinweis

    Wenn Sie noch nicht über ein Azure-Konto verfügen, müssen Sie eines erstellen. Wenn Sie dieses Tutorial in einer Unterrichts- oder Laborsituation befolgen, bitten Sie Ihren Kursleiter oder einen der Experten um Hilfe beim Einrichten Ihres neuen Kontos.

  2. Nachdem Sie angemeldet sind, klicken Sie in der oberen linken Ecke auf Neu, suchen Sie nach maschinelles Sehen API, und klicken Sie auf DIE EINGABETASTE.

    Erstellen einer neuen Ressource in Azure

    Hinweis

    Das Wort Neu wurde in neueren Portalen möglicherweise durch Ressource erstellen ersetzt.

  3. Die neue Seite enthält eine Beschreibung des maschinelles Sehen API-Diensts. Wählen Sie unten links auf dieser Seite die Schaltfläche Erstellen aus, um eine Zuordnung zu diesem Dienst zu erstellen.

    Informationen zum API-Dienst für maschinelles Sehen

  4. Nachdem Sie auf Erstellen geklickt haben:

    1. Geben Sie den gewünschten Namen für diesen Dienst instance ein.

    2. Wählen Sie ein Abonnementaus.

    3. Wählen Sie den für Sie geeigneten Tarif aus. Wenn Sie zum ersten Mal einen maschinelles Sehen API-Dienst erstellen, sollte ihnen ein Free-Tarif (mit dem Namen F0) zur Verfügung stehen.

    4. Wählen Sie eine Ressourcengruppe aus, oder erstellen Sie eine neue. Eine Ressourcengruppe bietet eine Möglichkeit zum Überwachen, Steuern des Zugriffs, Bereitstellen und Verwalten der Abrechnung für eine Sammlung von Azure-Ressourcen. Es wird empfohlen, alle Azure-Dienste, die einem einzelnen Projekt (z. B. diesen Labs) zugeordnet sind, unter einer gemeinsamen Ressourcengruppe zu halten.

      Weitere Informationen zu Azure-Ressourcengruppen finden Sie im Artikel Ressourcengruppe.

    5. Ermitteln Sie den Speicherort für Ihre Ressourcengruppe (wenn Sie eine neue Ressourcengruppe erstellen). Der Speicherort befindet sich idealerweise in der Region, in der die Anwendung ausgeführt wird. Einige Azure-Ressourcen sind nur in bestimmten Regionen verfügbar.

    6. Sie müssen auch bestätigen, dass Sie die für diesen Dienst geltenden Geschäftsbedingungen verstanden haben.

    7. Klicken Sie auf „Erstellen“.

      Informationen zur Diensterstellung

  5. Nachdem Sie auf Erstellen geklickt haben, müssen Sie warten, bis der Dienst erstellt wurde. Dies kann eine Minute dauern.

  6. Eine Benachrichtigung wird im Portal angezeigt, sobald der Dienst instance erstellt wurde.

    Anzeigen der neuen Benachrichtigung für Ihren neuen Dienst

  7. Klicken Sie auf die Benachrichtigung, um Ihre neue Dienst-instance zu erkunden.

    Wählen Sie die Schaltfläche Zu Ressource wechseln aus.

  8. Klicken Sie in der Benachrichtigung auf die Schaltfläche Zu Ressource wechseln, um Ihre neue Dienst-instance zu erkunden. Sie werden zu Ihrem neuen maschinelles Sehen API-Dienst instance weitergeleitet.

    Ihr neues maschinelles Sehen-API-Dienstimage

  9. In diesem Tutorial muss Ihre Anwendung Aufrufe an Ihren Dienst durchführen, was mithilfe des Abonnementschlüssels Ihres Diensts erfolgt.

  10. Navigieren Sie auf der Schnellstartseite Ihres maschinelles Sehen API-Diensts zum ersten Schritt, greifen Sie Ihre Schlüssel, und klicken Sie auf Schlüssel (Sie können dies auch erreichen, indem Sie auf den blauen Link Schlüssel klicken, der sich im Navigationsmenü dienste befindet und durch das Schlüsselsymbol gekennzeichnet ist). Dadurch werden Ihre Dienstschlüssel angezeigt.

  11. Nehmen Sie eine Kopie eines der angezeigten Schlüssel an, da Sie diese später in Ihrem Projekt benötigen.

  12. Zurück zur Schnellstartseite, und rufen Sie dort Ihren Endpunkt ab. Seien Sie sich bewusst, dass Sich Ihres je nach Region unterscheiden kann (wenn dies der Wert ist, müssen Sie später eine Änderung am Code vornehmen). Nehmen Sie eine Kopie dieses Endpunkts zur späteren Verwendung an:

    Ihr neuer maschinelles Sehen-API-Dienst

    Tipp

    Hier können Sie überprüfen, welche Endpunkte es gibt.

Kapitel 2 – Einrichten des Unity-Projekts

Das Folgende ist eine typische Einrichtung für die Entwicklung mit Mixed Reality und ist daher eine gute Vorlage für andere Projekte.

  1. Öffnen Sie Unity, und klicken Sie auf Neu.

    Starten Sie ein neues Unity-Projekt.

  2. Sie müssen nun einen Unity-Projektnamen angeben. Fügen Sie MR_ComputerVision ein. Stellen Sie sicher, dass der Projekttyp auf 3D festgelegt ist. Legen Sie den Speicherort auf einen für Sie geeigneten Ort fest (denken Sie daran, dass näher an Stammverzeichnissen besser ist). Klicken Sie dann auf Projekt erstellen.

    Geben Sie Details zum neuen Unity-Projekt an.

  3. Wenn Unity geöffnet ist, lohnt es sich, zu überprüfen, ob der Standardskript-Editor auf Visual Studio festgelegt ist. Navigieren Sie zu Einstellungen bearbeiten>, und navigieren Sie dann im neuen Fenster zu Externe Tools. Ändern Sie den externen Skript-Editor in Visual Studio 2017. Schließen Sie das Fenster Einstellungen.

    Aktualisieren Sie die Skript-Editor-Einstellung.

  4. Wechseln Sie als Nächstes zu Dateierstellungseinstellungen>, wählen Sie Universelle Windows-Plattform aus, und klicken Sie dann auf die Schaltfläche Plattform wechseln, um Ihre Auswahl anzuwenden.

    Fenster

  5. Wenn Sie sich noch in den Dateibuildeinstellungen > befinden , stellen Sie sicher, dass:

    1. Zielgerät ist auf HoloLens festgelegt

      Legen Sie für die immersiven Headsets Zielgerät auf Beliebiges Gerät fest.

    2. Buildtyp ist auf D3D festgelegt

    3. SDK ist auf Zuletzt installiert festgelegt.

    4. Visual Studio-Version ist auf Zuletzt installiert festgelegt.

    5. Build and Run ist auf Lokaler Computer festgelegt.

    6. Speichern Sie die Szene, und fügen Sie sie dem Build hinzu.

      1. Wählen Sie dazu Offene Szenen hinzufügen aus. Es wird ein Fenster zum Speichern angezeigt.

        Klicken Sie auf die Schaltfläche

      2. Erstellen Sie einen neuen Ordner für diese und jede zukünftige Szene, und wählen Sie dann die Schaltfläche Neuer Ordner aus, um einen neuen Ordner zu erstellen, und nennen Sie ihn Szenen.

        Erstellen eines neuen Skriptordners

      3. Öffnen Sie Ihren neu erstellten Ordner Scenes , und geben Sie dann im Textfeld Dateiname: MR_ComputerVisionScene ein, und klicken Sie dann auf Speichern.

        Geben Sie der neuen Szene einen Namen.

        Beachten Sie, dass Sie Ihre Unity-Szenen im Ordner Assets speichern müssen, da sie dem Unity-Projekt zugeordnet sein müssen. Das Erstellen des Szenenordners (und anderer ähnlicher Ordner) ist eine typische Methode zum Strukturieren eines Unity-Projekts.

    7. Die restlichen Einstellungen in Buildeinstellungen sollten vorerst als Standard beibehalten werden.

  6. Klicken Sie im Fenster Buildeinstellungen auf die Schaltfläche Playereinstellungen . Dadurch wird der zugehörige Bereich in dem Bereich geöffnet, in dem sich der Inspektor befindet.

    Öffnen Sie die Playereinstellungen.

  7. In diesem Bereich müssen einige Einstellungen überprüft werden:

    1. Auf der Registerkarte Andere Einstellungen :

      1. Die Skriptlaufzeitversion sollte stabil (.NET 3.5 gleichwertig) sein.

      2. Skript-Back-End sollte .NET sein

      3. API-Kompatibilitätsgrad sollte .NET 4.6 sein

        Aktualisieren Sie andere Einstellungen.

    2. Überprüfen Sie auf der Registerkarte Veröffentlichungseinstellungen unter Funktionen Folgendes:

      1. InternetClient

      2. Webcam

        Aktualisieren der Veröffentlichungseinstellungen.

    3. Wählen Sie weiter unten im Bereich unter XR-Einstellungen (unter Veröffentlichungseinstellungen) die Option Virtual Reality Supported (Virtual Reality Supported) aus, stellen Sie sicher, dass das Windows Mixed Reality SDK hinzugefügt wurde.

      Aktualisieren Sie die X R-Einstellungen.

  8. Zurück in BuildeinstellungenUnity C#- Projekte ist nicht mehr abgeblendet. aktivieren Sie das Kontrollkästchen neben diesem.

  9. Schließen Sie das Fenster „Build Settings“ (Buildeinstellungen).

  10. Speichern Sie Ihre Szene und Ihr Projekt (FILE > SAVE SCENE / FILE > SAVE PROJECT).

Kapitel 3 – Einrichtung der Hauptkamera

Wichtig

Wenn Sie die Unity Set up-Komponente dieses Kurses überspringen und direkt mit dem Code fortfahren möchten, können Sie dieses UnityPackage herunterladen, es als benutzerdefiniertes Paket in Ihr Projekt importieren und dann mit Kapitel 5 fortfahren.

  1. Wählen Sie im Hierarchiebereich die Hauptkamera aus.

  2. Nach der Auswahl können Sie alle Komponenten der Hauptkamera im Inspektorbereich sehen.

    1. Das Camera-Objekt muss den Namen Hauptkamera haben (beachten Sie die Schreibweise!)

    2. Das Hauptkameratag muss auf MainCamera festgelegt werden (beachten Sie die Schreibweise!)

    3. Stellen Sie sicher, dass die Transformationsposition auf 0, 0, 0 festgelegt ist.

    4. Legen Sie Clear Flags auf Einfarbig fest (ignorieren Sie dies für immersive Headsets).

    5. Legen Sie die Hintergrundfarbe der Kamerakomponente auf Schwarz, Alpha 0 (Hexcode: #00000000) fest (ignorieren Sie dies für immersive Headsets).

      Kamerakomponenten aktualisieren.

  3. Als Nächstes müssen Sie ein einfaches "Cursor"-Objekt erstellen, das an die Hauptkamera angefügt ist, um die Bildanalyseausgabe zu positionieren, wenn die Anwendung ausgeführt wird. Dieser Cursor bestimmt den Mittelpunkt des Kamerafokus.

So erstellen Sie den Cursor:

  1. Klicken Sie im Hierarchiebereich mit der rechten Maustaste auf die Hauptkamera. Klicken Sie unter 3D-Objekt auf Kugel.

    Wählen Sie das Cursorobjekt aus.

  2. Benennen Sie die Kugel in Cursor um (doppelklicken Sie auf das Cursor-Objekt, oder drücken Sie die Tastenkombination "F2" mit ausgewähltem Objekt), und stellen Sie sicher, dass sie sich als untergeordnetes Element der Hauptkamera befindet.

  3. Klicken Sie im Hierarchiebereich mit der linken Maustaste auf den Cursor. Wenn Der Cursor ausgewählt ist, passen Sie die folgenden Variablen im Inspektorbereich an:

    1. Legen Sie die Transformationsposition auf 0, 0, 5 fest.

    2. Festlegen der Skalierung auf 0,02, 0,02, 0,02

      Aktualisieren Sie die Transformierungsposition und Skalierung.

Kapitel 4: Einrichten des Bezeichnungssystems

Nachdem Sie ein Bild mit der HoloLens-Kamera erfasst haben, wird dieses Bild zur Analyse an Ihre Azure maschinelles Sehen API Service-instance gesendet.

Die Ergebnisse dieser Analyse sind eine Liste der erkannten Objekte namens Tags.

Sie verwenden Bezeichnungen (als 3D-Text im Weltraum), um diese Tags an der Stelle anzuzeigen, an der das Foto aufgenommen wurde.

Die folgenden Schritte zeigen, wie Sie das Label-Objekt einrichten.

  1. Klicken Sie mit der rechten Maustaste an eine beliebige Stelle im Hierarchiebereich (die Position spielt an diesem Punkt keine Rolle), fügen Sie unter 3D-Objekt einen 3D-Text hinzu. Nennen Sie ihn LabelText.

    Erstellen Sie das 3D Text-Objekt.

  2. Klicken Sie im Hierarchiebereich mit der linken Maustaste auf labelText. Wenn LabelText ausgewählt ist, passen Sie die folgenden Variablen im Inspektorbereich an:

    1. Legen Sie die Position auf 0,0,0 fest.
    2. Festlegen der Skalierung auf 0,01, 0,01, 0,01
    3. In der Komponente Textgitter:
    4. Ersetzen Sie den gesamten Text in Text durch "..."
    5. Legen Sie den Anker auf Mittlere Mitte fest.
    6. Festlegen der Ausrichtung auf Zentrierung
    7. Legen Sie die Registerkartengröße auf 4 fest.
    8. Festlegen des Schriftgrads auf 50
    9. Legen Sie die Farbe auf #FFFFFFFF fest.

    Textkomponente

  3. Ziehen Sie den LabelText aus dem Hierarchiebereich in den Ressourcenordner innerhalb des Projektbereichs. Dadurch wird labelText zu einem Prefab, sodass er im Code instanziiert werden kann.

    Erstellen Sie ein Prefab des LabelText-Objekts.

  4. Sie sollten den LabelText aus dem Hierarchiebereich löschen, damit er nicht in der Eröffnungsszene angezeigt wird. Da es sich jetzt um ein Prefab handelt, das Sie für einzelne Instanzen aus Dem Ordner Assets aufrufen, ist es nicht erforderlich, es innerhalb der Szene zu behalten.

  5. Die endgültige Objektstruktur im Hierarchiebereich sollte wie in der folgenden Abbildung dargestellt sein:

    Endgültige Struktur des Hierarchiebereichs.

Kapitel 5: Erstellen der ResultsLabel-Klasse

Das erste Skript, das Sie erstellen müssen, ist die ResultsLabel-Klasse , die für Folgendes verantwortlich ist:

  • Erstellen der Bezeichnungen im entsprechenden Weltbereich relativ zur Position der Kamera.
  • Zeigt die Tags aus der Bild-Anaysis an.

So erstellen Sie diese Klasse:

  1. Klicken Sie mit der rechten Maustaste in den Projektbereich, und klicken Sie dann auf Ordner erstellen>. Nennen Sie den Ordner Skripts.

    Ordner

  2. Doppelklicken Sie beim Erstellen des Ordners Skripts darauf, um ihn zu öffnen. Klicken Sie dann in diesem Ordner mit der rechten Maustaste, und wählen Sie Erstellen > und dann C#-Skript aus. Nennen Sie das Skript ResultsLabel.

  3. Doppelklicken Sie auf das neue ResultsLabel-Skript , um es mit Visual Studio zu öffnen.

  4. Fügen Sie in der -Klasse den folgenden Code in die ResultsLabel-Klasse ein:

        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. Speichern Sie ihre Änderungen in Visual Studio , bevor Sie zu Unity zurückkehren.

  6. Klicken Sie zurück im Unity-Editor auf die ResultsLabel-Klasse , und ziehen Sie sie aus dem Ordner Skripts in das Hauptkameraobjekt im Hierarchiebereich.

  7. Klicken Sie auf die Hauptkamera , und sehen Sie sich den Inspektorbereich an.

Sie werden feststellen, dass aus dem Skript, das Sie gerade in die Kamera gezogen haben, zwei Felder vorhanden sind: Cursor und Label Prefab.

  1. Ziehen Sie das Objekt mit dem Namen Cursor aus dem Hierarchiebereich in den Slot Cursor, wie in der folgenden Abbildung dargestellt.

  2. Ziehen Sie das Objekt mit dem Namen LabelText aus dem Ordner Assets im Projektbereich in den Slot Label Prefab, wie in der folgenden Abbildung dargestellt.

    Legen Sie die Verweisziele in Unity fest.

Kapitel 6: Erstellen der ImageCapture-Klasse

Die nächste Klasse, die Sie erstellen, ist die ImageCapture-Klasse . Diese Klasse ist für Folgendes zuständig:

  • Erfassen eines Bilds mithilfe der HoloLens-Kamera und Speichern im App-Ordner.
  • Erfassen von Tap-Gesten des Benutzers.

So erstellen Sie diese Klasse:

  1. Wechseln Sie zum Ordner Skripts, den Sie zuvor erstellt haben.

  2. Klicken Sie mit der rechten Maustaste in den Ordner C#-Skript erstellen>. Rufen Sie das Skript ImageCapture auf.

  3. Doppelklicken Sie auf das neue ImageCapture-Skript , um es mit Visual Studio zu öffnen.

  4. Fügen Sie am Anfang der Datei die folgenden Namespaces hinzu:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. Fügen Sie dann die folgenden Variablen in der ImageCapture-Klasse oberhalb der Start() -Methode hinzu:

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

Die TapsCount-Variable speichert die Anzahl der vom Benutzer erfassten Tippengesten. Diese Zahl wird bei der Benennung der erfassten Bilder verwendet.

  1. Code für die Methoden Awake() und Start() muss jetzt hinzugefügt werden. Diese werden aufgerufen, wenn die -Klasse initialisiert:

        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. Implementieren Sie einen Handler, der aufgerufen wird, wenn eine Tippen-Geste auftritt.

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

Die TapHandler() -Methode inkrementiert die Anzahl der vom Benutzer erfassten Tippen und bestimmt anhand der aktuellen Cursorposition, wo eine neue Bezeichnung positioniert werden soll.

Diese Methode ruft dann die ExecuteImageCaptureAndAnalysis()- Methode auf, um mit der Kernfunktionalität dieser Anwendung zu beginnen.

  1. Sobald ein Image erfasst und gespeichert wurde, werden die folgenden Handler aufgerufen. Wenn der Prozess erfolgreich ist, wird das Ergebnis zur Analyse an den VisionManager übergeben (den Sie noch erstellen müssen).

        /// <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. Fügen Sie dann die Methode hinzu, die von der Anwendung zum Starten des Bildaufnahmeprozesses und zum Speichern des Bilds verwendet wird.

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

Warnung

An diesem Punkt wird im Konsolenbereich des Unity-Editors ein Fehler angezeigt. Dies liegt daran, dass der Code auf die VisionManager-Klasse verweist, die Sie im nächsten Kapitel erstellen.

Kapitel 7: Aufruf von Azure und Bildanalyse

Das letzte Skript, das Sie erstellen müssen, ist die VisionManager-Klasse .

Diese Klasse ist für Folgendes zuständig:

  • Laden des neuesten Bilds, das als Bytearray erfasst wurde.
  • Senden des Bytearrays zur Analyse an Ihre Azure maschinelles Sehen API Service-instance.
  • Empfangen der Antwort als JSON-Zeichenfolge.
  • Deserialisieren der Antwort und Übergeben der resultierenden Tags an die ResultsLabel-Klasse .

So erstellen Sie diese Klasse:

  1. Doppelklicken Sie auf den Ordner Skripts , um ihn zu öffnen.

  2. Klicken Sie mit der rechten Maustaste in den Ordner Skripts, und klicken Sie auf C#-Skript erstellen>. Nennen Sie das Skript VisionManager.

  3. Doppelklicken Sie auf das neue Skript, um es mit Visual Studio zu öffnen.

  4. Aktualisieren Sie die Namespaces so, dass sie am Anfang der VisionManager-Klasse mit den folgenden übereinstimmen:

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Am Anfang Ihres Skripts müssen Sie in der VisionManager-Klasse (oberhalb der Start()-Methode zwei Klassen erstellen, die die deserialisierte JSON-Antwort von Azure darstellen:

        [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;
        }
    

    Hinweis

    Für die Klassen TagData und AnalysedObject muss das [System.Serializable] -Attribut vor der Deklaration hinzugefügt werden, um mit den Unity-Bibliotheken deserialisiert werden zu können.

  6. In der VisionManager-Klasse sollten Sie die folgenden Variablen hinzufügen:

        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;
    

    Warnung

    Stellen Sie sicher, dass Sie Ihren Authentifizierungsschlüssel in die Variable authorizationKey einfügen. Zu Beginn dieses Kurses, Kapitel 1, haben Sie ihren Authentifizierungsschlüssel notiert.

    Warnung

    Die Variable visionAnalysisEndpoint kann sich von der in diesem Beispiel angegebenen variable unterscheiden. West-US bezieht sich streng auf Dienstinstanzen, die für die Region "USA, Westen" erstellt wurden. Aktualisieren Sie dies mit Ihrer Endpunkt-URL. Im Folgenden finden Sie einige Beispiele dafür, wie dies aussehen könnte:

    • Europa, Westen: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Südostasien: https://southeastasia.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • Australien, Osten: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. Code für Awake muss jetzt hinzugefügt werden.

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. Fügen Sie als Nächstes die Coroutine (mit der statischen Streammethode darunter) hinzu, die die Ergebnisse der Analyse des Bilds abruft, das von der ImageCapture-Klasse erfasst wurde.

        /// <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. Speichern Sie ihre Änderungen in Visual Studio , bevor Sie zu Unity zurückkehren.

  10. Klicken Sie zurück im Unity-Editor auf die Klassen VisionManager und ImageCapture aus dem Ordner Skripts in das Objekt Hauptkamera im Hierarchiebereich.

Kapitel 8 – Vor dem Aufbau

Um einen gründlichen Test Ihrer Anwendung durchzuführen, müssen Sie sie auf Ihre HoloLens querladen. Stellen Sie zunächst Folgendes sicher:

  • Alle in Kapitel 2 erwähnten Einstellungen sind ordnungsgemäß festgelegt.
  • Alle Skripts sind an das Hauptkameraobjekt angefügt.
  • Alle Felder im Hauptkamerainspektorbereich sind ordnungsgemäß zugewiesen.
  • Stellen Sie sicher, dass Sie Ihren Authentifizierungsschlüssel in die Variable authorizationKey einfügen.
  • Stellen Sie sicher, dass Sie auch Ihren Endpunkt in Ihrem VisionManager-Skript überprüft haben und dass er auf Ihre Region ausgerichtet ist (in diesem Dokument wird standardmäßig west-us verwendet).

Kapitel 9: Erstellen der UWP-Lösung und Querladen der Anwendung

Alles, was für den Unity-Abschnitt dieses Projekts benötigt wird, wurde nun abgeschlossen, daher ist es an der Zeit, es aus Unity zu erstellen.

  1. Navigieren Sie zu Buildeinstellungen - Datei > Buildeinstellungen...

  2. Klicken Sie im Fenster Buildeinstellungen auf Erstellen.

    Erstellen der App aus Unity

  3. Wenn noch nicht geschehen, markieren Sie Unity C#-Projekte.

  4. Klicken Sie auf Erstellen. Unity startet ein Explorer Fenster, in dem Sie einen Ordner erstellen und dann auswählen müssen, in dem die App erstellt werden soll. Erstellen Sie diesen Ordner jetzt, und nennen Sie ihn App. Drücken Sie dann, wenn der Ordner App ausgewählt ist, Ordner auswählen.

  5. Unity beginnt mit dem Erstellen Ihres Projekts im Ordner App .

  6. Sobald Unity den Bau abgeschlossen hat (es kann einige Zeit dauern), öffnet es ein Explorer Fenster an der Position Ihres Builds (überprüfen Sie Ihre Taskleiste, da es möglicherweise nicht immer über Ihren Fenstern angezeigt wird, aber Sie über das Hinzufügen eines neuen Fensters benachrichtigt).

Kapitel 10: Bereitstellen in HoloLens

So stellen Sie auf HoloLens bereit:

  1. Sie benötigen die IP-Adresse Ihrer HoloLens (für Remote Deploy) und um sicherzustellen, dass sich Ihre HoloLens im Entwicklermodus befindet. Gehen Sie dazu folgendermaßen vor:

    1. Öffnen Sie die Einstellungen, während Sie Ihre HoloLens tragen.
    2. Wechseln Sie zu Netzwerk & Internet > Wi-Fi > Erweiterte Optionen.
    3. Notieren Sie sich die IPv4-Adresse .
    4. Navigieren Sie als Nächstes zurück zu Einstellungen und dann zu Aktualisieren & Sicherheit > für Entwickler.
    5. Legen Sie den Entwicklermodus ein.
  2. Navigieren Sie zu Ihrem neuen Unity-Build (dem Ordner App ), und öffnen Sie die Projektmappendatei mit Visual Studio.

  3. Wählen Sie in der Projektmappenkonfiguration debuggen aus.

  4. Wählen Sie auf der Lösungsplattform die Option x86, Remotecomputer aus.

    Stellen Sie die Projektmappe aus Visual Studio bereit.

  5. Wechseln Sie zum Menü Erstellen , und klicken Sie auf Lösung bereitstellen, um die Anwendung in Ihre HoloLens querzuladen.

  6. Ihre App sollte jetzt in der Liste der installierten Apps auf Ihrer HoloLens angezeigt werden, bereit für den Start!

Hinweis

Legen Sie für die Bereitstellung auf einem immersiven Headset die Lösungsplattform auf Lokaler Computer fest, und legen Sie die Konfiguration auf Debuggen fest, wobei x86 als Plattform verwendet wird. Stellen Sie dann auf dem lokalen Computer bereit, und wählen Sie im Menü Erstellen die Option Lösung bereitstellen aus.

Ihre fertige maschinelles Sehen-API-Anwendung

Herzlichen Glückwunsch! Sie haben eine Mixed Reality-App erstellt, die die Azure maschinelles Sehen-API nutzt, um reale Objekte zu erkennen und die Zuverlässigkeit des Gesehenen anzuzeigen.

Lab-Ergebnis

Zusatzübungen

Übung 1

Genau wie Sie den Tags-Parameter verwendet haben (wie innerhalb des im VisionManager verwendeten Endpunkts nachgewiesen), erweitern Sie die App, um andere Informationen zu erkennen. sehen Sie sich hier an, auf welche parameter Sie Zugriff haben.

Übung 2

Zeigen Sie die zurückgegebenen Azure-Daten in einer konversationsorientierten und lesbareren Weise an, wobei sie möglicherweise die Zahlen ausblenden. Als ob ein Bot mit dem Benutzer spricht.