この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
前回、顔認証のクラウドサービス Mercury Cloud を使って顔比較を行いました。
顔認証のクラウドサービスMercury Cloudで遊んでみる – 顔比較 –
顔検知、顔比較では画像データをバイナリ化してAPIのパラメータとして渡し、Mercury Cloudはその画像データをもとに結果を返してくれます.
ベストプラクティスとして
APIを呼び出す前に、高品質・正面・鮮明な画像を、有効な顔サイズが200x200ピクセル以上を確保しながら、画像をトリミングして200KB未満に圧縮することを強くお勧めします
とされています。 画質が高いほど認識精度が高くなるので品質の確認は重要と言えますね。
Mercury Cloudでは品質チェックのAPIが用意されていて、顔のサイズ、角度、明るさ、鋭さ、遮蔽などを分析し、すべての要素の値を応答します。
まだ記事化していませんが、顔検索APIを使用するときのデータベースに顔の画像を登録する前には品質チェックのAPIを実行してチェックを行うことが推奨されています。
使ってみる
前提
Mercury CloudのAPIを使うには、全てのAPI共通で認証を行っておく必要があります。
x-dateとAuthorizationのheaderが必要で、含まれていないと401エラーとなります。
前回の記事で行いましたので、本記事では詳細を割愛します。
例)
x-date: Fri, 09 Jul 2021 01:51:02 GMT
Authorization: hmac username="005c5acf-5ea9-499c-8d3e-690413f9b5b9", algorithm="hmac-sha256", headers="x-date request-line", signature="kUJ6OHiMMBZnxgSEa2ARxVAlgjC2kzjedZgxOz07i+Y="
品質チェックAPIへリクエスト
URL: https://{domain}/openapi/face/v1/{app_id}/quality
画像のバイナリデータをRequest Bodyに与える必要があります。
リクエスト例)
curl --location --request POST 'https://{domain}/openapi/face/v1/{app_id}/quality' \
--header 'x-date: Tue, 02 Nov 2021 01:27:49 GMT' \
--header 'Authorization: hmac username="{access_key}", algorithm="hmac-sha256", headers="x-date request-line", signature="v7mUOcnEsftAhicEG+fSRzrhIY065KyBb15YrgWYNjQ="' \
--header 'Content-Type: application/json' \
--data-raw '{
"image": {
"data": "/9j/4AAQSkZJRgA...Tpi3Q1lZTCn//Z"
}
}'
レスポンスの確認
上記画像をリクエストした時の結果を見てみます。
{
"trace_id": "2ddb80237f03f3e3c10855ab590cca07",
"result": {
"code": 0,
"message": "Success.",
"internal_code": 0
},
"face": {
"angle": {
"yaw": -20.232817,
"pitch": -0.82377076,
"roll": -8.167998
},
"quality": {
"distance2center": 0.23039812,
"size": 0.18051992,
"brightness": -0.09724788,
"sharpness": 0.764679,
"mouth_open": 0.45437628,
"missing": 1,
"align_score": 9.999924
},
"occlusion": {
"eye": 0,
"nose": 0,
"mouth": 0,
"eyebrow": 0,
"face_line": 0,
"occlusion_total": 0
},
"rectangle": {
"top": 45,
"left": 88,
"width": 70,
"height": 77
},
"orientation": 1
}
}
上記のように結果が返ってきますが、この情報をもとに自身で許容レベルを決定して判断する必要があります。
以下の表がチェック項目と推奨されるしきい値を示しています
パラメータ名 | 範囲 | 推奨しきい値 | 説明 |
---|---|---|---|
angle.yaw | [-90, 90] | [-10.0, 10.0] | 顔が上下を軸にした(ヨー)回転角度\r\n頭が左寄りなほど、値は大きくなります |
angle.pitch | [-90, 90] | [-15.0, 15.0] | 顔が左右を軸にした(ピッチ)回転角度\r\n頭が下がるほど、値は大きくなります |
angle.roll | [-90, 90] | [-10.0, 10.0] | 顔が前後を軸にした(ロール)回転角度\r\n頭が反時計回りなほど、値は大きくなります |
quality.distance2center | [0, 1] | [0, 0.2] | 顔の中心と写真の中心との位置偏差\r\n2つの中心の距離が近いほど、値は大きくなります |
occlusion.occlusion_total | [0, 1] | [0 , 0.02] | 顔全体が遮蔽された度合い\r\n顔全体の遮蔽が大きいほど、値は大きくなります |
occlusion.eye | [0, 1] | =0 | 目が遮蔽された度合い\r\n目の遮蔽が大きいほど、値は大きくなります |
occlusion.nose | [0, 1] | =0 | 鼻が遮蔽された度合い\r\n鼻の遮蔽が大きいほど、値は大きくなります |
occlusion.mouth | [0, 1] | [0, 0.4] | 口が遮蔽された度合い\r\n口の遮蔽が大きいほど、値は大きくなります |
occlusion.eyebrow | [0, 1] | =0 | 眉毛が遮蔽された度合い\r\n眉毛の遮蔽が大きいほど、値は大きくなります |
quality.align_score | [0, 10] | [1.0, 10] | 顔ランドマークのスコア\r\n揃いが良いほど、値は大きくなります |
quality.brightness | [-1, 1] | [-0.5, 0.5] | 顔枠の平均明るさ\r\n明るいほど、値は大きくなります |
quality.sharpness | [0, 1] | [0.8, 1.0] | MAGICアルゴリズムで計算したシャープネス(鋭さ)\r\n鋭いほど、値は大きくなります |
quality.mouth_open | [0, 1] | [0, 0.4] | 口が開いている度合い\r\n口が開いているほど、値は大きくなります |
quality.missing | [0, 1] | [0.9, 1.0] | ランディングポイントが写真の中に含めない度合い\r\n含まれていないランディングポイントが少ないほど、値は大きくなります |
quality.size | [0, 1] | [0, 0.85] | 写真全体に対する顔枠面積の比率\r\n顔枠の面積が大きいほど、値は大きくなります |
orientation | 0, 1, 2, 3, 4 | =1 | 1、2、3、4は、上向きの画像の時計回りの回転角度がそれぞれ0、90、180、270度を示します。0は予備で使用されていません。 |
いろんな画像でチェック
目の付近を黒く塗りつぶしたりしてみた結果は以下のようになりました、
{
"trace_id": "c145d857f9aa1bfb3f4901aa70702ded",
"result": {
"code": 0,
"message": "Success.",
"internal_code": 0
},
"face": {
"angle": {
"yaw": -18.884073,
"pitch": 0.59742945,
"roll": -9.100546
},
"quality": {
"distance2center": 0.22264344,
"size": 0.18051992,
"brightness": -0.23255374,
"sharpness": 0.99760157,
"mouth_open": 0.48383373,
"missing": 1,
"align_score": 9.998194
},
"occlusion": {
"eye": 0.6111111,
"nose": 0,
"mouth": 0,
"eyebrow": 0.22222221,
"face_line": 0,
"occlusion_total": 0.14705884
},
"rectangle": {
"top": 45,
"left": 87,
"width": 68,
"height": 76
},
"orientation": 1
}
}
何もしていない画像に比べて、
occlusion
の eye
が 0.6111111、eyebrow
が0.22222221 となっていて、目の付近を隠した画像だということがデータとしてもわかります。
この画像のようにマスクをした状態だと
{
"trace_id": "e07ea65d50a92852e95b518e36f86a5d",
〜〜〜,
"occlusion": {
"eye": 0,
"nose": 0.23076922,
"mouth": 1,
"eyebrow": 0,
"face_line": 0.45454544,
"occlusion_total": 0.372549
},
〜〜〜
}
}
occlusion
のnose
、 mouth
の値が増えます。
ちょっと明るくして不鮮明な感じの画像だと
{
"trace_id": "a9e5f2d66386ab5eb6716fa70c7944ca",
~~~
"quality": {
"distance2center": 0.07739246,
"size": 0.17479675,
"brightness": 0.8932953,
"sharpness": 0.65244,
"mouth_open": 0.46528304,
"missing": 1,
"align_score": 9.98233
},
~~~
}
}
quality
の brightness
の値が大きくなります。
最後に
品質チェックAPIを使っていろんな画像を確認しました。 APIを呼び出すことは非常に簡単で、返ってくるデータも正確だと感じます。
できるだけ精度を高くした顔認証をサービスに組み込む際、
- APIで返されるチェック項目を使ってしきい値を決める
- 実際に顔検知や顔比較、顔検索の画像をアップロードされた時に閾値と比較するようにプログラムする
といったことが必要になってきますね。