AzureFunctionsのFaceLocatorCSharpを試してみる

スポンサーリンク

最近ようやくAzure Functionsに本腰入れ始めましてVisual Studioで開発できるようにSDKやらToolsやらをインストールしました。

テンプレートが結構あったのでFaceLocatorCSharpを先ずは試してみようとして四苦八苦した内容を記載していきます。

※この情報は2017年1月31日時点の情報となります。

※Visual Studio 2015でローカル実行した情報となります。

事前作業

前提としてVisual Studio 2015 Update 3 がインストールされていることとします。

インストールされていなければこちらからCommunityエディションをインストールしてください。

まずは下記のSDKをインストールしましょう。

Azure 2.9.6 .NET SDK 

Download and install Visual Studio Tools for Azure Functions

インストールが完了するとVisual StudioのテンプレートにAzure Funcitonsが追加されています。

FaceLocatorCSharpの構築

いろんなサンプルがありますがここでは流行に乗ってFaceLocatorCSharpを選択します。

これはVisionAPIを利用して画像中の顔の位置を四角で囲むための始点と縦横の幅の情報をAzure Storage Tableに登録する処理のテンプレートです。

それでは早速作っていきましょう。

Fucntionsのプロジェクトを作成し、Fucntionsのプロジェクトを右クリックして「追加」から「New Azure Function」を選択します。

Azure Functionのテンプレートがプログラミング言語ごとに用意されています。

ここではC#のFaceLocator-C#を選択します。

プロジェクトを作成するときにAzure Storageの接続文字列を要求されるので準備しておきましょう。

因みにNAME:KEYのセットではなく接続文字列で指定する必要がありますので下記を参考にしてください。

DefaultEndpointsProtocol=https;AccountName=[NAME];AccountKey=[KEY]

FaceLocatorは指定のAzureStorageに画像ファイル(jpg)がアップロードされると自動的にフックしてVisionAPIに送信して顔画像の場所情報をアウトプット用のAzureStorageTableに出力します。

なのでInput用のStorageとOutput用のStorageを指定する必要があります。2つのSotrageは同じものでもかまいません。

プロジェクトを作成すると下図のようになると思います。

ここからもうひと手間があります。各種設定を書き換えないといけません。

プロジェクト作成時に入力したAzureStorageの接続情報がFaceLocatorCSharp配下のfunction.jsonに記載されているのですが、その他内容を一つ上の階層のappsetting.jsonに転記する必要があります。

また、VisionAPIのKEYの設定も必要となります。

この作業を行わないと実行時にエラーになりますので注意してください。

appsettings.jsonの内容を変更

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=[NAME];AccountKey=[KEY]", ←ここを書き換える
    "AzureWebJobsDashboard": ""
  }
}

function.jsonの内容を変更

{
  "bindings": [
    {
      "type": "blobTrigger",
      "name": "image",
      "path": "images/{name}.jpg",
      "connection": "AzureWebJobsStorage", ←ここをappsettings.jsonのKEY名に変更する
      "direction": "in"
    },
    {
      "type": "table",
      "name": "outTable",
      "tableName": "faceRectangle",
      "connection": "AzureWebJobsStorage", ←ここをappsettings.jsonのKEY名に変更する
      "direction": "out"
    }
  ],
  "disabled": false
}

VisionAPIのKEYを設定します。

VisoinAPIのKEYはこちらか取得してください。FaceAPIではないので注意が必要です。

取得したら下記のように変更してください。

run.csx

{
    var content = new StreamContent(image);
    var url = "https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures=Faces";
    //client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key")); ←コメントアウト
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", [VisionAPIのKEY]); ←上記をコピーしてKEYを転記
    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    var httpResponse = await client.PostAsync(url, content);

    if (httpResponse.StatusCode == HttpStatusCode.OK)
    {
        return await httpResponse.Content.ReadAsStringAsync();
    }
}

設定が終わったら実行してみましょう。

初夏実行時にAzure Functions CLI Toolがインストールされていない場合、下図のようにインストールを求められるので実行します。

インストールが完了したら実行されると思います。

下記のように表示されたら成功です。

赤い文字や黄色い文字で警告文が表示された場合は何処かでエラーになっていますのでエラー内容を対処しましょう。

動作確認

VisualSutdioで実行したら動作確認を行います。

動作確認を行うためにここではAzure Storage Exploreを利用します。

インストールしてない場合はインストールしてください。

Input用のimagesコンテナを作成します。これはプロジェクトのテンプレートに指定されているのであわせてください。

function.json

{
  "bindings": [
    {
      "type": "blobTrigger",
      "name": "image",
      "path": "images/{name}.jpg", ← コンテナ名をパスに合わせる(逆でもOK)
      "connection": "AzureWebJobsStorage",
      "direction": "in"
    },
    {
      "type": "table",
      "name": "outTable",
      "tableName": "faceRectangle",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    }
  ],
  "disabled": false
}

Functionsで指定したAzure Storageにjpgファイルを投入します。

Googleの画像検索で顔が写っているフリー画像を任意に取得してください。

処理のトリガーとなるのは「Azure Storageのimagesというコンテナにjpgのファイルが配置された時」です。

アウトプット(処理の結果)として「VisionAPIのレスポンスをAzure Storage TableのfaceRectangleテーブルにデータを出力」となります。

ここではテンプレート通りの処理にしていますが、自分で処理を追記すればVisionAPIのレスポンスデータを下に画像の顔の部分に四角の枠を描画することも可能です。

実行ログをFunctionsのコンソール画面で確認することができます。

上の図は成功した時の状態です。インプットのファイル情報とアウトプットの顔の位置情報が取得できているのが解ります。

処理が成功すればfaceRectangleテーブルに顔の位置情報が入力されていると思います。

これで環境構築から実行まで一通りできるようになったかと思います。

FunctionsプロジェクトからAzurenにデプロイすることも可能です。

WebAppsを公開するのと同じ要領なのでここでは割愛します。

まとめ

案外簡単そうに出来て実のところ罠が多くて一通りの手順をまわすのに時間がかかりました。Portal側とVSテンプレート側で差異のある部分を見極めてしまえば些細なことですが・・・。

GitHubと連携したCIデプロイが出来たり、ライブストリーミング監視ができたりと慣れてくれば簡単に小規模な処理を実装して運用することが出来ます。

AppServiceを複数たててサービス毎に処理をわけて運用すれば簡単にマイクロサービスの概念を導入できたりするんだろうなと愚考もしてます。

弱点としてVisual がC#スクリプトのインテリセンスやコード保管をデフォルトで対応していないため、Visual Studioだとしても編集するのは困難です。C#スクリプトが今後どうなるかわかりませんが、Functionsに関しては結構注目度の高いサービスだなと思います。

面白くなってきたので全てのテンプレートを試してみようかなと思います・・・時間があれば・・・・。

参考

コメント