使用 Amazon Rekognition 進行身分驗證 - Amazon Rekognition

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 Amazon Rekognition 進行身分驗證

Amazon Rekognition 為使用者提供多項操作,可讓您輕鬆建立身分驗證系統。Amazon Rekognition 可讓使用者偵測影像中的人臉,然後比較人臉資料,將任何偵測到的人臉與其他人臉進行比較。此人臉資料存儲於稱為「集合」的伺服器端容器中。透過使用 Amazon Rekognition 的人臉偵測、人臉比較和集合管理操作,您可以使用身分驗證解決方案建立應用程式。

本教學課程將示範兩種常見的工作流程,以建立需要身分驗證的應用程式。

第一個工作流程涉及在集合中註冊新使用者。第二個工作流程涉及為了登錄傳回的使用者而搜尋現有集合。

您將在本教學課程中使用適用於 Python 的AWS SDK。您也可以查看 AWS 文件開發套件範例 GitHub 儲存庫,以取得更多 Python 教學課程。

先決條件

開始本教學課程之前,您需要安裝 Python 並完成設定 Python AWS SDK 所需的步驟。除此之外,請務必備妥:

建立集合

您必須先擁有要使用的集合,才能在集合中註冊新使用者或搜尋系列。Amazon Rekognition 集合是伺服器端容器,用於儲存偵測到的人臉的相關資訊。

建立集合

您將首先編寫一個函數,該函數會建立供應用程式使用的集合。Amazon Rekognition 會在伺服器端容器 (稱為「集合」) 中儲存偵測到的人臉相關資訊。您可以搜尋儲存在集合中的人臉資訊,找出已知的人臉。若要儲存人臉資訊,您首先需要使用該 CreateCollection 操作建立集合。

  1. 選擇您想要建立的收藏名稱。在下列程式碼中,將 collection_id 的值取代為您要建立的集合名稱,並以您的使用者憑證中定義的區域名稱取代 region 的值。您可以使用該 Tags 參數將任何您想要的標籤應用於集合,儘管這不是必需的。此 CreateCollection 操作會傳回您所建立之集合的相關資訊,包括集合的 Arn。記下您在執行程式碼時收到的 Arn。

    import boto3 def create_collection(collection_id, region): client = boto3.client('rekognition', region_name=region) # Create a collection print('Creating collection:' + collection_id) response = client.create_collection(CollectionId=collection_id, Tags={"SampleKey1":"SampleValue1"}) print('Collection ARN: ' + response['CollectionArn']) print('Status code: ' + str(response['StatusCode'])) print('Done...') collection_id = 'collection-id-name' region = "region-name" create_collection(collection_id, region)
  2. 儲存並執行程式碼。複製下來集合阿恩。

    現在 Rekognition 系列已經建立完畢,您可以將人臉資訊和識別碼儲存在該集合中。您還可以將人臉與儲存的資訊比較以進行驗證。

新使用者註冊

您將希望能夠註冊新使用者並將他們的資訊新增到收藏中。註冊新使用者的過程通常包括以下步驟:

呼叫 DetectFaces 操作。

編寫程式碼以通過 DetectFaces 操作檢查人臉映像的質量。您將使用該 DetectFaces 操作來確定相機拍攝的映像是否適合通過 SearchFacesByImage 操作進行處理。影像應該只包含一個人臉。您將提供本機輸入影像檔案給 DetectFaces 操作,並接收影像中偵測到的人臉的詳細資訊。下列範例程式碼會提供 DetectFaces 輸入影像,然後檢查影像中是否偵測到只有一個人臉。

  1. 在下列程式碼範例中,請以您要偵測人臉的目標影像名稱取代 photo。您還需要將 region 的值替換為與您帳戶關聯的地區名稱。

    import boto3 import json def detect_faces(target_file, region): client=boto3.client('rekognition', region_name=region) imageTarget = open(target_file, 'rb') response = client.detect_faces(Image={'Bytes': imageTarget.read()}, Attributes=['ALL']) print('Detected faces for ' + photo) for faceDetail in response['FaceDetails']: print('The detected face is between ' + str(faceDetail['AgeRange']['Low']) + ' and ' + str(faceDetail['AgeRange']['High']) + ' years old') print('Here are the other attributes:') print(json.dumps(faceDetail, indent=4, sort_keys=True)) # Access predictions for individual face details and print them print("Gender: " + str(faceDetail['Gender'])) print("Smile: " + str(faceDetail['Smile'])) print("Eyeglasses: " + str(faceDetail['Eyeglasses'])) print("Emotions: " + str(faceDetail['Emotions'][0])) return len(response['FaceDetails']) photo = 'photo-name' region = 'region-name' face_count=detect_faces(photo, region) print("Faces detected: " + str(face_count)) if face_count == 1: print("Image suitable for use in collection.") else: print("Please submit an image with only one face.")
  2. 儲存並執行任務程式碼。

呼叫 CompareFaces 操作。

您的應用程式必須能夠在集合中註冊新使用者,並確認回訪使用者的身分。您將首先建立用於註冊新使用者的功能。您將首先使用 CompareFaces 操作來比較使用者的本地輸入/目標映像和 ID/儲存的映像。如果在兩個影像中偵測到的人臉之間存在相符專案,您可以搜尋集合,以查看使用者是否已在其中註冊。

首先撰寫一個函數,將輸入影像與您存放在 Amazon S3 儲存貯體中的 ID 映像進行比較。在下面的程式碼範例中,您將需要自己提供輸入映像,這些映像應在使用某種形式的活體偵測器後被擷取。您還需要傳遞您的 Amazon S3 儲存貯體中所存放的映像名稱。

  1. bucket 的值取代為包含您的來源檔案之 Amazon S3 儲存貯體的名稱。您還需要將 source_file 的值替換為您正在使用的源映像的名稱。將 target_file 的值取代為您所提供的目標檔案名稱。將 region 的值取代為您的使用者憑證中 region 定義的名稱。

    若要指定您想要在回應中傳回之符合項的最低信賴度,請在要求中使用 similarityThreshold 參數。只有當信賴度高於此閾值時,才會在 FaceMatches 陣列中傳回偵測到的人臉。您選擇的 similarityThreshold 應反映您的特定使用案例的性質。任何涉及重要安全性應用程式的使用案例都應使用 99 做為選取的閾值。

    import boto3 def compare_faces(bucket, sourceFile, targetFile, region): client = boto3.client('rekognition', region_name=region) imageTarget = open(targetFile, 'rb') response = client.compare_faces(SimilarityThreshold=99, SourceImage={'S3Object':{'Bucket':bucket,'Name':sourceFile}}, TargetImage={'Bytes': imageTarget.read()}) for faceMatch in response['FaceMatches']: position = faceMatch['Face']['BoundingBox'] similarity = str(faceMatch['Similarity']) print('The face at ' + str(position['Left']) + ' ' + str(position['Top']) + ' matches with ' + similarity + '% confidence') imageTarget.close() return len(response['FaceMatches']) bucket = 'bucket-name' source_file = 'source-file-name' target_file = 'target-file-name' region = "region-name" face_matches = compare_faces(bucket, source_file, target_file, region) print("Face matches: " + str(face_matches)) if str(face_matches) == "1": print("Face match found.") else: print("No face match found.")
  2. 儲存並執行任務程式碼。

    將傳回一個回應物件,其中包含有關匹配的人臉和可信度的資訊。

呼叫 SearchFacesByImage 操作。

如果 CompareFaces 操作的信賴等級高於您所選擇的 SimilarityThreshold,則您需要搜尋集合中可能與輸入映像匹配的人臉。如果在您的收藏中找到匹配項,這意味著該使用者很可能已經在收藏中註冊,並且不需要在您的收藏中註冊新使用者。如果沒有相符專案,您可以在收藏中註冊新使用者。

  1. 首先編寫將調用 SearchFacesByImage 操作的程式碼。該操作將以本地映像檔案作為參數,然後搜尋與提供的 Collection 映像中偵測到的最大人臉匹配的人臉。

    在下列程式碼範例中,將 collectionId 的值變更為您要搜尋的集合。將 region 的值取代為與您帳戶相關聯的區域名稱。您還需要將 photo 的值替換為輸入檔案的名稱。您也會想要使用選取的百分位數來取代 threshold 的值,以指定相似性臨界值。

    import boto3 collectionId = 'collection-id-name' region = "region-name" photo = 'photo-name' threshold = 99 maxFaces = 1 client = boto3.client('rekognition', region_name=region) # input image should be local file here, not s3 file with open(photo, 'rb') as image: response = client.search_faces_by_image(CollectionId=collectionId, Image={'Bytes': image.read()}, FaceMatchThreshold=threshold, MaxFaces=maxFaces) faceMatches = response['FaceMatches'] print(faceMatches) for match in faceMatches: print('FaceId:' + match['Face']['FaceId']) print('ImageId:' + match['Face']['ImageId']) print('Similarity: ' + "{:.2f}".format(match['Similarity']) + "%") print('Confidence: ' + str(match['Face']['Confidence']))
  2. 儲存並執行任務程式碼。如果有匹配項,則表示映像中識別的人已經是收藏的一部分,因此無需繼續進行後續步驟。在這種情況下,您可以直接允許使用者存取應用程式。

呼叫 IndexFaces 操作。

假設在您搜尋的集合中找不到相符專案,您會想要將使用者的人臉新增至您的收藏。您可以透過呼叫作業來執行此 IndexFaces 操作。當您呼叫 IndexFaces Face 時,Amazon Rekognition 會擷取輸入影像中識別的人臉特徵,並將資料儲存在指定的集合中。

  1. 首先編寫要呼叫的程式碼 IndexFaces。將 image 的值取代為您要用作 IndexFaces 作業輸入影像的本機檔案名稱。您還需要將 photo_name 的值替換為輸入映像的所需名稱。以您先前建立的集合 ID 取代 collection_id 的值。接下來,將 region 的值取代為與您帳戶相關聯的區域名稱。您也會想要指定 MaxFaces 輸入參數的值,此參數會定義影像中應建立索引的最大人臉數目。此參數的預設值為 1。

    import boto3 def add_faces_to_collection(target_file, photo, collection_id, region): client = boto3.client('rekognition', region_name=region) imageTarget = open(target_file, 'rb') response = client.index_faces(CollectionId=collection_id, Image={'Bytes': imageTarget.read()}, ExternalImageId=photo, MaxFaces=1, QualityFilter="AUTO", DetectionAttributes=['ALL']) print(response) print('Results for ' + photo) print('Faces indexed:') for faceRecord in response['FaceRecords']: print(' Face ID: ' + faceRecord['Face']['FaceId']) print(' Location: {}'.format(faceRecord['Face']['BoundingBox'])) print(' Image ID: {}'.format(faceRecord['Face']['ImageId'])) print(' External Image ID: {}'.format(faceRecord['Face']['ExternalImageId'])) print(' Confidence: {}'.format(faceRecord['Face']['Confidence'])) print('Faces not indexed:') for unindexedFace in response['UnindexedFaces']: print(' Location: {}'.format(unindexedFace['FaceDetail']['BoundingBox'])) print(' Reasons:') for reason in unindexedFace['Reasons']: print(' ' + reason) return len(response['FaceRecords']) image = 'image-file-name' collection_id = 'collection-id-name' photo_name = 'desired-image-name' region = "region-name" indexed_faces_count = add_faces_to_collection(image, photo_name, collection_id, region) print("Faces indexed count: " + str(indexed_faces_count))
  2. 儲存並執行任務程式碼。決定是否要儲存 IndexFaces 操作傳回的任何資料,例如指定給影像中人物的 FaceID。下一節將研究如何儲存這些資料。在繼續之前,請先複製傳回的 FaceIdImageId、和 Confidence 值。

將映像和 FaceID 資料存放在 Amazon S3 和 Amazon DynamoDB

取得輸入影像的人臉識別碼後,影像資料即可儲存在 Amazon S3 中,而人臉資料和影像 URL 則可輸入 DynamoDB 等資料庫中。

  1. 撰寫程式碼,將輸入映像上傳到您的 Amazon S3 資料庫。在接下來的程式碼範例中,以您想要上傳檔案的儲存貯體名稱取代 bucket 的值,然後以您想要存放在 Amazon S3 儲存貯體的本機檔案名稱取代 file_name 的值。提供可識別 Amazon S3 儲存貯體中檔案的金鑰名稱,方法是將 key_name 的值取代為映像檔的名稱。您要上傳的檔案與先前程式碼範例中定義的檔案相同,即您用於 IndexFaces 的輸入檔案。最後,將 region 的值替換為與您的帳戶相關聯的區域名稱。

    import boto3 import logging from botocore.exceptions import ClientError # store local file in S3 bucket bucket = "amzn-s3-demo-bucket" file_name = "file-name" key_name = "key-name" region = "region-name" s3 = boto3.client('s3', region_name=region) # Upload the file try: response = s3.upload_file(file_name, bucket, key_name) print("File upload successful!") except ClientError as e: logging.error(e)
  2. 儲存並執行正在進行的程式碼範例,將您的輸入影像上傳到 Amazon S3。

  3. 您也需要將傳回的 Face ID 儲存到資料庫中。這可以透過建立 DynamoDB 資料庫資料表,然後將人臉識別碼上傳至該資料表來完成。以下程式碼範例會建立 DynamoDB 資料表。請注意,您只需要執行一次建立此資料表的程式碼。在下列程式碼中,將 region 的值取代為與您帳戶相關聯的區域值。您也需要將 database_name 的值取代為您想要提供 DynamoDB 資料表的名稱。

    import boto3 # Create DynamoDB database with image URL and face data, face ID def create_dynamodb_table(table_name, region): dynamodb = boto3.client("dynamodb", region_name=region) table = dynamodb.create_table( TableName=table_name, KeySchema=[{ 'AttributeName': 'FaceID', 'KeyType': 'HASH' # Partition key },], AttributeDefinitions=[ { 'AttributeName': 'FaceID', 'AttributeType': 'S' }, ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 } ) print(table) return table region = "region-name" database_name = 'database-name' dynamodb_table = create_dynamodb_table(database_name, region) print("Table status:", dynamodb_table)
  4. 儲存並執行正在進行的程式碼以建立資料表。

  5. 建立資料表後,您可以將傳回的 FaceId 上傳到該表中。若要這麼做,您將使用 Table 函數建立與資料表的連線,然後使用 put_item 函數上傳資料。

    在下列程式碼範例中,將 bucket 的值取代為包含您上傳至 Amazon S3 之輸入影像的儲存貯體名稱。您還需要將 file_name 的值替換為上傳到 Amazon S3 儲存貯體的輸入檔案名稱,以及先前用於識別輸入檔案的金鑰的 key_name 值。最後,將 region 的值替換為與您的帳戶相關聯的區域名稱。這些值應與步驟 1 中提供的值相符。

    AddDBEntry 會儲存指派給集合中人臉的 FaceId、ImageId 和可信度值。提供以下功能,其中包含您在繼續 IndexFaces 部分的步驟 2 中儲存的值。

    import boto3 from pprint import pprint from decimal import Decimal import json # The local file that was stored in S3 bucket bucket = "amzn-s3-demo-bucket" file_name = "file-name" key_name = "key-name" region = "region-name" # Get URL of file file_url = "https://s3.amazonaws.com/{}/{}".format(bucket, key_name) print(file_url) # upload face-id, face info, and image url def AddDBEntry(file_name, file_url, face_id, image_id, confidence): dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table('FacesDB-4') response = table.put_item( Item={ 'ExternalImageID': file_name, 'ImageURL': file_url, 'FaceID': face_id, 'ImageID': image_id, 'Confidence': json.loads(json.dumps(confidence), parse_float=Decimal) } ) return response # Mock values for face ID, image ID, and confidence - replace them with actual values from your collection results dynamodb_resp = AddDBEntry(file_name, file_url, "FACE-ID-HERE", "IMAGE-ID-HERE", confidence-here) print("Database entry successful.") pprint(dynamodb_resp, sort_dicts=False)
  6. 儲存並執行正在進行的程式碼範例,將傳回的 Face ID 資料儲存在資料表中。

現有使用者簽署

使用者在集合中註冊之後,可以使用該 SearchFacesByImage 操作在傳回時對其進行驗證。您將需要獲取輸入映像,然後使用 DetectFaces 檢查輸入映像的質量。這會決定在執行 SearchFacesbyImage 操作之前是否已使用合適的影像。

呼叫 DetectFaces 操作

  1. 您將使用該 DetectFaces 操作來檢查人臉影像的品質,並確定相機拍攝的影像是否適合透過 SearchFacesByImage 操作進行處理。輸入映像應該只包含一張臉。下列程式碼範例會取得輸入影像,並將其提供給 DetectFaces 作業。

    在下列程式碼範例中,將 photo 的值取代為本機目標映像檔的名稱,並以與您帳戶相關聯的區域名稱取代 region 的值。

    import boto3 import json def detect_faces(target_file, region): client=boto3.client('rekognition', region_name=region) imageTarget = open(target_file, 'rb') response = client.detect_faces(Image={'Bytes': imageTarget.read()}, Attributes=['ALL']) print('Detected faces for ' + photo) for faceDetail in response['FaceDetails']: print('The detected face is between ' + str(faceDetail['AgeRange']['Low']) + ' and ' + str(faceDetail['AgeRange']['High']) + ' years old') print('Here are the other attributes:') print(json.dumps(faceDetail, indent=4, sort_keys=True)) # Access predictions for individual face details and print them print("Gender: " + str(faceDetail['Gender'])) print("Smile: " + str(faceDetail['Smile'])) print("Eyeglasses: " + str(faceDetail['Eyeglasses'])) print("Emotions: " + str(faceDetail['Emotions'][0])) return len(response['FaceDetails']) photo = 'photo-name' region = 'region-name' face_count=detect_faces(photo, region) print("Faces detected: " + str(face_count)) if face_count == 1: print("Image suitable for use in collection.") else: print("Please submit an image with only one face.")
  2. 儲存並執行程式碼。

呼叫 SearchFacesByImage 操作

  1. 撰寫程式碼,使用 SearchFacesByImage 將偵測到的人臉與集合中的人臉進行比較。您將使用新使用者註冊部分中顯示的程式碼,並將輸入映像提供給 SearchFacesByImage 操作。

    在下列程式碼範例中,將 collectionId 的值變更為您要搜尋的集合。您也會將 bucket 的值變更為 Amazon S3 儲存貯體的名稱,將 fileName 的值變更為該儲存貯體中的映像檔案。將 region 的值取代為與您帳戶相關聯的區域名稱。您也會想要使用選取的百分位數來取代 threshold 的值,以指定相似性臨界值。

    import boto3 bucket = 'amzn-s3-demo-bucket' collectionId = 'collection-id-name' region = "region-name" fileName = 'file-name' threshold = 70 maxFaces = 1 client = boto3.client('rekognition', region_name=region) # input image should be local file here, not s3 file with open(fileName, 'rb') as image: response = client.search_faces_by_image(CollectionId=collectionId, Image={'Bytes': image.read()}, FaceMatchThreshold=threshold, MaxFaces=maxFaces)
  2. 儲存並執行程式碼。

檢查傳回的 FaceID 和可信度水平

現在,您可以透過列印出諸如 FaceId、相似性和可信度屬性之類的回應元素來檢查匹配的 FaceId 上的資訊。

faceMatches = response['FaceMatches'] print(faceMatches) for match in faceMatches: print('FaceId:' + match['Face']['FaceId']) print('ImageId:' + match['Face']['ImageId']) print('Similarity: ' + "{:.2f}".format(match['Similarity']) + "%") print('Confidence: ' + str(match['Face']['Confidence']))