이미지에 있는 얼굴 비교 - Amazon Rekognition

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

이미지에 있는 얼굴 비교

Rekognition을 사용하면 작업을 통해 두 이미지 사이의 얼굴을 비교할 수 있습니다. CompareFaces 이 기능은 신원 확인 또는 사진 매칭과 같은 애플리케이션에 유용합니다.

CompareFaces 소스 이미지의 얼굴을 대상 이미지의 각 얼굴과 비교합니다. 이미지는 다음 중 CompareFaces 하나로 전달됩니다.

  • base64로 인코딩된 이미지 표현입니다.

  • Amazon S3 객체.

얼굴 인식과 얼굴 비교

얼굴 비교는 얼굴 감지와 다릅니다. 얼굴 인식 (사용 DetectFaces) 은 이미지나 비디오에서 얼굴의 존재 여부와 위치만 식별합니다. 반면, 얼굴 비교는 소스 이미지에서 감지된 얼굴을 대상 이미지의 얼굴과 비교하여 일치하는 얼굴을 찾는 것입니다.

유사성 임계값

similarityThreshold파라미터를 사용하여 대응이 응답에 포함될 최소 신뢰 수준을 정의합니다. 기본적으로 유사성 점수가 80% 이상인 얼굴만 응답에 반환됩니다.

참고

CompareFaces확률론적 기계 학습 알고리즘을 사용합니다. False negative는 대상 이미지의 얼굴이 소스 이미지의 얼굴과 비교할 때 유사성 신뢰도 점수가 낮다는 잘못된 예측입니다. False negative의 확률을 줄이려면 대상 이미지를 여러 소스 이미지와 비교하는 것이 좋습니다. CompareFaces를 사용하여 개인의 권리, 개인 정보 보호 또는 서비스 액세스에 영향을 미치는 결정을 내리려는 경우 조치를 취하기 전에 결과를 사람에게 전달하여 검토 및 추가 검증을 받는 것을 권고합니다.

다음 코드 예제는 다양한 AWS SDK의 CompareFaces 작업을 사용하는 방법을 보여줍니다. 이 AWS CLI 예제에서는 Amazon S3 버킷에 JPEG 이미지 두 개를 업로드하고 객체 키 이름을 지정합니다. 다른 예제에서는 로컬 파일 시스템에서 파일 2개를 로드하여 이미지 바이트 배열로 입력합니다.

얼굴을 비교하려면
  1. 아직 설정하지 않았다면 다음과 같이 하세요.

    1. AmazonRekognitionFullAccessAmazonS3ReadOnlyAccess (AWS CLI 예시만 해당) 권한을 가진 사용자를 생성하거나 업데이트하십시오. 자세한 설명은 1단계: AWS 계정 설정 및 사용자 생성 섹션을 참조하세요.

    2. 및 AWS SDK를 설치 AWS CLI 및 구성합니다. 자세한 설명은 2단계: AWS CLI 및 AWS SDK 설정 섹션을 참조하세요.

  2. 다음 예제 코드를 사용하여 CompareFaces 작업을 호출하십시오.

    Java

    이 예제는 로컬 파일 시스템에서 불러오는 소스 이미지와 대상 이미지의 일치 얼굴에 대한 정보를 표시합니다.

    sourceImage 값과 targetImage 값을 소스 및 대상 이미지의 파일 이름과 경로로 바꿉니다.

    //Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. //PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) package aws.example.rekognition.image; import com.amazonaws.services.rekognition.AmazonRekognition; import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder; import com.amazonaws.services.rekognition.model.Image; import com.amazonaws.services.rekognition.model.BoundingBox; import com.amazonaws.services.rekognition.model.CompareFacesMatch; import com.amazonaws.services.rekognition.model.CompareFacesRequest; import com.amazonaws.services.rekognition.model.CompareFacesResult; import com.amazonaws.services.rekognition.model.ComparedFace; import java.util.List; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.nio.ByteBuffer; import com.amazonaws.util.IOUtils; public class CompareFaces { public static void main(String[] args) throws Exception{ Float similarityThreshold = 70F; String sourceImage = "source.jpg"; String targetImage = "target.jpg"; ByteBuffer sourceImageBytes=null; ByteBuffer targetImageBytes=null; AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.defaultClient(); //Load source and target images and create input parameters try (InputStream inputStream = new FileInputStream(new File(sourceImage))) { sourceImageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream)); } catch(Exception e) { System.out.println("Failed to load source image " + sourceImage); System.exit(1); } try (InputStream inputStream = new FileInputStream(new File(targetImage))) { targetImageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream)); } catch(Exception e) { System.out.println("Failed to load target images: " + targetImage); System.exit(1); } Image source=new Image() .withBytes(sourceImageBytes); Image target=new Image() .withBytes(targetImageBytes); CompareFacesRequest request = new CompareFacesRequest() .withSourceImage(source) .withTargetImage(target) .withSimilarityThreshold(similarityThreshold); // Call operation CompareFacesResult compareFacesResult=rekognitionClient.compareFaces(request); // Display results List <CompareFacesMatch> faceDetails = compareFacesResult.getFaceMatches(); for (CompareFacesMatch match: faceDetails){ ComparedFace face= match.getFace(); BoundingBox position = face.getBoundingBox(); System.out.println("Face at " + position.getLeft().toString() + " " + position.getTop() + " matches with " + match.getSimilarity().toString() + "% confidence."); } List<ComparedFace> uncompared = compareFacesResult.getUnmatchedFaces(); System.out.println("There was " + uncompared.size() + " face(s) that did not match"); } }
    Java V2

    이 코드는 AWS 문서 SDK 예제 GitHub 저장소에서 가져왔습니다. 전체 예제는 여기에서 확인하세요.

    import java.util.List; import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import software.amazon.awssdk.services.rekognition.model.Image; import software.amazon.awssdk.services.rekognition.model.BoundingBox; import software.amazon.awssdk.services.rekognition.model.CompareFacesMatch; import software.amazon.awssdk.services.rekognition.model.CompareFacesRequest; import software.amazon.awssdk.services.rekognition.model.CompareFacesResponse; import software.amazon.awssdk.services.rekognition.model.ComparedFace; import software.amazon.awssdk.core.SdkBytes; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; // snippet-end:[rekognition.java2.detect_faces.import] /** * Before running this Java V2 code example, set up your development environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CompareFaces { public static void main(String[] args) { final String usage = "\n" + "Usage: " + " <pathSource> <pathTarget>\n\n" + "Where:\n" + " pathSource - The path to the source image (for example, C:\\AWS\\pic1.png). \n " + " pathTarget - The path to the target image (for example, C:\\AWS\\pic2.png). \n\n"; if (args.length != 2) { System.out.println(usage); System.exit(1); } Float similarityThreshold = 70F; String sourceImage = args[0]; String targetImage = args[1]; Region region = Region.US_EAST_1; RekognitionClient rekClient = RekognitionClient.builder() .region(region) .credentialsProvider(ProfileCredentialsProvider.create("profile-name")) .build(); compareTwoFaces(rekClient, similarityThreshold, sourceImage, targetImage); rekClient.close(); } // snippet-start:[rekognition.java2.compare_faces.main] public static void compareTwoFaces(RekognitionClient rekClient, Float similarityThreshold, String sourceImage, String targetImage) { try { InputStream sourceStream = new FileInputStream(sourceImage); InputStream tarStream = new FileInputStream(targetImage); SdkBytes sourceBytes = SdkBytes.fromInputStream(sourceStream); SdkBytes targetBytes = SdkBytes.fromInputStream(tarStream); // Create an Image object for the source image. Image souImage = Image.builder() .bytes(sourceBytes) .build(); Image tarImage = Image.builder() .bytes(targetBytes) .build(); CompareFacesRequest facesRequest = CompareFacesRequest.builder() .sourceImage(souImage) .targetImage(tarImage) .similarityThreshold(similarityThreshold) .build(); // Compare the two images. CompareFacesResponse compareFacesResult = rekClient.compareFaces(facesRequest); List<CompareFacesMatch> faceDetails = compareFacesResult.faceMatches(); for (CompareFacesMatch match: faceDetails){ ComparedFace face= match.face(); BoundingBox position = face.boundingBox(); System.out.println("Face at " + position.left().toString() + " " + position.top() + " matches with " + face.confidence().toString() + "% confidence."); } List<ComparedFace> uncompared = compareFacesResult.unmatchedFaces(); System.out.println("There was " + uncompared.size() + " face(s) that did not match"); System.out.println("Source image rotation: " + compareFacesResult.sourceImageOrientationCorrection()); System.out.println("target image rotation: " + compareFacesResult.targetImageOrientationCorrection()); } catch(RekognitionException | FileNotFoundException e) { System.out.println("Failed to load source image " + sourceImage); System.exit(1); } } // snippet-end:[rekognition.java2.compare_faces.main] }
    AWS CLI

    이 예제는 작업의 JSON 출력을 표시합니다. compare-faces AWS CLI

    bucket-name을 소스 이미지와 대상 이미지가 들어 있는 Amazon S3 버킷의 이름으로 바꿉니다. source.jpgtarget.jpg를 소스 이미지와 대상 이미지의 파일 이름으로 바꿉니다.

    aws rekognition compare-faces --target-image \ "{"S3Object":{"Bucket":"bucket-name","Name":"image-name"}}" \ --source-image "{"S3Object":{"Bucket":"bucket-name","Name":"image-name"}}" --profile profile-name

    Windows 디바이스에서 CLI에 액세스하는 경우 작은따옴표 대신 큰따옴표를 사용하고 내부 큰따옴표는 백슬래시(즉 \)로 이스케이프 처리하여 발생할 수 있는 구문 분석 오류를 해결합니다. 예를 들어 다음을 참조하세요.

    aws rekognition compare-faces --target-image "{\"S3Object\":{\"Bucket\":\"bucket-name\",\"Name\":\"image-name\"}}" \ --source-image "{\"S3Object\":{\"Bucket\":\"bucket-name\",\"Name\":\"image-name\"}}" --profile profile-name
    Python

    이 예제는 로컬 파일 시스템에서 불러오는 소스 이미지와 대상 이미지의 일치 얼굴에 대한 정보를 표시합니다.

    source_file 값과 target_file 값을 소스 및 대상 이미지의 파일 이름과 경로로 바꿉니다. Rekognition 세션을 생성하는 라인에서 profile_name의 값을 개발자 프로필의 이름으로 대체합니다.

    # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. # PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) import boto3 def compare_faces(sourceFile, targetFile): session = boto3.Session(profile_name='profile-name') client = session.client('rekognition') imageSource = open(sourceFile, 'rb') imageTarget = open(targetFile, 'rb') response = client.compare_faces(SimilarityThreshold=80, SourceImage={'Bytes': imageSource.read()}, 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') imageSource.close() imageTarget.close() return len(response['FaceMatches']) def main(): source_file = 'source-file-name' target_file = 'target-file-name' face_matches = compare_faces(source_file, target_file) print("Face matches: " + str(face_matches)) if __name__ == "__main__": main()
    .NET

    이 예제는 로컬 파일 시스템에서 불러오는 소스 이미지와 대상 이미지의 일치 얼굴에 대한 정보를 표시합니다.

    sourceImage 값과 targetImage 값을 소스 및 대상 이미지의 파일 이름과 경로로 바꿉니다.

    //Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. //PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) using System; using System.IO; using Amazon.Rekognition; using Amazon.Rekognition.Model; public class CompareFaces { public static void Example() { float similarityThreshold = 70F; String sourceImage = "source.jpg"; String targetImage = "target.jpg"; AmazonRekognitionClient rekognitionClient = new AmazonRekognitionClient(); Amazon.Rekognition.Model.Image imageSource = new Amazon.Rekognition.Model.Image(); try { using (FileStream fs = new FileStream(sourceImage, FileMode.Open, FileAccess.Read)) { byte[] data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length); imageSource.Bytes = new MemoryStream(data); } } catch (Exception) { Console.WriteLine("Failed to load source image: " + sourceImage); return; } Amazon.Rekognition.Model.Image imageTarget = new Amazon.Rekognition.Model.Image(); try { using (FileStream fs = new FileStream(targetImage, FileMode.Open, FileAccess.Read)) { byte[] data = new byte[fs.Length]; data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length); imageTarget.Bytes = new MemoryStream(data); } } catch (Exception) { Console.WriteLine("Failed to load target image: " + targetImage); return; } CompareFacesRequest compareFacesRequest = new CompareFacesRequest() { SourceImage = imageSource, TargetImage = imageTarget, SimilarityThreshold = similarityThreshold }; // Call operation CompareFacesResponse compareFacesResponse = rekognitionClient.CompareFaces(compareFacesRequest); // Display results foreach(CompareFacesMatch match in compareFacesResponse.FaceMatches) { ComparedFace face = match.Face; BoundingBox position = face.BoundingBox; Console.WriteLine("Face at " + position.Left + " " + position.Top + " matches with " + match.Similarity + "% confidence."); } Console.WriteLine("There was " + compareFacesResponse.UnmatchedFaces.Count + " face(s) that did not match"); } }
    Ruby

    이 예제는 로컬 파일 시스템에서 불러오는 소스 이미지와 대상 이미지의 일치 얼굴에 대한 정보를 표시합니다.

    photo_source 값과 photo_target 값을 소스 및 대상 이미지의 파일 이름과 경로로 바꿉니다.

    # Add to your Gemfile # gem 'aws-sdk-rekognition' require 'aws-sdk-rekognition' credentials = Aws::Credentials.new( ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'] ) bucket = 'bucket' # the bucketname without s3:// photo_source = 'source.jpg' photo_target = 'target.jpg' client = Aws::Rekognition::Client.new credentials: credentials attrs = { source_image: { s3_object: { bucket: bucket, name: photo_source }, }, target_image: { s3_object: { bucket: bucket, name: photo_target }, }, similarity_threshold: 70 } response = client.compare_faces attrs response.face_matches.each do |face_match| position = face_match.face.bounding_box similarity = face_match.similarity puts "The face at: #{position.left}, #{position.top} matches with #{similarity} % confidence" end
    Node.js

    이 예제는 로컬 파일 시스템에서 불러오는 소스 이미지와 대상 이미지의 일치 얼굴에 대한 정보를 표시합니다.

    photo_source 값과 photo_target 값을 소스 및 대상 이미지의 파일 이름과 경로로 바꿉니다. Rekognition 세션을 생성하는 라인에서 profile_name의 값을 개발자 프로필의 이름으로 대체합니다.

    // Load the SDK var AWS = require('aws-sdk'); const bucket = 'bucket-name' // the bucket name without s3:// const photo_source = 'photo-source-name' // path and the name of file const photo_target = 'photo-target-name' var credentials = new AWS.SharedIniFileCredentials({profile: 'profile-name'}); AWS.config.credentials = credentials; AWS.config.update({region:'region-name'}); const client = new AWS.Rekognition(); const params = { SourceImage: { S3Object: { Bucket: bucket, Name: photo_source }, }, TargetImage: { S3Object: { Bucket: bucket, Name: photo_target }, }, SimilarityThreshold: 70 } client.compareFaces(params, function(err, response) { if (err) { console.log(err, err.stack); // an error occurred } else { response.FaceMatches.forEach(data => { let position = data.Face.BoundingBox let similarity = data.Similarity console.log(`The face at: ${position.Left}, ${position.Top} matches with ${similarity} % confidence`) }) // for response.faceDetails } // if });

CompareFaces 작업 요청

CompareFaces에 대한 입력은 이미지입니다. 이 예제에서는 소스 이미지와 대상 이미지를 로컬 파일 시스템에서 불러옵니다. SimilarityThreshold 입력 파라미터는 비교 얼굴을 응답에 포함시키는 기준이 되는 최소 신뢰도를 지정합니다. 자세한 설명은 이미지 작업 섹션을 참조하세요.

{ "SourceImage": { "Bytes": "/9j/4AAQSk2Q==..." }, "TargetImage": { "Bytes": "/9j/4O1Q==..." }, "SimilarityThreshold": 70 }

CompareFaces 운영 응답

응답에는 다음이 포함됩니다.

  • 일치하는 얼굴 배열: 일치하는 각 얼굴에 대한 유사성 점수 및 메타데이터가 포함된 일치하는 얼굴의 목록입니다. 여러 얼굴이 일치하는 경우 faceMatches

    배열에는 일치하는 모든 얼굴이 포함됩니다.

  • 얼굴 일치 세부 정보: 일치하는 각 얼굴은 경계 상자, 신뢰도, 랜드마크 위치 및 유사성 점수도 제공합니다.

  • 일치하지 않는 얼굴 목록: 응답에는 원본 이미지 얼굴과 일치하지 않는 대상 이미지의 얼굴도 포함됩니다. 일치하지 않는 각 얼굴에 대한 바운딩 박스가 포함되어 있습니다.

  • 소스 얼굴 정보: 경계 상자 및 신뢰도 값을 포함하여 비교에 사용된 소스 이미지의 얼굴 정보를 포함합니다.

이 예제는 대상 이미지에서 일치하는 얼굴이 한 개 발견되었음을 보여줍니다. 이 얼굴 일치의 경우, 경계 상자와 신뢰도 값(Amazon Rekognition이 경계 상자에 얼굴이 포함되었다고 믿는 신뢰도 수준)이 제공됩니다. 유사성 점수 99.99는 얼굴이 얼마나 비슷한지를 나타냅니다. 또한 이 예제에서는 Amazon Rekognition이 대상 이미지에서 발견한 얼굴 중 소스 이미지에서 분석된 얼굴과 일치하지 않는 얼굴 하나를 보여줍니다.

{ "FaceMatches": [{ "Face": { "BoundingBox": { "Width": 0.5521978139877319, "Top": 0.1203877404332161, "Left": 0.23626373708248138, "Height": 0.3126954436302185 }, "Confidence": 99.98751068115234, "Pose": { "Yaw": -82.36799621582031, "Roll": -62.13221740722656, "Pitch": 0.8652129173278809 }, "Quality": { "Sharpness": 99.99880981445312, "Brightness": 54.49755096435547 }, "Landmarks": [{ "Y": 0.2996366024017334, "X": 0.41685718297958374, "Type": "eyeLeft" }, { "Y": 0.2658946216106415, "X": 0.4414493441581726, "Type": "eyeRight" }, { "Y": 0.3465650677680969, "X": 0.48636093735694885, "Type": "nose" }, { "Y": 0.30935320258140564, "X": 0.6251809000968933, "Type": "mouthLeft" }, { "Y": 0.26942989230155945, "X": 0.6454493403434753, "Type": "mouthRight" } ] }, "Similarity": 100.0 }], "SourceImageOrientationCorrection": "ROTATE_90", "TargetImageOrientationCorrection": "ROTATE_90", "UnmatchedFaces": [{ "BoundingBox": { "Width": 0.4890109896659851, "Top": 0.6566604375839233, "Left": 0.10989011079072952, "Height": 0.278298944234848 }, "Confidence": 99.99992370605469, "Pose": { "Yaw": 51.51519012451172, "Roll": -110.32493591308594, "Pitch": -2.322134017944336 }, "Quality": { "Sharpness": 99.99671173095703, "Brightness": 57.23163986206055 }, "Landmarks": [{ "Y": 0.8288310766220093, "X": 0.3133862614631653, "Type": "eyeLeft" }, { "Y": 0.7632885575294495, "X": 0.28091415762901306, "Type": "eyeRight" }, { "Y": 0.7417283654212952, "X": 0.3631140887737274, "Type": "nose" }, { "Y": 0.8081989884376526, "X": 0.48565614223480225, "Type": "mouthLeft" }, { "Y": 0.7548204660415649, "X": 0.46090251207351685, "Type": "mouthRight" } ] }], "SourceImageFace": { "BoundingBox": { "Width": 0.5521978139877319, "Top": 0.1203877404332161, "Left": 0.23626373708248138, "Height": 0.3126954436302185 }, "Confidence": 99.98751068115234 } }