Azure Functions: FaceAPIとOpenCVで顔検出をしてみた。② -Face APIの利用-

スクリプトは以下のように作成しました。

coding: utf-8

01‐ライブラリのインポート

import os
import json
import requests
import imghdr

def main():

inputimgpath = os.environ["triggerImage"]
result_path = os.environ["resultJson"]

02‐Face API未対応フォーマット判定

print("Checking input image format")
imgformat = imghdr.what(inputimg_path)

if img_format not in ["jpeg", "png", "bmp", "gif"]:
status = {"status": "error"}

if img_format == None:
status["message"] = "Input file is not image."
else:
status["message"] = "Unsupported image format."

print(status)

with open(result_path, "w") as f:
json.dump(status, f, indent=4)

return

03‐Face APIで顔検出

print("Detecting faces")
faceapilocation = "westus"
faceapikey = "{Face APIキー}"

url = "https://{location}.api.cognitive.microsoft.com/face/v1.0/{function}".format(location=faceapilocation, function="detect")

headers = {
"Content-Type": "application/octet-stream",
"Ocp-Apim-Subscription-Key": faceapikey
}

params = {
"returnFaceId": True,
"returnFaceLandmarks": False,
"returnFaceAttributes": "age,gender,smile,emotion"
}

res = requests.request("POST", url, headers=headers, params=params, data=open(inputimgpath, "rb"))
detect_data = res.json()

04‐顔検出結果をJSONで出力

print("Output detect result as JSON.")
with open(result_path, "w") as f:
json.dump(detect_data, f, indent=4)

if _name == "main_":
main()

スクリプトの説明

スクリプトの内容は以下の通りです。

01‐ライブラリのインポート

処理に必要なライブラリを指定してインポートします。

Face APIに対するリクエストを実行するため、外部ライブラリ「requests」を使用しています。

※ 「requests」については

前回の手順 で予めインストールしておきます。

02‐Face API未対応フォーマット判定

トリガーとしてアップロードされたファイルがFace APIの対応フォーマット(JPEG、PNG、BMP、GIF)に該当するか判定します。

Azure Functionsでは、os.environ[“トリガーバインド名”]に格納されたパスにアップロードデータのコピーがあるため、標準ライブラリ「imghdr」を使用して画像フォーマットを判定し、対応フォーマットのみを選別します。

03‐Face APIで顔検出

Face APIにリクエストをして、画像内の顔を検出します。

Azure FunctionsのPython関数では、アップロードされたBlobのパスを取得できないため、JSON形式でのリクエストができませんが、Face APIはバイナリ形式のリクエストにも対応しているため、os.environ[“トリガーバインド名”]のパスにあるアップロードデータのコピーで直接リクエストし、顔の検出を行います。

04‐顔検出結果をJSONで出力

Face APIで出力された結果をそのままJSON形式で出力します。

os.environ[“出力バインド名”]のパスに出力したいデータを保存するとBlobストレージに格納されます。

実行結果

テストとして、JPEG画像を「face-01.jpg」としてBlobストレージにアップロードしてみます。

Azure Functionsのログを見ると、アップロードされた4秒後に関数が開始され、順次ログを出力しながら約10秒で関数が完了しました。

Blobストレージを見ると、関数が完了した同時刻に「face-01_result.json」の名称でJSONファイルが出力されていました。バインドで設定したパスパターンが出力ファイル名に反映されていることがわかりました。

出力されたJSONの内容は以下になります。Face APIの出力がそのままBlobストレージに出力できていました。

[
{
"faceId": "4d551839-3ddf-4fdd-95f9-a9fc8ed2bf09",
"faceRectangle": {
"top": 154,
"left": 118,
"width": 199,
"height": 199
},
"faceAttributes": {
"smile": 1.0,
"gender": "male",
"age": 23.5,
"emotion": {
"anger": 0.0,
"contempt": 0.0,
"disgust": 0.0,
"fear": 0.0,
"happiness": 1.0,
"neutral": 0.0,
"sadness": 0.0,
"surprise": 0.0
}
}
}
]

続いて、画像ではないJSONデータ「face-02.json」をBlobストレージにアップロードしてみます。

スクリプトでフォーマット判定を行っているため、Azure Functionsのログを見ると正常に処理が中断されていることがわかりました。

スクリプトでフォーマット判定を行っているため、Azure Functionsのログを見ると正常に処理が中断されていることがわかりました。

まとめ

Azure FunctionsのPython関数は、C#やJavaScriptのようにバインドのパスパターンをスクリプトで参照できないため、入出力の方法にひと工夫が必要になりますが、今回のようにパスパターンに大きな変更がなければ簡単に設定して処理を組むことができました。

次回は、今回の処理にOpenCVを使いして、検出した顔の情報を画像に描画してみます。

この記事を書いた人

azure-recipe-user