MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「MR and Azure 302 7章」を試してみる

本日はチュートリアルの実施枠です。
Academyの「MR and Azure 302: Computer vision」の実施内容をまとめます。
docs.microsoft.com
前回記事の続きです。
bluebirdofoz.hatenablog.com
今回は「Chapter 7」です。

Chapter 7:Call to Azure and Image Analysis

最後に作成するスクリプトは VisionManager クラスです。
このクラスは以下を担当します。
・取得した最新のイメージをバイト配列としてロードします。
・解析のためにAzure Computer Vision API Serviceインスタンスにバイト配列を送信します。
・応答をJSON文字列として受け取る。
・レスポンスをデシリアライズし、結果のタグをResultsLabelクラスに渡します。

1.Script フォルダを開きます。
2.フォルダ内で右クリックして、Creapte -> C# Script を選択します。
Script の名称は VisionManager に設定します。
f:id:bluebirdofoz:20180815094204j:plain

3.新しいスクリプトをダブルクリックしてVisual Studioで開きます。
4-9.以下の通り、スクリプトを編集します。
・VisionManager.cs

// 名前空間の追加
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class VisionManager : MonoBehaviour {

    // Azureからの逆シリアル化されたJSON応答を表す2つのクラスを作成する
    [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;
    }

    // メンバ変数の追加
    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";
    // This is where you need to update your endpoint, if you set your location to something other than west-us.
    // ロケーションをwest-us以外の場所に設定した場合、エンドポイントを更新する必要があります。
    private string visionAnalysisEndpoint = "https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags";   

    internal byte[] imageBytes;

    internal string imagePath;

    private void Awake()
    {
        // allows this instance to behave like a singleton
        // このクラスをシングルトンと同じように動作させます 
        instance = this;
    }

    // ImageCaptureクラスでキャプチャした画像の解析結果を取得するコルーチン(静的ストリームメソッドを使用)を追加します
    /// <summary>
    /// Call the Computer Vision Service to submit the image.
    /// Computer Vision Service を呼び出して画像を送信します
    /// </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
            // ダウンロードハンドラは、Azureから分析を受け取るのに役立ちます
            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
                // 応答はJson形式になります
                //したがって、クラスをAnalysedObjectおよび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);
    }
}

※ 個人の環境に合わせて "-InsertYourAuthKeyHere-"の値を Chapter 1 で取得した Key 値に修正します。
"https://westus.api.cognitive.microsoft.com/~"の値も同様にエンドポイントの URL に修正します。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20180815094236j:plain

9.Visual Studio で変更を保存して Unity に戻ります。
f:id:bluebirdofoz:20180815094248j:plain

10.Scripts オブジェクトに Assets フォルダから VisionManagerおよびImageCaptureクラスをドラッグして適用します。
f:id:bluebirdofoz:20180815094319j:plain

Chapter 7 はここまでです。
次回は Chapter 8 ~ Chapter 10 を実施します。
bluebirdofoz.hatenablog.com