関数の実装
いよいよコードを実装します。ここでは作業環境にMacを利用する前提で説明します。
まず、FaceDetectProject
として作っておきましょう。
$ mkdir FaceDetectProject
Face APIを利用するモジュールの導入
Functionsには、Net::Azure::CognitiveService::Face
CPANモジュールの導入には、cpanm
を使います。プロジェクトフォルダ直下でcpanm
を使い、
$ cpanm -n -L local Net::Azure::CognitiveServices::Face
関数名フォルダの作成
関数名フォルダの名称はそのまま関数名となりますので、InspectFace
という名称で関数名フォルダを作ります。
$ mkdir InspectFace
ここから先は、
function.jsonの作成
トリガとバインディングの設定をするために、function.
を作成します。InspectFace
はHTTPリクエストを受けてHTTPレスポンスを返す関数ですので、function.
と同じです。
run.shの作成
関数本体となるrun.
は次の内容です。
perl task.pl > $res
Functionsから起動されたときにtask.
を起動し、res
で指定されたファイルにレスポンスデータを出力させる役割を担います。
Perlプログラムの作成
関数本体から呼び出されるtask.
を作ります。
use strict;
use warnings;
use lib "../local/lib/perl5";
use Net::Azure::CognitiveServices::Face;
use JSON 'encode_json';
# (1)長い名前なので変数に入れて短くする
my $cog = 'Net::Azure::CognitiveServices::Face';
# (2)環境変数から、Face APIの設定値を取得する
$cog->endpoint($ENV{FACEAPI_URL});
$cog->access_key($ENV{FACEAPI_KEY});
# (3)HTTPクエリパラメータimageを取得する
my $image_url = $ENV{REQ_QUERY_IMAGE};
# (4)デフォルトのレスポンスを定義する
my $res = {
status => 400,
headers => {'Content-Type' => 'application/json'},
body => {
message => 'parameter "image" is required',
}
};
# (5)画像URLが指定されている場合のみ顔認識を試みる
if ($image_url) {
# (6)Face APIクライアントを使って顔認識を行う
my $faceapi = $cog->Face;
my $result = $faceapi->detect(
$image_url,
returnFaceAttributes => ['age', 'gender']
);
# (7)認識した顔情報から年齢と性別を抽出する
my @faces = ();
if ($result->[0]) {
@faces = map { $_->{faceAttributes} } @$result;
}
# (8)レスポンスデータを上書きする
$res = {
status => 200,
headers => {
'Content-Type' => 'application/json'
},
body => {
faces => [@faces]
}
};
}
# (9)レスポンスを返す
print encode_json($res);
冒頭のuse
文では、Net::Azure::CognitiveService::Face
モジュールを利用するので、$cog
にモジュール名を代入し、JSON
モジュールをuse
していますが、
(2)では、Net::Azure::CognitiveService::Face
に対し、
(3)では、image
を取得しています。
(4)ではデフォルトのレスポンスを定義しています。もしクエリパラメータimage
が指定されていない場合、
(6)でFace APIに顔認識のリクエストを行い、@faces
に格納します。顔が認識されなかった場合は何もしません。
(8)でレスポンスデータを正常系のものに上書きしています。このとき、@faces
を配列リファレンスに展開します。
そして(9)でレスポンスデータをJSONに変換して、print
で出力しています。run.
ではtask.
の出力内容をそのまま環境変数resで指定されているファイルにリダイレクトしており、
Functionsリソースへの環境変数の設定
task.
の(2)で、FACEAPI_
と、FACEAPI_
を参照している箇所がありました。これらの環境変数をFunctionsリソースに設定します。
まず、
$ az cognitiveservices account show \
--resource-group face-detect \
--name face-detect-test |
grep endpoint
"endpoint": "https://japaneast.api.cognitive.microsoft.com/face/v1.0",
↑実行結果。エンドポイントURLなのでメモしておく
--resource-group
にはリソースグループ名を、--name
にはCognitive Serviceアカウント名を指定します。
続いて、--resource-group
、--name
の指定は先ほどと同じです。
$ az cognitiveservices account keys list \
--resource-group face-detect \
--name face-detect-test |
grep key1
"key1": "ba74XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
↑実行結果。アクセスキーなのでメモしておく
Face APIのエンドポイントURLとアクセスキーの両方がメモできたら、
$ az functionapp config appsettings set \
--resource-group face-detect \
--name face-detect-app1001 \
--settings \
FACEAPI_URL=https://japaneast.api.cognitive.microsoft.com/face/v1.0 \
FACEAPI_KEY=ba74XXXXXXXXXXXXXXXXXXXXXXXXXXXX
Azureへのデプロイ
できあがったコードをAzureにデプロイします。
Functionsでは、
まず、
$ zip -r FaceDetectProject.zip ./
できあがったZIPファイルのFaceDetectProject.
をデプロイします。
$ az functionapp deployment source config-zip \
--resource-group face-detect \
--name face-detect-app1001 \
--src FaceDetectProject.zip
--resource-group
にはリソースグループ名を、--name
にはリソース名を、--src
には先ほど作成したZIPファイルのパスを指定します。
これで、
ブラウザで動作確認
ブラウザでアクセスして動作を確認します。アクセス先URLは関数のエンドポイントURLで、
# Functionsリソース名。この例では"face-detect"
my $functionapp_name = "face-detect";
# 関数名。この例では"FaceDetect"
my $funcname = "FaceDetect";
# エンドポイントURL
my $endpoint_url = sprintf(
'https://%s.azurewebsites.net/api/%s',
$functionapp_name,
$funcname
);
print $endpoint_url;
上記の実行結果、https://
です。
また、image
パラメータとして付加すると、https://
となります。
ブラウザでこのURLにアクセスすると、
{
"faces":[
{"gender":"male","age":56},
{"age":58,"gender":"male"}
]
}
これは、
まとめ
本稿を通じて、
Perlの強みは、
さて、
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT