この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Mercury Cloudという顔認証のサービスを触る機会があったのでご紹介します。
顔認証のユースケースとしては、 オンラインサービスの本人確認、チケットレス入場(スタジアムやイベント会場など)、鍵解錠などが挙げられます。
Mercury Cloudは、既存のサービスでも簡単に顔認証を追加できるようなAPIを提供しているサービスです。 APIを実行するロジックは自身で追加しないといけません。
特徴として
- 高速で顔を認識
- 高精度な認証(マスク着用時も高い認証を誇る)
- 2000万人の顔データ登録が可能
- 顔の特徴から年齢や性別などの属性の識別が可能
といったものが挙げられています。
用意されているAPIですが、大きく分けると
- 顔検知
- 画像内の顔を検出し顔枠に外接する長方形の座標を返します
- 顔比較
- 2つの画像の中にあるそれぞれ最大の顔を検出し、これら2つの顔が同じ人物であるかどうかを確認
- 顔検索
- 特徴データベースに登録されているすべての顔特徴の中からアップロードした画像から検出された顔を検索し、最も近い結果を返します
があります。
本記事では顔検知を試していきたいと思います。
使ってみる
base uri: https://<<domain.com>>/openapi/face/v1
domain.com っは、サービス地域によって変わってきます。サービス開始時の連絡メールにこのドメイン部分は記載されています。
認証について
全てのAPIでクライアントの検証のためAPI認証トークンが必須となっています。
各APIを呼び出す際に、2つのヘッダー(x-dateとAuthorization)が必要です。それらが含まれていない場合、401のHTTPエラーコードが表示されます。
x-date
RFC-7231形式でのUTC日付と時刻の形式を使用します
Fri, 09 Jul 2021 01:51:02 GMT
Authorization
指定されたAPIパス、HTTPメソッド、アプリID、アクセスキー、およびシークレットキーに基づいて生成されます。特徴DBに関連する一部のAPIではDB IDも必要で、 以下のフォーマットに従う必要があります。
hmac username="{Access_key}", algorithm="hmac-sha256", headers="x-date request-line", signature="{Signature}"
Authorizationヘッダーの作成 に作成手順が詳しく記載されています。
アプリID、アクセスキー、およびシークレットキーはサービス開始時の連絡時に記載されているものを使用します。
これらの情報は安全な箇所に保管し、他人に開示してはいけない情報となっています。
ヘッダー作成ツールサンプル がドキュメントに用意されていますので、これを利用して作成することができます。
サンプル実行例)
画像について
Mercury Cloud APIはHTTPリクエストで、base64でエンコードされたバイナリを使用して画像データを送信します。
例)
def base64_encode_file(file_path):
handle = open(file_path, "rb")
raw_bytes = handle.read()
handle.close()
return base64.b64encode(raw_bytes).decode("utf-8")
- 画像のフォーマットは、JPG、PNG、BMP、TIFF、またはGIF
- 画像のファイルサイズは、8MB未満
- 有効な顔サイズは、32✕32ピクセル以上
- バッチアップロードがサポートされている顔検知APIと顔特徴追加APIでは、1回のAPI呼び出しでの画像の数量は16以下
以上の基準を守る必要があります。
基本的に画像の画質が高いほど精度が高くなりますが、ファイルサイズが大きいほどAPIの呼び出し時間が長くなります。
APIを呼び出す前に、高品質・正面・鮮明な画像を、有効な顔サイズが200x200ピクセル以上を確保しながら、画像をトリミングして200KB未満に圧縮すること
が推奨されていました。
顔検知API
URL
https://{domain}/openapi/face/v1/{app_id}/detect
Parameters
- x-date (必須)
- API認証時使用されるRFC-7231フォーマットのUTC日時文字列のヘッダーパラメータ
- 例:
Wed, 03 Mar 2021 02:11:37 GMT
- app_id (必須)
- テナントの下のアプリケーションIDを指定するURLパラメータ
Request body
指定された画像のバイナリデータ(base64でエンコード)
{
"images": [
{
"data": "/9j/4AAQSk...ZJRgABAQEA"
}
]
}
実行例
認証ヘッダーの作成、画像のbase64でエンコードを行った後、顔検知APIのURLにパラメータをつけて実行します。
アクセス例)
curl -X 'POST'
'https://<<domain>>/openapi/face/v1/<<app_id>>/detect'
-H 'accept: application/json'
-H 'x-date: <<RFC-7231フォーマットのUTC日時>>'
-H 'Authorization: hmac username="<<api_key>>", algorithm="hmac-sha256", headers="x-date request-line", signature="<<signature>>"'
-H 'Content-Type: application/json'
-d '{
"images": [
{
"data": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/~~~~~~~~~~sABFEdIMSMMQhNS/p19B6v0H+C/ouXGX6HrA0R"
}
]
}'
画像1
- レスポンス
{
"trace_id": "f035eca5057ff86f81407e6fa494abed",
"results": [
{
"code": 80303,
"message": "No face found.",
"internal_code": 303
}
],
"batches": [
{
"faces": []
}
]
}
顔が検知できなかったといういうレスポンスが返ってきた例です
画像2
- レスポンス
{
"trace_id": "af32b826835ff2d152609c03e5e77920",
"results": [
{
"code": 80303,
"message": "No face found.",
"internal_code": 303
}
],
"batches": [
{
"faces": []
}
]
}
イラストだと顔が検知できないようです
画像3
- レスポンス
{
"trace_id": "a29ceb0182508c5c012fb209c62c1b57",
"results": [
{
"code": 0,
"message": "Success.",
"internal_code": 0
}
],
"batches": [
{
"faces": [
{
"quality": 0.99826276,
"rectangle": {
"top": 220,
"left": 162,
"width": 203,
"height": 196
},
"angle": {
"yaw": 17.226185,
"pitch": 8.400441,
"roll": 15.522398
},
"landmarks": [
{
"x": 163,
"y": 277
},
{
"x": 167,
"y": 289
},
~~~~~~~,
{
"x": 269,
"y": 255
}
],
"attributes": {
"age_lower_limit": {
"type": 0,
"category": "age_lower_limit",
"value": 23
},
"age_up_limit": {
"type": 0,
"category": "age_up_limit",
"value": 33
},
"cap_style": {
"type": 2,
"category": "HAT_STYLE_TYPE_NONE",
"value": 0.999972
},
"gender_code": {
"type": 2,
"category": "MALE",
"value": 0.999675
},
"glass_style": {
"type": 2,
"category": "GLASSES_STYLE_TYPE_NONE",
"value": 0.9972076
},
"mustache_style": {
"type": 2,
"category": "MUSTACHE_STYLE_TYPE_NONE",
"value": 0.97730595
},
"respirator_color": {
"type": 2,
"category": "COLOR_TYPE_NONE",
"value": 0.99573535
},
"st_age": {
"type": 2,
"category": "ST_ADULT",
"value": 1
},
"st_expression": {
"type": 2,
"category": "ST_CALM",
"value": 0.99880713
},
"st_helmet_style": {
"type": 2,
"category": "ST_HELMET_STYLE_TYPE_NONE",
"value": 0.9993663
},
"st_respirator": {
"type": 0,
"category": "",
"value": 0
}
},
"rotated": 1
}
]
}
]
}
顔検知が成功すると、上記のようなレスポンスが返ってきます。
st_ageがST_ADULT
なので大人、gender_code
がMALE
なので男性, respirator_color
がCOLOR_TYPE_NONE
なのでマスク着用無 と推測されたようです。
あってますね、すごい。
属性に関して詳しくは
を参照。
画像4
- レスポンス
{
"trace_id": "f97f4e32e12b0c9d2df3f4c8f6f4ccb1",
"results": [
{
"code": 0,
"message": "Success.",
"internal_code": 0
}
],
"batches": [
{
"faces": [
{
"quality": 0.9982797,
"rectangle": {
"top": 150,
"left": 181,
"width": 130,
"height": 136
},
"angle": {
"yaw": 18.2098,
"pitch": 7.520368,
"roll": -15.592735
},
"landmarks": [
{
"x": 198,
"y": 162
},
~~~~~~~~~~~
{
"x": 262,
"y": 178
}
],
"attributes": {
"age_lower_limit": {
"type": 0,
"category": "age_lower_limit",
"value": 27
},
"age_up_limit": {
"type": 0,
"category": "age_up_limit",
"value": 37
},
"cap_style": {
"type": 2,
"category": "HAT_STYLE_TYPE_NONE",
"value": 0.98707956
},
"gender_code": {
"type": 2,
"category": "MALE",
"value": 0.99992156
},
"glass_style": {
"type": 2,
"category": "GLASSES_STYLE_TYPE_NONE",
"value": 0.9942698
},
"mustache_style": {
"type": 2,
"category": "MUSTACHE_STYLE_TYPE_NONE",
"value": 0.67222404
},
"respirator_color": {
"type": 2,
"category": "COLOR_TYPE_OTHER",
"value": 0.9999087
},
"st_age": {
"type": 2,
"category": "ST_ADULT",
"value": 1
},
"st_expression": {
"type": 2,
"category": "ST_HAPPY",
"value": 0.85142446
},
"st_helmet_style": {
"type": 2,
"category": "ST_HELMET_STYLE_TYPE_NONE",
"value": 0.99641335
},
"st_respirator": {
"type": 0,
"category": "",
"value": 0
}
},
"rotated": 1
}
]
}
]
}
respirator_color
が COLOR_TYPE_OTHER
となっているのでマスク着用有
と判定されています。
あってますね。
画像5
- レスポンス
{
"trace_id": "4a731fb6205477d95f4493594fc542e7",
"results": [
{
"code": 80303,
"message": "No face found.",
"internal_code": 303
}
],
"batches": [
{
"faces": []
}
]
}
顔が小さいためか、顔検知はできませんでした。
画像6
- レスポンス
{
"trace_id": "22a81df7f812bf6b99d0593f5ce1f19d",
"results": [
{
"code": 0,
"message": "Success.",
"internal_code": 0
}
],
"batches": [
{
"faces": [
{
"quality": 0.9965526,
"rectangle": {
"top": 292,
"left": 45,
"width": 123,
"height": 142
},
"angle": {
"yaw": 59.729923,
"pitch": 4.07797,
"roll": 7.824665
},
"landmarks": [
{
"x": 46,
"y": 322
},
~~~~~~~
{
"x": 79,
"y": 322
}
],
"attributes": {
"age_lower_limit": {
"type": 0,
"category": "age_lower_limit",
"value": 16
},
"age_up_limit": {
"type": 0,
"category": "age_up_limit",
"value": 26
},
"cap_style": {
"type": 2,
"category": "HAT_STYLE_TYPE_NONE",
"value": 0.99567693
},
"gender_code": {
"type": 2,
"category": "FEMALE",
"value": 0.9466953
},
"glass_style": {
"type": 2,
"category": "GLASSES_STYLE_TYPE_NONE",
"value": 0.9986252
},
"mustache_style": {
"type": 2,
"category": "MUSTACHE_STYLE_TYPE_NONE",
"value": 0.9887771
},
"respirator_color": {
"type": 2,
"category": "COLOR_TYPE_NONE",
"value": 0.9993965
},
"st_age": {
"type": 2,
"category": "ST_ADULT",
"value": 1
},
"st_expression": {
"type": 2,
"category": "ST_CALM",
"value": 0.7430104
},
"st_helmet_style": {
"type": 2,
"category": "ST_HELMET_STYLE_TYPE_NONE",
"value": 0.9973989
},
"st_respirator": {
"type": 0,
"category": "",
"value": 0
}
},
"rotated": 1
},
{
"quality": 0.9761087,
"rectangle": {
"top": 341,
"left": 847,
"width": 75,
"height": 82
},
~~~~~
},
{
"quality": 0.96427304,
~~~~~~~~~
},
{
"quality": 0.9879387,
~~~~~~
}
]
}
]
}
複数の顔を検知することも可能でした。
faces
に検知した複数の顔の情報が格納されています。
st_expression
には ST_CALM
、ST_HAPPY
などで分類されていました。
最後に
顔認証クラウドサービスMercury Cloudの顔検知APIを使ってみました。
6枚の画像でしか試していませんが、全て顔の検知はできていましたね。 精度が高いと評価されているのもうなづけます。
今回は検知だけでしたが、次回は検知したデータを使い顔の比較を行ってみたいと思います。