【Azure】Microsoft Cognitive ServicesのFace APIを検証したキロク
2017.03.28 大幅加筆しました。
Microsoft AzureにはCognitive Services(コグニティブサービス)といって、視覚や聴覚などAI技術を利用して認識を行う超絶便利なサービスがあります。
今回はその中で顔認識「Face API」を利用し、公式ドキュメントの曖昧な部分を検証しました。
Face APIに関しての詳細は、マイクロソフトの公式ドキュメント(英語)をご確認ください。
Microsoft Cognitive Services - Documentation
この通りに実装すれば、いとも簡単に顔認証ができます。本当に、Azureはヤバいです。
FaceAPI Freeプラン
FaceAPIにはFreeプランが存在します。ちょっとした評価や簡単な実装であれば問題ないのですが、少し本格的なサービスを実装しようとするとFreeプランのままでは制約が多いと感じました。
特に最初に判らないのは「トランザクション」の概念かと思います。
レベル 機能 料金 Face API - Free 1 分あたり 20 トランザクションまで 30,000 無料トランザクション / 月 Face API - Standard 最大 10 トランザクション/秒 0 - 1,000,000 トランザクション \153/1,000 トランザクション 1,000,001 - 5,000,000 トランザクション \112.20/1,000 トランザクション 5,000,001 - 20,000,000 トランザクション \66.30/1,000 トランザクション フェイス ストレージ フェイス ストレージ - 各画像のサイズ上限は 4 MB 画像 1,000 枚あたり月額 - \51
ここで挙げられている「トランザクション」とは、何かしらの命令をFaceAPIに送る度にカウントされます。
例えば公式サンプルの記載では、顔認証完了までに最低3トランザクションが必要となっています。
using (Stream s = File.OpenRead(testImageFile)) { // 画像ファイルの認証 ->これで1トランザクション var faces = await faceServiceClient.DetectAsync(s); var faceIds = faces.Select(face => face.FaceId).ToArray(); // 顔の認証 -> これで2トランザクション var results = await faceServiceClient.IdentifyAsync(personGroupId, faceIds); foreach (var identifyResult in results) { if (identifyResult.Candidates.Length == 0) { Console.WriteLine("No one identified"); } else { var candidateId = identifyResult.Candidates[0].PersonId; // Person情報の呼び出し -> Loop毎にトランザクション数加算 var person = await faceServiceClient.GetPersonAsync(personGroupId, candidateId); } } }
これ以外にも、削除処理でも1件に付き1トランザクションとなりますので、不要なデータを削除したい場合でも注意が必要です。
Freeプランでは、「1分間に20トランザクションまで」という制約がありますので、ちょっとしたサービスを構築するだけでもスグに上限値には達しそうです。
FaceAPIの階層構成
FaceAPIで写真を登録する場合、実際は3階層に分かれているのですが、サンプル通りに実装すると2階層までしか意識しなくても良い書き方となっています。お手軽に作成する分には何も問題はないのですが、原理を知りたいとか構成を知りたいとか行った場合には気になる所です。後述しますが、FaceAPIは「登録上限数」があるので、階層でどれくらい登録できるのか?は押さえておいて損はないと思います。
具体的には、「PersonGroup」「Person」「PersonFace」の3階層となっています。
1.PersonGroup階層
人物のグループを登録する為の階層です。認識の際は、このグループ内で合致する顔があるかどうかで検索が行われます。
最大1,000個のPersonGroupを作成する事が可能です。
PersonGroupには一意のpersonGroupIdが必要で、任意の文字列で登録することが出来ます。但し、使用出来る文字には制約があり数字、英字(小文字)、'-','_'が使用出来ます。特にこだわりがないのであれば、GUIDを作成しその値で作成すると良いと思います。
詳しくは、下記APIリファレンスを参照ください。
Microsoft Cognitive Services
2.Person階層
人単位のグループです。例えば、山田太郎さんの顔写真(複数)を管理する階層です。
新規登録時、PersonIdがGUIDで作成されます。同じ人物に画像を追加する場合はこのGUIDを保持しておく必要があります。
Person情報は、PersonGroup階層下に1,000ユーザー分作成可能です。1,000件を超えるとエラーとなる為、別グループへ登録する等の考慮が必要です。
3.PersonFace階層
人物の顔情報データです。(1画像毎に作成される)
一人の人物に対して、複数枚の画像を登録出来ます。理由としては、同じ人物に複数の顔写真を登録する事により、顔認証の精度が向上する事が可能な為です。
可能であれば、正面を向いた顔・側面・眼鏡の有無などの写真を登録すれば、より精度を高めることが出来ます。
但し、登録に際しては制約条件が数点あります。
- 登録可能な数は1ユーザー毎に248件
- 画像の種類は、JPEG、PNG、GIF(最初のフレーム)、およびBMPがサポート
- イメージファイルのサイズは、1KB以上4MB以下
- 検出可能な顔のサイズは、36×36〜4096×4096ピクセル
特に写真で撮った画像をそのまま認証させたい場合など、画像サイズに注意が必要です。
削除時は下位層を考慮する
FaceServiceClientには各Deleteメソッドが準備されています。
例えば、PersonGroupを削除する場合は「DeletePersonGroupAsync」といった具合です。
但し、上位のPersonGroupを削除したとしても、下位層の「Person」「PersistedFace」は残ったままとなります。
よって、上位を削除する際には、下位層のデータを削除してから消すといった一手間が要りそうです。
削除も1件=1トランザクションで課金の対象となる為、敢えて残すという選択肢もあるとは思います。
値の無いデータは全てNotFoundでExceptionがスローされる
GetPersonGroupAsync等で指定した値に該当するデータが無い場合、nullでは無くExceptionがスローされます。
この辺りは善し悪しなのですが、個人的にはnullで返ってきてもらった方が慣れているので、一手間を加えて使用しています。
まとめ
もう何点か検証中項目がある為、随時更新していきます。
一つ言えるのは、Azure楽しい♪という事です。