※本記事は2019年11月時点での情報です。
はじめに
本記事では、Azure Functions(v2,C#)のBlob Input Bindingの使用法をCognitive Serviceの利用を例として取り上げて紹介します。Blob Input Bindingの設定方法に関する記事が全く見つからなかったため、ドキュメントとして残しておくことにしました。今回はAzureポータルでの設定方法をご紹介します。
事前準備
・任意のCognitive Serviceのデプロイ
Cognitive Serviceをデプロイし、エンドポイントとキーをコピーしておきます。今回のサンプルでは、Face APIのEmotionを利用します。
・ストレージアカウントのデプロイ
ストレージアカウントをデプロイします。Functionsから呼び出すためには、「汎用」SKUを選ぶ必要があります。作成後、Blob Storageに任意の名前のコンテナを作成し、人物の顔が載っている写真を何枚かアップロードしてください。
・Functionsのデプロイ
Azure Functionsをデプロイします。今回のサンプルでは、.NET CORE(C#)を使用します。
Functionsの設定方法
本記事では、Azureポータルを使用した際の設定方法をご紹介します。
1.Blob Input Bindingの設定
Azure Functionsのデプロイ後、HTTP Triggerで任意の関数を作成します。作成後、「統合」タブをクリックすると、トリガーとバインディングを管理するための画面に遷移します。ここでは初めに、「入力」の設定をします。モジュールのインストールなどが完了したら、先ほど画像をアップロードしたストレージアカウントに接続をしてください。接続完了後、パスの設定を行います。パスは、コンテナ名/{name}としてください。
2.Suffixの設定
Blob Storage内の画像ファイル名をパラメータとして受け取るために、APIのSuffixを設定します。統合タブから「トリガー」の設定画面に移り、「ルートテンプレート」を設定してください。このサンプルでは、FaceEmotion/picture={name}という形で設定を行いました。{name}には、クエリパラメータとして渡された画像ファイル名が入ります。
3.function.jsonの確認
関数名をクリックし、ファイルの一覧からfunction.jsonを開いてください。このファイルには、トリガーやバインディングの設定情報が書かれています。Azureポータルからの設定では、先ほど設定内容がfunction.jsonに反映されないケースが稀にあるため、希望している設定がきちんと書かれているか、確認する必要があります。
4.ソースコードの作成
Blob Input Bindingを使って取ってきた画像ファイルをFace APIに投げるサンプルを作成しました。Cognitive Serviceでは、BlobのPathをBodyとして登録しなければなりません。Pathを取得するために、今回はCloudBlockBlobクラスのUriプロパティを利用しました。
参照1: https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage-blob?tabs=csharp-script#input---usage
参照2: https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.blob.cloudblockblob?view=azure-dotnet-legacy
# r "Newtonsoft.Json"
# r "Microsoft.WindowsAzure.Storage"
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Blob;
public static async Task<IActionResult> Run(HttpRequest req, CloudBlockBlob inputBlob, ILogger log)
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "<YOUR_SUBSCRIPTION_KEY>");
queryString["returnFaceAttributes"] = "emotion";
var uri = "https://<YOUR_FACE_API_SERVICE_NAME>.cognitiveservices.azure.com/face/v1.0/detect?" + queryString;
HttpResponseMessage response;
// Request body
string body = "{\"url\": " + $"\" {inputBlob.Uri} \"" + "}";
log.LogInformation($"C# Blob trigger function Processed blob\nURI:{body}");
byte[] byteData = Encoding.UTF8.GetBytes(body);
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response = await client.PostAsync(uri, content);
}
string contentString = await response.Content.ReadAsStringAsync();
return (ActionResult)new OkObjectResult($"{contentString}");
}
5.テスト
クエリパラメータとしてBlob Storageにアップロードした画像ファイル名を指定して、実験してみましょう。Face APIによって顔が検出されれば、顔の位置情報や感情スコアがJSON形式で表示されます。
※200OKでJSON配列が空の場合には、顔を検出できていないということになります。横顔などは検出されないため、お気を付けください。
さいごに
ソースコードはGitHubにも置いておきました。プルリクなどがありましたら、是非ともお願いいたします。