【Amazon Rekognition 信頼スコア比較】


この記事で得られること

Amazon Rekognition における、
1. 検出範囲。
2. 検証画像の推奨事項。
3. 実際の生体認証 (顔認証) による信頼スコア比較。

検出範囲

まず、どのような検出が可能なのかを調査した。

"Amazon Rekognition では、イメージ分析とビデオ分析をアプリケーションに簡単に追加することができ ます。Amazon Rekognition API にイメージやビデオを指定するだけで、このサービスによってモノ、人 物、テキスト、シーン、アクティビティを識別できます。不適切なコンテンツも検出できます。Amazon Rekognition は、高精度な顔分析、顔比較、および顔検索機能も備えています。顔の検出、分析、比較は、 ユーザー検証、カタログ作成、人数計数、公共安全など、多岐にわたって活用できます。"

(出典「Amazon Rekognition 開発者ガイド」)

イメージ、またはビデオをもとに、生体認証のみならず、物体の識別にも適用可能。
広範囲での活用が期待出来そうだが、検証可能な画像に制約はあるのだろうか?

検証画像の推奨事項

生体認証 (顔認証) に的を絞って調査したところ、次のような事項が推奨とされている。

  1. ピンぼけ、大部分が切り取られていないこと。
  2. ヘッドバンド、マスクなどで顔を遮らないこと。
  3. 人の頭全体と肩が含まれている必要がある。
  4. 顔比較用に、少なくとも 5 枚のイメージをインデックスに登録する。
    • 正面をまっすぐ向いたもの。
    • 45 度以下のヨーイングで左を向いた顔。
    • 45 度以下のヨーイングで右を向いた顔。
    • 30 度以下のピッチで下を向いた顔。
    • 45 度以下のピッチで上を向いた顔。
  5. インデックス化された顔画像が 1 つしかない場合、外部イメージ ID 属性使用を検討する。

(参照: https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/recommendations-facial-input-images.html)

信頼スコア比較用写真

「推奨事項」にそぐわない画像を交えて、信頼スコア比較を行ってみた。
今回の実験のために用意した写真は次の通り。(フリー素材集の写真を使用)

デフォルト
閉じた目正面 閉じた目横向き 両頬に手
マスク眼鏡 顔3分の2 顔半分

検証

検証写真のうち、「デフォルト.jpg」を Rekognition にインデックス登録する。

$ aws rekognition index-faces --collection-id 'facesCollection' --image '{"S3Object”:{“Bucket":"バケット名","Name":"デフォルト.jpg"}}' --external-image-id '20200510'

次のコマンドにより、S3 バケットに保存した写真と「デフォルト.jpg」を比較する。

$ aws rekognition compare-faces --source-image "S3Object={Bucket=バケット名,Name=デフォルト.jpg}" --target-image "S3Object={Bucket=バケット名,Name=閉じた目正面.jpg}" --region ap-northeast-1

結果: 閉じた目正面

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.41360822319984436, 
                    "Top": 0.16738523542881012, 
                    "Left": 0.33072414994239807, 
                    "Height": 0.4866061210632324
                }, 
                "Confidence": 99.99998474121094, 
                "Pose": {
                    "Yaw": 9.889140129089355, 
                    "Roll": 2.0434916019439697, 
                    "Pitch": 2.727581262588501
                }, 
                "Quality": {
                    "Sharpness": 73.32209777832031, 
                    "Brightness": 93.77152252197266
                }, 
                "Landmarks": [
                    {
                        "Y": 0.3295896649360657, 
                        "X": 0.43512019515037537, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.3341609835624695, 
                        "X": 0.6278741955757141, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.5237436294555664, 
                        "X": 0.45004794001579285, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.5271170139312744, 
                        "X": 0.6098234057426453, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.4135397970676422, 
                        "X": 0.5413277745246887, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 94.61534881591797
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

結果: 閉じた目横向き

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.26115351915359497, 
                    "Top": 0.2572881877422333, 
                    "Left": 0.3942970037460327, 
                    "Height": 0.36763879656791687
                }, 
                "Confidence": 99.99978637695312, 
                "Pose": {
                    "Yaw": 67.60726928710938, 
                    "Roll": -13.45390796661377, 
                    "Pitch": 0.40739765763282776
                }, 
                "Quality": {
                    "Sharpness": 67.22731018066406, 
                    "Brightness": 96.20038604736328
                }, 
                "Landmarks": [
                    {
                        "Y": 0.38040149211883545, 
                        "X": 0.5113434195518494, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.368644118309021, 
                        "X": 0.5509953498840332, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.5143603086471558, 
                        "X": 0.5734089016914368, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.5050305128097534, 
                        "X": 0.6003172397613525, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.415506511926651, 
                        "X": 0.6130676865577698, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 82.33488464355469
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

結果: 両頬に手

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.20240534842014313, 
                    "Top": 0.36693572998046875, 
                    "Left": 0.4098302721977234, 
                    "Height": 0.2377210408449173
                }, 
                "Confidence": 100.0, 
                "Pose": {
                    "Yaw": -4.391824245452881, 
                    "Roll": 3.562525510787964, 
                    "Pitch": -10.13006591796875
                }, 
                "Quality": {
                    "Sharpness": 95.51618957519531, 
                    "Brightness": 70.825439453125
                }, 
                "Landmarks": [
                    {
                        "Y": 0.45272162556648254, 
                        "X": 0.4586236774921417, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.45951828360557556, 
                        "X": 0.5411313772201538, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.5393064022064209, 
                        "X": 0.4594725966453552, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.5449655652046204, 
                        "X": 0.5279838442802429, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.5055729150772095, 
                        "X": 0.49501097202301025, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 98.96453094482422
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

結果: マスク眼鏡

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.3824339807033539, 
                    "Top": 0.2504523694515228, 
                    "Left": 0.2694239020347595, 
                    "Height": 0.5604692697525024
                }, 
                "Confidence": 99.99982452392578, 
                "Pose": {
                    "Yaw": -18.912364959716797, 
                    "Roll": 5.935861587524414, 
                    "Pitch": -15.86832332611084
                }, 
                "Quality": {
                    "Sharpness": 97.45164489746094, 
                    "Brightness": 81.87736511230469
                }, 
                "Landmarks": [
                    {
                        "Y": 0.4401859939098358, 
                        "X": 0.2798130214214325, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.4621078372001648, 
                        "X": 0.46966812014579773, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.6604933142662048, 
                        "X": 0.29142722487449646, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.6802700161933899, 
                        "X": 0.44906315207481384, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.5923178195953369, 
                        "X": 0.3314099907875061, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 87.92839813232422
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

結果: 顔3分の2

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.6502764821052551, 
                    "Top": -0.0013810403179377317, 
                    "Left": 0.27466630935668945, 
                    "Height": 0.6481964588165283
                }, 
                "Confidence": 100.0, 
                "Pose": {
                    "Yaw": -31.26296615600586, 
                    "Roll": -14.175341606140137, 
                    "Pitch": -5.726714611053467
                }, 
                "Quality": {
                    "Sharpness": 83.14741516113281, 
                    "Brightness": 82.5372543334961
                }, 
                "Landmarks": [
                    {
                        "Y": 0.2296328991651535, 
                        "X": 0.3510913550853729, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.17131587862968445, 
                        "X": 0.6091099977493286, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.5460081100463867, 
                        "X": 0.45194196701049805, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.4989546835422516, 
                        "X": 0.6664861440658569, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.4009784162044525, 
                        "X": 0.46206873655319214, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 97.51073455810547
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

結果: 顔半分

{
    "UnmatchedFaces": [], 
    "FaceMatches": [
        {
            "Face": {
                "BoundingBox": {
                    "Width": 0.33683139085769653, 
                    "Top": 0.270496666431427, 
                    "Left": 0.3322230875492096, 
                    "Height": 0.51352459192276
                }, 
                "Confidence": 99.99974822998047, 
                "Pose": {
                    "Yaw": -11.188610076904297, 
                    "Roll": 4.19580602645874, 
                    "Pitch": -10.553825378417969
                }, 
                "Quality": {
                    "Sharpness": 94.08262634277344, 
                    "Brightness": 76.0780029296875
                }, 
                "Landmarks": [
                    {
                        "Y": 0.4418652057647705, 
                        "X": 0.3567337691783905, 
                        "Type": "eyeLeft"
                    }, 
                    {
                        "Y": 0.44846487045288086, 
                        "X": 0.5500836968421936, 
                        "Type": "eyeRight"
                    }, 
                    {
                        "Y": 0.6645649075508118, 
                        "X": 0.35018762946128845, 
                        "Type": "mouthLeft"
                    }, 
                    {
                        "Y": 0.6686034798622131, 
                        "X": 0.5104967951774597, 
                        "Type": "mouthRight"
                    }, 
                    {
                        "Y": 0.5827540755271912, 
                        "X": 0.43896913528442383, 
                        "Type": "nose"
                    }
                ]
            }, 
            "Similarity": 94.54290008544922
        }
    ], 
    "SourceImageFace": {
        "BoundingBox": {
            "Width": 0.30034777522087097, 
            "Top": 0.2371588796377182, 
            "Left": 0.3409177362918854, 
            "Height": 0.3729771077632904
        }, 
        "Confidence": 99.9998550415039
    }
}

所感

  1. 「マスク眼鏡.jpg」 について、

    • Confidence 99.9 %、Similarity 87.9 % を返すのが意外だった。(もっと低い数値を期待していた。)
    • FaceMatches ではなく、UnmatchedFaces に値を返すなど、顔認証の対象から外せるようにすべきでは?
    • 眼鏡やマスク着用でも、正面写真だとスコアが上がるらしい。
  2. 「閉じた目横向き.jpg」 について、

    • Similarity が 82.3 % と、「マスク眼鏡.jpg」 よりも低い。
  3. Amazon が、異なるヨーイングとピッチの複数画像登録を推奨するのは、画像一枚のみの Confidence や Similarity だけで個人を証明するのは脆弱過ぎるからだろうか。

  4. ログインフローをより手軽なものに近付けたいのは山々だが、顔認証においては、深層学習テクノロジーで解決出来ていない部分が多少あるように感じた。

  5. 顔認証をログインフローで採択するならば、ユーザープールを挟んだ方が、より堅牢だと言える。(単体での使用は危険だと思われる。)