기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
신원 확인을 위한 Amazon Rekognition 사용
Amazon Rekognition은 사용자에게 신원 확인 시스템을 간단하게 생성할 수 있는 여러 작업을 제공합니다. Amazon Rekognition을 사용하면 이미지에서 얼굴을 감지한 다음 얼굴 데이터를 비교하여 감지된 얼굴을 다른 얼굴과 비교할 수 있습니다. 이 얼굴 데이터는 컬렉션이라 불리는 서버 측 컨테이너에 저장됩니다. Amazon Rekognition의 얼굴 감지, 얼굴 비교 및 컬렉션 관리 작업을 활용하면 신원 확인 솔루션이 포함된 애플리케이션을 만들 수 있습니다.
이 자습서에서는 신원 확인이 필요한 애플리케이션을 생성하기 위한 두 가지 일반적인 워크플로를 보여줍니다.
첫 번째 워크플로는 컬렉션에 새 사용자를 등록하는 것입니다. 두 번째 워크플로는 재방문하는 사용자를 기록하기 위해 기존 컬렉션을 검색하는 것입니다.
이 자습서에서는 AWS SDK for Python
사전 조건
이 자습서를 시작하기 전에 Python을 설치하고 Python AWS SDK를 설정하는
-
Amazon Simple Storage Service 버킷을 생성하고 신원 확인을 위해 ID로 사용하려는 이미지를 업로드 완료함.
-
신원 확인을 위한 대상 이미지로 사용할 두 번째 이미지를 선택함.
모음 만들기
컬렉션에 새 사용자를 등록하거나 컬렉션에서 사용자를 검색하려면 먼저 사용할 컬렉션이 있어야 합니다. Amazon Rekognition 컬렉션은 감지된 얼굴에 대한 정보를 저장하는 데 사용되는 서버 측 컨테이너입니다.
컬렉션 생성
먼저 애플리케이션에서 사용할 컬렉션을 생성하는 함수를 작성해 보겠습니다. Amazon Rekognition 은 감지된 얼굴에 대한 정보를 컬렉션이라고 하는 서버 측 컨테이너에 저장합니다. 컬렉션에 저장된 얼굴 정보를 검색하여 알려진 얼굴을 찾을 수 있습니다. 얼굴 정보를 저장하려면 먼저 CreateCollection
작업을 사용하여 컬렉션을 만들어야 합니다.
-
생성하려는 컬렉션의 이름을 선택합니다. 다음 코드에서
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)
-
코드를 저장하고 실행합니다. 컬렉션 ARN을 복사하세요.
이제 Rekognition 컬렉션이 생성되었으므로 해당 컬렉션에 얼굴 정보와 식별자를 저장할 수 있습니다. 또한 검증을 위해 저장된 정보와 얼굴을 비교할 수 있습니다.
신규 사용자 등록
새 사용자를 등록하고 컬렉션에 사용자 정보를 추가할 수 있어야 합니다. 새 사용자를 등록하는 프로세스에는 일반적으로 다음 단계가 포함됩니다.
DetectFaces
작업 직접 호출
DetectFaces
작업을 통해 얼굴 이미지의 품질을 확인하는 코드를 작성하세요. 이 DetectFaces
작업을 통해 카메라로 찍은 이미지가 SearchFacesByImage
작업 처리에 적합한지 판단할 수 있습니다. 이미지에는 얼굴이 한 개만 포함되어야 합니다. DetectFaces
작업에 로컬 입력 이미지 파일을 제공하고 이미지에서 감지된 얼굴에 대한 세부 정보를 받게 됩니다. 다음 샘플 코드는 입력 이미지를 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.")
-
진행 코드를 저장하고 실행합니다.
CompareFaces
작업 직접 호출
애플리케이션은 컬렉션에 새 사용자를 등록하고 재방문 사용자의 신원을 확인할 수 있어야 합니다. 새 사용자를 등록하는 데 사용되는 함수를 먼저 생성해야 합니다. 먼저 CompareFaces
작업을 사용하여 사용자의 로컬 입력 이미지 혹은 대상 이미지와 ID 또는 저장된 이미지를 비교합니다. 두 이미지에서 감지된 얼굴이 일치하는 경우 컬렉션을 검색하여 사용자가 컬렉션에 등록되어 있는지 확인할 수 있습니다.
먼저 입력 이미지를 Amazon S3 버킷에 저장한 ID 이미지와 비교하는 함수를 작성합니다. 다음 코드 예제에서는 입력 이미지를 직접 제공해야 합니다. 입력 이미지는 일종의 생체 확인 감지기를 사용한 후에 촬영해야 합니다. Amazon S3 버킷에 저장되어 있는 이미지의 이름도 전달해야 합니다.
-
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.")
-
진행 코드를 저장하고 실행합니다.
일치하는 얼굴에 대한 정보 및 신뢰도가 포함된 응답 개체가 반환됩니다.
SearchFacesByImage
작업 직접 호출
CompareFaces
작업의 신뢰도가 선택한 SimilarityThreshold
보다 높으면 컬렉션에서 입력 이미지와 일치할 수 있는 얼굴을 검색해 보는 것이 좋습니다. 컬렉션에서 일치하는 항목이 발견되면 해당 사용자는 이미 컬렉션에 등록되어 있을 가능성이 높으므로 컬렉션에 새 사용자를 등록할 필요가 없습니다. 일치하는 사용자가 없는 경우 컬렉션에 새 사용자를 등록할 수 있습니다.
-
먼저
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']))
-
진행 코드를 저장하고 실행합니다. 일치하는 항목이 있으면 이미지에서 인식된 사람이 이미 컬렉션에 속해 있다는 의미이므로 다음 단계를 진행할 필요가 없습니다. 이 경우에는 애플리케이션에 대한 사용자 액세스를 허용하기만 하면 됩니다.
IndexFaces
작업 직접 호출
검색한 컬렉션에 일치하는 항목이 없었다면 컬렉션에 사용자의 얼굴을 추가해야 합니다. IndexFaces
작업을 직접 호출해서 이를 수행할 수 있습니다. IndexFaces를 직접 호출하면 Amazon Rekognition은 입력 이미지에서 식별된 얼굴의 특성을 추출하여 지정된 컬렉션에 데이터를 저장합니다.
-
먼저
IndexFaces
를 직접 호출할 코드를 작성합니다.image
의 값을 IndexFaces 작업의 입력 이미지로 사용할 로컬 파일 이름으로 바꿉니다. 또한photo_name
의 값을 원하는 입력 파일의 이름으로 바꿔야 합니다.collection_id
의 값을 이전에 만든 컬렉션의 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))
-
진행 코드를 저장하고 실행합니다. 이미지 속 인물에게 할당된 FaceID와 같은
IndexFaces
작업에서 반환된 데이터를 저장할지 결정하세요. 다음 섹션에서는 이 데이터를 저장하는 방법을 살펴보겠습니다. 계속하기 전에 반환된FaceId
,ImageId
, 및Confidence
값을 복사해 두세요.
Amazon S3와 Amazon DynamoDB에 이미지 및 FaceID 데이터 저장
입력 이미지의 Face ID를 가져오면 이미지 데이터를 Amazon S3에 저장하고, 얼굴 데이터와 이미지 URL은 DynamoDB와 같은 데이터베이스에 입력할 수 있습니다.
-
입력 이미지를 Amazon S3 데이터베이스에 업로드하는 코드를 작성합니다. 다음 코드 샘플에서
bucket
값을 파일을 업로드하려는 버킷의 이름으로 대체한 다음,file_name
값을 Amazon S3 버킷에 저장하려는 로컬 파일의 이름으로 대체합니다.key_name
값을 이미지 파일에 지정하고자 하는 이름으로 대체하여 Amazon S3 버킷에 있는 파일을 식별할 키 이름을 입력합니다. 업로드하려는 파일은 이전 코드 샘플에서 정의한 파일, 즉 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)
-
진행 코드 샘플을 저장하고 실행하여 입력 이미지를 Amazon S3에 업로드합니다.
-
반환된 Face ID도 데이터베이스에 저장해야 할 것입니다. DynamoDB 데이터베이스 테이블을 생성한 다음 Face ID를 해당 테이블에 업로드하면 됩니다. 다음 코드 샘플에서는 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)
-
진행 코드를 저장하고 실행하여 테이블을 생성합니다.
-
테이블을 생성한 후 반환된 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)
-
진행 코드 샘플을 저장하고 실행하여 반환된 Face ID 데이터를 테이블에 저장합니다.
기존 사용자 로그인
컬렉션에 사용자를 등록한 후에는 해당 사용자가 다시 돌아오면 SearchFacesByImage
작업을 사용하여 인증을 받을 수 있습니다. 입력 이미지를 가져온 다음 DetectFaces
를 사용하여 입력 이미지의 품질을 확인해야 합니다. 이를 통해 SearchFacesbyImage
작업을 실행하기 전에 적절한 이미지를 사용했는지 확인할 수 있습니다.
DetectFaces 작업 직접 호출
-
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.")
-
코드를 저장하고 실행합니다.
SearchFacesByImage 작업 직접 호출
-
감지된 얼굴을
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)
-
코드를 저장하고 실행합니다.
반환된 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']))