HoloLens (第 1 代) 和 Azure 302:電腦視覺


注意

混合實境學院教學課程的設計是以 HoloLens (第 1 代) 和混合實境沉浸式頭戴裝置為準。 因此,對於仍在尋找這些裝置開發指引的開發人員而言,我們覺得這些教學課程很重要。 這些教學課程不會使用用於 HoloLens 2 的最新工具組或互動進行更新。 系統會保留這些資訊,以繼續在支援的裝置上運作。 未來將會張貼一系列新的教學課程,示範如何針對 HoloLens 2 進行開發。 此通知會在張貼時更新這些教學課程的連結。


在此課程中,您將瞭解如何使用混合實境應用程式中的 Azure 電腦視覺 功能來辨識所提供影像內的視覺內容。

辨識結果會顯示為描述性標記。 您可以使用這項服務,而不需要定型機器學習模型。 如果您的實作需要定型機器學習模型,請參閱 MR 和 Azure 302b

實驗室結果

Microsoft 電腦視覺 是一組 API,其設計目的是為開發人員提供影像處理和分析 (,以及使用進階演算法從雲端傳回資訊) 。 開發人員上傳影像或影像 URL,而 Microsoft 電腦視覺 API 演算法會根據所選使用者的輸入來分析視覺內容,然後可以傳回資訊,包括識別影像的類型和品質、偵測人臉 (傳回其座標) ,以及標記或分類影像。 如需詳細資訊,請流覽 Azure 電腦視覺 API 頁面

完成此課程之後,您將擁有混合實境 HoloLens 應用程式,其可以執行下列動作:

  1. 使用點選手勢,HoloLens 的相機會擷取影像。
  2. 映像會傳送至 Azure 電腦視覺 API 服務。
  3. 辨識的物件會列在位於 Unity 場景的簡單 UI 群組中。

在您的應用程式中,您必須先瞭解如何將結果與您的設計整合。 本課程旨在教導您如何整合 Azure 服務與您的 Unity 專案。 您的工作是使用此課程取得的知識來增強混合實境應用程式。

裝置支援

課程 HoloLens 沉浸式頭戴裝置
MR 和 Azure 302:電腦視覺 ✔️ ✔️

注意

雖然本課程主要著重於 HoloLens,但您也可以將此課程中學到的內容套用至 Windows Mixed Reality 沉浸式 (VR) 頭戴裝置。 由於沉浸式 (VR) 頭戴式裝置沒有可存取的相機,因此您需要連線到計算機的外部相機。 隨著課程一起進行時,您會看到可能需要採用的任何變更附註,以支援沉浸式 (VR) 頭戴裝置。

必要條件

注意

本教學課程專為具備 Unity 和 C# 基本體驗的開發人員所設計。 另請注意,本檔中的必要條件和書面指示代表在撰寫 (2018 年 5 月) 時已測試及驗證的內容。 您可以隨意使用最新的軟體,如 安裝工具 一文中所列,但不應該假設本課程中的資訊會完全符合您在較新軟體中找到的內容,而不是下面所列的內容。

針對本課程,我們建議使用下列硬體和軟體:

開始之前

  1. 若要避免建置此專案時發生問題,強烈建議您在根資料夾或近根資料夾中建立本教學課程中提及的專案, (長資料夾路徑可能會導致建置時間) 的問題。
  2. 設定及測試 HoloLens。 如果您需要設定 HoloLens 的支援, 請務必流覽 HoloLens 設定一文
  3. 在開始開發新的 HoloLens 應用程式時,最好執行校正和感測器微調 (有時有助於針對每個使用者執行這些工作) 。

如需校正的說明,請遵循此 連結至 HoloLens 校正文章

如需感測器微調的說明,請遵循此 連結至 HoloLens 感測器微調文章

第 1 章 – Azure 入口網站

若要在 Azure 中使用 電腦視覺 API 服務,您必須將服務的實體設定為可供您的應用程式使用。

  1. 首先,登入 Azure 入口網站

    注意

    如果您還沒有 Azure 帳戶,則必須建立一個帳戶。 如果您在教室或實驗室案例中遵循本教學課程,請詢問講師或其中一個專業人員,以協助設定新的帳戶。

  2. 登入之後,按兩下左上角的 [新增],然後搜尋 電腦視覺 API,然後按兩下 Enter

    在 Azure 中建立新的資源

    注意

    New 一詞可能已取代為在較新的入口網站中建立資源

  3. 新頁面會提供 電腦視覺 API 服務的描述。 在此頁面左下方,選取 [ 建立 ] 按鈕,以建立與此服務的關聯。

    關於電腦視覺 API 服務

  4. 按兩下 [ 建立] 之後:

    1. 插入此服務實例所需的 Name

    2. 選取 [訂用帳戶] 。

    3. 選取適合您的定價層,如果這是第一次建立 電腦視覺 API 服務,您應該可以使用名為 F0) 的免費層 (。

    4. 選擇 資源群組 或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。 建議您保留與單一專案相關聯的所有 Azure 服務 (例如,這些實驗室) 在通用資源群組底下) 。

      如果您想要深入瞭解 Azure 資源群組,請 瀏覽資源群組一文

    5. 如果您要建立新的資源群組) ,請判斷資源群組的位置 (。 在理想情況下,位置會位於應用程式執行所在的區域中。 某些 Azure 資產僅適用於特定區域。

    6. 您也必須確認您已瞭解套用至此服務的條款及條件。

    7. 按一下 [建立]。

      服務建立資訊

  5. 按兩下 [ 建立] 之後,您必須等候服務建立,這可能需要一分鐘的時間。

  6. 建立服務實例之後,入口網站中會出現通知。

    查看新服務的新通知

  7. 按兩下通知以探索新的服務實例。

    選取 [移至資源] 按鈕。

  8. 按兩下通知中的 [ 移至資源] 按鈕,以探索新的服務實例。 系統會將您帶至新的 電腦視覺 API 服務實例。

    您的新 電腦視覺 API 服務映像

  9. 在本教學課程中,您的應用程式必須呼叫您的服務,這是透過使用您服務的訂用帳戶密鑰來完成的。

  10. 電腦視覺 API 服務的 [快速入門] 頁面中,流覽至第一個步驟:擷取金鑰,然後按下 [金鑰] (您也可以按下位於服務導覽功能表中的藍色超連結 [金鑰],以) 表示。 這會顯示您的服務 金鑰

  11. 擷取其中一個顯示金鑰的複本,因為您稍後會在專案中需要此複本。

  12. 返回 至 [快速入門] 頁面,然後從該處擷取您的端點。 請注意,視您的區域而定,視您的區域而定 (,您必須在稍後變更程式代碼) 。 取得此端點的複本以供稍後使用:

    新的 電腦視覺 API 服務

    提示

    您可以在這裏檢查各種端點。

第 2 章 – 設定 Unity 專案

以下是使用混合實境進行開發的一般設定,因此是其他專案的良好範本。

  1. 開啟 Unity ,然後按兩下 [ 新增]。

    啟動新的 Unity 專案。

  2. 您現在必須提供 Unity 項目名稱。 插入 MR_ComputerVision。 請確定專案類型已設定為 3D。 將 [位置] 設定為適合您 (記住的位置,更接近根目錄) 。 然後按兩下 [建立專案]。

    提供新 Unity 專案的詳細數據。

  3. 開啟 Unity 時,值得檢查預設 的腳本編輯器 已設定為 Visual Studio。 移至 [編輯 > 喜好設定 ],然後從新視窗中流覽至 [外部工具]。 將 外部腳本編輯器 變更為 Visual Studio 2017。 關閉 [喜好設定] 視窗。

    更新文本編輯器喜好設定。

  4. 接下來,移至 [檔案>建置設定],然後選取 [通用 Windows 平台],然後按兩下 [切換平臺] 按鈕以套用您的選擇。

    [建置設定] 視窗,將平臺切換至 UWP。

  5. 仍在 [檔案 > 建置設定 ] 中,並確定:

    1. 目標裝置 設定為 HoloLens

      針對沉浸式頭戴式裝置,將 [目標裝置 ] 設定為 [任何裝置]。

    2. 組建類型 設定為 D3D

    3. SDK 設定為 [最新安裝]

    4. Visual Studio 版本 設定為 [最新安裝]

    5. [建置並執行 ] 設定為 [本機計算機]

    6. 儲存場景,並將它新增至組建。

      1. 選取 [ 新增開啟場景] 來執行此動作。 隨即會出現儲存視窗。

        按兩下 [新增開啟的場景] 按鈕

      2. 為此建立新的資料夾,以及任何未來的場景,然後選取 [ 新增資料夾 ] 按鈕,以建立新的資料夾,將它命名為 Scenes

        建立新的腳本資料夾

      3. 開啟新建立 的 Scenes 資料夾,然後在 [ 檔名:文字] 字段中,輸入 MR_ComputerVisionScene,然後按兩下 [ 儲存]。

        為新的場景指定名稱。

        請注意,您必須將 Unity 場景儲存在 Assets 資料夾中,因為它們必須與 Unity 專案相關聯。 建立場景資料夾 (和其他類似資料夾) 是建構 Unity 專案的一般方式。

    7. 其餘設定在 [建置設定] 中,現在應該保留為預設值。

  6. 在 [ 建置設定 ] 視窗中,按兩下 [ 播放機設定 ] 按鈕,這會在 Inspector 所在的空間中開啟相關的面板。

    開啟播放機設定。

  7. 在此面板中,需要驗證一些設定:

    1. 在 [ 其他設定] 索引 標籤中:

      1. 腳本運行時間版本 應該是 穩定 (.NET 3.5 對等) 。

      2. 腳本後端 應該是 .NET

      3. API 相容性層級 應該是 .NET 4.6

        更新其他設定。

    2. 在 [ 發佈設定] 索引標籤的 [ 功能] 底下,檢查:

      1. InternetClient

      2. 網路攝影機

        更新發佈設定。

    3. 在面板下方,在 [XR 設定] (中找到 [發佈設定]) ,勾選 [支援的虛擬實境],確定已新增 Windows Mixed Reality SDK

      更新 X R 設定。

  8. 回到 組建設定Unity C# 專案不再呈現灰色;勾選此旁邊的複選框。

  9. 關閉 [建置設定] 視窗。

  10. 儲存場景和專案 (檔案 > 儲存場景/檔案 > 儲存專案) 。

第 3 章 – 主要相機設定

重要

如果您想要略過本課程的 Unity 設定 元件,並繼續進入程式碼,請隨意下載此 .unitypackage、將它匯入您的專案作為 自定義套件,然後從 第 5 章繼續進行。

  1. 在 [ 階層] 面板中,選取 [主相機]。

  2. 選取之後,您就可以在 [偵測器] 面板中看到主要相機的所有元件。

    1. Camera 對象必須命名為主相機 (記下拼字!)

    2. 主相機 標籤 必須設定為 MainCamera (記下拼字!)

    3. 確定 [轉換位置 ] 設定為 0、0、0

    4. [清除旗標] 設定為 [純色 ], (針對沉浸式頭戴式裝置) 忽略此功能。

    5. 將相機元件 的背景 色彩設定為 黑色、Alpha 0 (十六進位碼:#0000000000 ) (忽略沈浸式頭戴式裝置) 。

      更新相機元件。

  3. 接下來,您必須建立附加至 主相機的簡單「游標」物件,這可協助您在應用程式執行時放置影像分析輸出。 此游標會決定相機焦點的中心點。

若要建立資料指標:

  1. 在 [ 階層] 面板中,以滑鼠右鍵按兩下 主要相機。 在 [3D 物件] 下,按兩下 [Sphere]。

    選取 Cursor 物件。

  2. Sphere 重新命名為 Cursor (按下 Cursor 物件,或按下 [F2] 鍵盤按鈕並選取物件) ,並確定它位於 主相機的子系。

  3. 在 [階層] 面板中,以滑鼠左鍵按兩下游標。 選取 [游標] 之後,在 [偵測器] 面板中調整下列變數:

    1. [轉換位置] 設定為 0、0、5

    2. Scale 設定為 0.02、0.02、0.02

      更新轉換位置和縮放比例。

第 4 章 – 設定標籤系統

使用 HoloLens 相機擷取影像之後,該影像將會傳送至您的 Azure 電腦視覺 API 服務實例進行分析。

該分析的結果將會是稱為 Tags的已辨識物件清單。

您將使用標籤 (做為世界空間中的 3D 文字,) 在拍攝相片的位置顯示這些標籤。

下列步驟將示範如何設定 Label 物件。

  1. 以滑鼠右鍵按兩下 [階層面板] 中的任何位置, (位置此時) 3D 物件底下新增 3D Text。 將它命名為 LabelText

    建立 3D Text 物件。

  2. 在 [ 階層] 面板中,按兩下 [ LabelText]。 選取 LabelText 之後,請在 [偵測器面板] 中調整下列變數:

    1. [位置] 設定為 0,0,0
    2. Scale 設定為 0.01、0.01、0.01
    3. 元件文字格中
    4. 以 “...” 取代 Text 中的所有文字
    5. 錨點 設定為 中間中心
    6. 對齊 設定為 置中
    7. 索引標籤大小 設定為 4
    8. [字型大小] 設定為 50
    9. [色彩 ] 設定為 [#FFFFFFFF

    文字元件

  3. LabelText[階層面板] 拖曳至 [項目面板] 內的 [資產資料夾]。 這會使 LabelText 成為預製物件,使其可以在程式代碼中具現化。

    建立 LabelText 物件的預製專案。

  4. 您應該從階層面板刪除 LabelText,使其不會顯示在開啟場景中。 由於現在是預製專案,因此您將從 [資產] 資料夾針對個別實例呼叫該預製專案,因此不需要將其保留在場景中。

  5. 階層面板中的最後一個對象結構應該像下圖所示:

    階層面板的最終結構。

第 5 章 – 建立 ResultsLabel 類別

您需要建立的第一個腳本是 ResultsLabel 類別,負責下列事項:

  • 在適當的世界空間中建立標籤,相對於相機的位置。
  • 顯示影像 Anaysis 中的標記。

若要建立此類別:

  1. 以滑鼠右鍵按兩下 [項目面板],然後按兩下 [ 建立 > 資料夾]。 將資料夾命名為 Scripts

    建立 scripts 資料夾。

  2. 建立 腳本 資料夾后,按兩下它以開啟。 然後在該資料夾中按兩下滑鼠右鍵,然後選取 [建立 > ] 和 [ C# 腳本]。 將腳本命名為 ResultsLabel

  3. 按兩下新的 ResultsLabel 腳稿,以使用 Visual Studio 加以開啟。

  4. 在類別內,在 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. 請務必先將變更儲存在 Visual Studio 中,再返回 Unity

  6. 回到 Unity 編輯器,按兩下 [腳稿] 資料夾的 ResultsLabel 類別,並將其拖曳至 [階層] 面板中的主相機物件。

  7. 按兩下 [主要相機 ],然後查看 [偵測器面板]。

您會注意到,從您剛拖曳到相機的腳本中,有兩個字段: 游標標籤預製專案

  1. 將名為 Cursor 的物件從 [階層面板 ] 拖曳到名為 Cursor 的位置,如下圖所示。

  2. 將名為 LabelText 的物件從 [項目面板] 中的 [資產資料夾] 拖曳至名為 Label Prefab 的位置,如下圖所示。

    在 Unity 中設定參考目標。

第 6 章 – 建立 ImageCapture 類別

您要建立的下一個類別是 ImageCapture 類別。 此類別負責:

  • 使用 HoloLens 相機擷取影像,並將其儲存在應用程式資料夾中。
  • 從使用者擷取點選手勢。

若要建立此類別:

  1. 移至您先前建立的 Scripts 資料夾。

  2. 以滑鼠右鍵按兩下資料夾內的 [建立 > C# 文稿]。 呼叫 ImageCapture 腳本。

  3. 按兩下新的 ImageCapture 腳稿,以使用 Visual Studio 加以開啟。

  4. 將下列命名空間新增至檔案頂端:

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. 然後在 ImageCapture 類別的 Start () 方法上方新增下列變數:

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

tapsCount 變數會儲存從使用者擷取的點選手勢數目。 這個數位用於擷取的影像命名。

  1. 現在必須新增 Awake () Start () 方法的程序代碼。 當類別初始化時,將會呼叫這些專案:

        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. 實作會在點選手勢發生時呼叫的處理程式。

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

TapHandler () 方法會遞增從使用者擷取的點選數目,並使用目前的 Cursor 位置來判斷新標籤的位置。

此方法接著會呼叫 ExecuteImageCaptureAndAnalysis () 方法,以開始此應用程式的核心功能。

  1. 擷取並儲存映像之後,將會呼叫下列處理程式。 如果程式成功,結果會傳遞至 VisionManager (,而您尚未建立) 進行分析。

        /// <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. 然後,新增應用程式用來啟動映像擷取程式並儲存映像的方法。

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

警告

此時,您會注意到 Unity 編輯器主控台面板中出現錯誤。 這是因為程式代碼會參考您將在下一章中建立的 VisionManager 類別。

第 7 章 – 呼叫 Azure 和影像分析

您需要建立的最後一個腳本是 VisionManager 類別。

此類別負責:

  • 載入擷取為位元組數位的最新影像。
  • 將位元組數位傳送至 Azure 電腦視覺 API 服務實例進行分析。
  • 以 JSON 字串形式接收回應。
  • 將回應還原串行化,並將產生的Tags傳遞至 ResultsLabel 類別。

若要建立此類別:

  1. 按兩下 [文稿 ] 資料夾,將其開啟。

  2. [腳本 ] 資料夾內按下滑鼠右鍵,按兩下 [建立 > C# 腳稿]。 將腳本命名為 VisionManager

  3. 按兩下新的文稿,以使用Visual Studio加以開啟。

  4. VisionManager 類別頂端,將命名空間更新為與下列相同:

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. 在腳本頂端的 VisionManager 類別, (Start () 方法) 上方,您現在必須建立兩個類別,以代表來自 Azure 的還原串行化 JSON 回應:

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

    注意

    TagDataAnalysisdObject 類別必須在宣告之前加入 [System.Serializable] 屬性,才能使用 Unity 連結庫還原串行化。

  6. 在 VisionManager 類別中,您應該新增下列變數:

        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;
    

    警告

    請務必將 驗證金鑰 插入 authorizationKey 變數。 您在本課程的第 1 章開頭將記下您的驗證金鑰

    警告

    visionAnalysisEndpoint 變數可能與此範例中指定的變數不同。 美國西部嚴格是指為美國西部區域建立的服務實例。 使用 您的端點 URL 更新此值;以下是一些可能看起來如下的範例:

    • 西歐: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • 東南亞: https://southeastasia.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • 澳大利亞東部: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. 現在必須新增 Awake 的程式代碼。

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. 接下來,將協同程式 (與其下方的靜態數據流方法新增) ,這會取得 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. 請務必先將變更儲存在 Visual Studio 中,再返回 Unity

  10. 回到 Unity 編輯器,按兩下 [VisionManager] 和 [ImageCapture] 類別,並將其從 [腳本] 資料夾拖曳至 [階層面板] 中的 [主要相機] 物件。

第 8 章 – 建置之前

若要執行應用程式的完整測試,您必須將它側載至 HoloLens。 在您這麼做之前,請確定:

  • 第2章中所述的所有設定都已正確設定。
  • 所有腳本都會附加至 主要相機 物件。
  • [主要相機偵測器] 面板中的所有欄位都會正確指派。
  • 請務必將 驗證金鑰 插入 authorizationKey 變數。
  • 請確定您已在 VisionManager 腳本中檢查您的端點,而且它符合 您的 區域, (本文件預設會使用 美國西部) 。

第 9 章 – 建置 UWP 解決方案並側載應用程式

此專案的 Unity 區段所需的所有項目現在都已完成,因此是時候從 Unity 建置它了。

  1. 流覽至 [組建配置檔 - >] [組建設定...]

  2. 從 [ 建置設定] 視窗中,按兩下 [ 建置]。

    從 Unity 建置應用程式

  3. 如果尚未這麼做,請勾選 Unity C# 專案

  4. 按一下 [建置]。 Unity 會啟動 檔案總管 視窗,您需要在其中建立,然後選取要建置應用程式的資料夾。 立即建立該資料夾,並將它命名為 應用程式。 然後選取 [應用程式 ] 資料夾,然後按 [選取資料夾]。

  5. Unity 會開始將專案建置至 [應用程式 ] 資料夾。

  6. 一旦 Unity 完成建置 (可能需要一些時間) ,它會在組建的位置開啟 檔案總管 視窗, (檢查您的任務欄,因為它不一定會出現在您的視窗上方,但會通知您新增視窗) 。

第 10 章 – 部署至 HoloLens

若要在 HoloLens 上部署:

  1. 您將需要 HoloLens (的 IP 位址以進行遠端部署) ,並確保 HoloLens 處於 開發人員模式。 作法如下:

    1. 在戴上 HoloLens 時,開啟 [ 設定]。
    2. 移至 網路 & 因特網 > Wi-Fi > 進階選項
    3. 請注意 IPv4 位址。
    4. 接下來,流覽回 [設定],然後流覽回 [更新開發人員安全性 & 安全性>]
    5. 設定 [開啟開發人員模式]。
  2. 流覽至新的 Unity 組建, (應用程式 資料夾) ,並使用 Visual Studio 開啟方案檔。

  3. 在 [方案組態] 中,選取 [ 偵錯]。

  4. 在 [解決方案平臺] 中,選取 [x86]、[ 遠端計算機]。

    從 Visual Studio 部署解決方案。

  5. 移至 [ 建置] 功能表 ,然後按兩下 [ 部署解決方案],將應用程式側載至HoloLens。

  6. 您的應用程式現在應該會出現在您的 HoloLens 上安裝的應用程式清單中,準備好啟動!

注意

若要部署至沉浸式頭戴式裝置,請將 [解決方案平臺 ] 設定為 [ 本機計算機],並將 [組 ] 設定為 [ 錯],並將 x86 設定為 [平臺]。 然後使用 [建置] 功能表,選取 [ 部署解決方案],部署至本機計算機。

您已完成 電腦視覺 API 應用程式

恭喜,您已建置混合實境應用程式,利用 Azure 電腦視覺 API 來辨識真實世界物件,並顯示所看到專案的信賴度。

實驗室結果

額外練習

練習 1

如同您已使用 Tags 參數 (做為 VisionManager) 內所使用端點內的辨識項,請擴充應用程式以偵測其他資訊;請查看您可以存取 HERE 的其他參數。

練習 2

以更交談且可讀的方式顯示傳回的 Azure 數據,或許隱藏數位。 就像 Bot 可能正在向使用者說話一樣。