저장된 비디오에서 얼굴 검색 - Amazon Rekognition

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

저장된 비디오에서 얼굴 검색

저장된 비디오나 스트리밍 비디오에서 감지한 얼굴과 일치하는 얼굴을 얼굴 모음에서 찾아낼 수 있습니다. 이 단원에서는 저장된 비디오에서 얼굴을 검색하는 과정에 대해 다룹니다. 스트리밍 비디오에서 얼굴을 검색하는 방법에 대한 정보는 스트리밍 비디오 이벤트 작업를 참조하십시오.

먼저 를 사용하여 IndexFaces검색하는 얼굴을 컬렉션에 인덱싱해야 합니다. 자세한 정보는 컬렉션에 얼굴 추가을 참조하세요.

Amazon Rekognition Video 얼굴 검색은 Amazon S3 버킷에 저장된 비디오를 분석하는 다른 Amazon Rekognition Video 작업과 동일한 비동기 워크플로를 따릅니다. 저장된 비디오에서 얼굴 검색을 시작하려면 검색하려는 컬렉션의 ID를 StartFaceSearch호출하여 제공하십시오. Amazon Rekognition Video는 동영상 분석 작업의 완료 상태를 Amazon Simple Notification Service(SNS) 주제에 게시합니다. 비디오 분석에 성공하면 전화를 GetFaceSearch걸어 검색 결과를 확인하세요. 비디오 분석 시작 및 결과 가져오기에 대한 자세한 내용은 Amazon Rekognition Video 작업 직접 호출 단원을 참조하십시오.

다음 절차는 비디오에서 감지된 사람의 얼굴과 일치하는 얼굴 모음을 감지하는 방법을 보여 줍니다. 다음 절차에서는 비디오에서 일치되는 사람의 추적 데이터를 가져오는 방법을 보여 줍니다. 이 절차는 동영상 분석 요청의 완료 상태를 가져오기 위해 Amazon Simple Queue Service(Amazon SQS) 대기열을 사용하는 Java 또는 Python으로 Amazon S3 버킷에 저장된 비디오 분석(SDK)의 코드를 확장합니다.

비디오에서 일치하는 얼굴을 검색하려면(SDK)
  1. 모음을 만듭니다.

  2. 얼굴을 모음으로 인덱싱합니다.

  3. Java 또는 Python으로 Amazon S3 버킷에 저장된 비디오 분석(SDK)을 수행합니다.

  4. 3단계에서 만든 클래스 VideoDetect에 다음 코드를 추가합니다.

    Java
    //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.) //Face collection search in video ================================================================== private static void StartFaceSearchCollection(String bucket, String video, String collection) throws Exception{ NotificationChannel channel= new NotificationChannel() .withSNSTopicArn(snsTopicArn) .withRoleArn(roleArn); StartFaceSearchRequest req = new StartFaceSearchRequest() .withCollectionId(collection) .withVideo(new Video() .withS3Object(new S3Object() .withBucket(bucket) .withName(video))) .withNotificationChannel(channel); StartFaceSearchResult startPersonCollectionSearchResult = rek.startFaceSearch(req); startJobId=startPersonCollectionSearchResult.getJobId(); } //Face collection search in video ================================================================== private static void GetFaceSearchCollectionResults() throws Exception{ GetFaceSearchResult faceSearchResult=null; int maxResults=10; String paginationToken=null; do { if (faceSearchResult !=null){ paginationToken = faceSearchResult.getNextToken(); } faceSearchResult = rek.getFaceSearch( new GetFaceSearchRequest() .withJobId(startJobId) .withMaxResults(maxResults) .withNextToken(paginationToken) .withSortBy(FaceSearchSortBy.TIMESTAMP) ); VideoMetadata videoMetaData=faceSearchResult.getVideoMetadata(); System.out.println("Format: " + videoMetaData.getFormat()); System.out.println("Codec: " + videoMetaData.getCodec()); System.out.println("Duration: " + videoMetaData.getDurationMillis()); System.out.println("FrameRate: " + videoMetaData.getFrameRate()); System.out.println(); //Show search results List<PersonMatch> matches= faceSearchResult.getPersons(); for (PersonMatch match: matches) { long milliSeconds=match.getTimestamp(); System.out.print("Timestamp: " + Long.toString(milliSeconds)); System.out.println(" Person number: " + match.getPerson().getIndex()); List <FaceMatch> faceMatches = match.getFaceMatches(); if (faceMatches != null) { System.out.println("Matches in collection..."); for (FaceMatch faceMatch: faceMatches){ Face face=faceMatch.getFace(); System.out.println("Face Id: "+ face.getFaceId()); System.out.println("Similarity: " + faceMatch.getSimilarity().toString()); System.out.println(); } } System.out.println(); } System.out.println(); } while (faceSearchResult !=null && faceSearchResult.getNextToken() != null); }

    main 함수에서 다음 줄을 바꿉니다.

    StartLabelDetection(bucket, video); if (GetSQSMessageSuccess()==true) GetLabelDetectionResults();

    다음으로 바꿉니다.

    String collection="collection"; StartFaceSearchCollection(bucket, video, collection); if (GetSQSMessageSuccess()==true) GetFaceSearchCollectionResults();
    Java V2

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

    import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.rekognition.model.*; import java.util.List; /** * 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 VideoDetectFaces { private static String startJobId = ""; public static void main(String[] args) { final String usage = """ Usage: <bucket> <video> <topicArn> <roleArn> Where: bucket - The name of the bucket in which the video is located (for example, (for example, myBucket).\s video - The name of video (for example, people.mp4).\s topicArn - The ARN of the Amazon Simple Notification Service (Amazon SNS) topic.\s roleArn - The ARN of the AWS Identity and Access Management (IAM) role to use.\s """; if (args.length != 4) { System.out.println(usage); System.exit(1); } String bucket = args[0]; String video = args[1]; String topicArn = args[2]; String roleArn = args[3]; Region region = Region.US_EAST_1; RekognitionClient rekClient = RekognitionClient.builder() .region(region) .build(); NotificationChannel channel = NotificationChannel.builder() .snsTopicArn(topicArn) .roleArn(roleArn) .build(); startFaceDetection(rekClient, channel, bucket, video); getFaceResults(rekClient); System.out.println("This example is done!"); rekClient.close(); } public static void startFaceDetection(RekognitionClient rekClient, NotificationChannel channel, String bucket, String video) { try { S3Object s3Obj = S3Object.builder() .bucket(bucket) .name(video) .build(); Video vidOb = Video.builder() .s3Object(s3Obj) .build(); StartFaceDetectionRequest faceDetectionRequest = StartFaceDetectionRequest.builder() .jobTag("Faces") .faceAttributes(FaceAttributes.ALL) .notificationChannel(channel) .video(vidOb) .build(); StartFaceDetectionResponse startLabelDetectionResult = rekClient.startFaceDetection(faceDetectionRequest); startJobId = startLabelDetectionResult.jobId(); } catch (RekognitionException e) { System.out.println(e.getMessage()); System.exit(1); } } public static void getFaceResults(RekognitionClient rekClient) { try { String paginationToken = null; GetFaceDetectionResponse faceDetectionResponse = null; boolean finished = false; String status; int yy = 0; do { if (faceDetectionResponse != null) paginationToken = faceDetectionResponse.nextToken(); GetFaceDetectionRequest recognitionRequest = GetFaceDetectionRequest.builder() .jobId(startJobId) .nextToken(paginationToken) .maxResults(10) .build(); // Wait until the job succeeds. while (!finished) { faceDetectionResponse = rekClient.getFaceDetection(recognitionRequest); status = faceDetectionResponse.jobStatusAsString(); if (status.compareTo("SUCCEEDED") == 0) finished = true; else { System.out.println(yy + " status is: " + status); Thread.sleep(1000); } yy++; } finished = false; // Proceed when the job is done - otherwise VideoMetadata is null. VideoMetadata videoMetaData = faceDetectionResponse.videoMetadata(); System.out.println("Format: " + videoMetaData.format()); System.out.println("Codec: " + videoMetaData.codec()); System.out.println("Duration: " + videoMetaData.durationMillis()); System.out.println("FrameRate: " + videoMetaData.frameRate()); System.out.println("Job"); // Show face information. List<FaceDetection> faces = faceDetectionResponse.faces(); for (FaceDetection face : faces) { String age = face.face().ageRange().toString(); String smile = face.face().smile().toString(); System.out.println("The detected face is estimated to be" + age + " years old."); System.out.println("There is a smile : " + smile); } } while (faceDetectionResponse != null && faceDetectionResponse.nextToken() != null); } catch (RekognitionException | InterruptedException e) { System.out.println(e.getMessage()); System.exit(1); } } }
    Python
    #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.) # ============== Face Search =============== def StartFaceSearchCollection(self,collection): response = self.rek.start_face_search(Video={'S3Object':{'Bucket':self.bucket,'Name':self.video}}, CollectionId=collection, NotificationChannel={'RoleArn':self.roleArn, 'SNSTopicArn':self.snsTopicArn}) self.startJobId=response['JobId'] print('Start Job Id: ' + self.startJobId) def GetFaceSearchCollectionResults(self): maxResults = 10 paginationToken = '' finished = False while finished == False: response = self.rek.get_face_search(JobId=self.startJobId, MaxResults=maxResults, NextToken=paginationToken) print(response['VideoMetadata']['Codec']) print(str(response['VideoMetadata']['DurationMillis'])) print(response['VideoMetadata']['Format']) print(response['VideoMetadata']['FrameRate']) for personMatch in response['Persons']: print('Person Index: ' + str(personMatch['Person']['Index'])) print('Timestamp: ' + str(personMatch['Timestamp'])) if ('FaceMatches' in personMatch): for faceMatch in personMatch['FaceMatches']: print('Face ID: ' + faceMatch['Face']['FaceId']) print('Similarity: ' + str(faceMatch['Similarity'])) print() if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True print()

    main 함수에서 다음 줄을 바꿉니다.

    analyzer.StartLabelDetection() if analyzer.GetSQSMessageSuccess()==True: analyzer.GetLabelDetectionResults()

    다음으로 바꿉니다.

    collection='tests' analyzer.StartFaceSearchCollection(collection) if analyzer.GetSQSMessageSuccess()==True: analyzer.GetFaceSearchCollectionResults()

    Java 또는 Python으로 Amazon S3 버킷에 저장된 비디오 분석(SDK) 이외에 비디오 예제를 이미 실행한 경우, 바꿀 코드가 다를 수 있습니다.

  5. collection의 값을, 1단계에서 만든 모음의 이름으로 변경합니다.

  6. 코드를 실행합니다. 입력 모음의 얼굴과 일치하는 비디오의 사람 목록이 표시됩니다. 일치하는 각 사람의 추적 데이터도 표시됩니다.

GetFaceSearch 작업 응답

다음은 GetFaceSearch의 JSON 응답 예제입니다.

응답에는 입력 모음의 얼굴과 얼굴이 일치하는 동영상에서 감지된 일련의 사람 Persons이 포함됩니다. 비디오에서 사람이 매칭될 때마다 배열 PersonMatch요소인 가 존재합니다. 각 항목에는 입력 컬렉션의 얼굴 일치 항목 배열 FaceMatch, 짝을 이룬 사람에 대한 정보 PersonDetail, 비디오에서 상대가 매칭된 시간 등이 PersonMatch 포함됩니다.

{ "JobStatus": "SUCCEEDED", "NextToken": "IJdbzkZfvBRqj8GPV82BPiZKkLOGCqDIsNZG/gQsEE5faTVK9JHOz/xxxxxxxxxxxxxxx", "Persons": [ { "FaceMatches": [ { "Face": { "BoundingBox": { "Height": 0.527472972869873, "Left": 0.33530598878860474, "Top": 0.2161169946193695, "Width": 0.35503000020980835 }, "Confidence": 99.90239715576172, "ExternalImageId": "image.PNG", "FaceId": "a2f2e224-bfaa-456c-b360-7c00241e5e2d", "ImageId": "eb57ed44-8d8d-5ec5-90b8-6d190daff4c3" }, "Similarity": 98.40909576416016 } ], "Person": { "BoundingBox": { "Height": 0.8694444298744202, "Left": 0.2473958283662796, "Top": 0.10092592239379883, "Width": 0.49427083134651184 }, "Face": { "BoundingBox": { "Height": 0.23000000417232513, "Left": 0.42500001192092896, "Top": 0.16333332657814026, "Width": 0.12937499582767487 }, "Confidence": 99.97504425048828, "Landmarks": [ { "Type": "eyeLeft", "X": 0.46415066719055176, "Y": 0.2572723925113678 }, { "Type": "eyeRight", "X": 0.5068183541297913, "Y": 0.23705792427062988 }, { "Type": "nose", "X": 0.49765899777412415, "Y": 0.28383663296699524 }, { "Type": "mouthLeft", "X": 0.487221896648407, "Y": 0.3452930748462677 }, { "Type": "mouthRight", "X": 0.5142884850502014, "Y": 0.33167609572410583 } ], "Pose": { "Pitch": 15.966927528381348, "Roll": -15.547388076782227, "Yaw": 11.34195613861084 }, "Quality": { "Brightness": 44.80223083496094, "Sharpness": 99.95819854736328 } }, "Index": 0 }, "Timestamp": 0 }, { "Person": { "BoundingBox": { "Height": 0.2177777737379074, "Left": 0.7593749761581421, "Top": 0.13333334028720856, "Width": 0.12250000238418579 }, "Face": { "BoundingBox": { "Height": 0.2177777737379074, "Left": 0.7593749761581421, "Top": 0.13333334028720856, "Width": 0.12250000238418579 }, "Confidence": 99.63436889648438, "Landmarks": [ { "Type": "eyeLeft", "X": 0.8005779385566711, "Y": 0.20915353298187256 }, { "Type": "eyeRight", "X": 0.8391435146331787, "Y": 0.21049551665782928 }, { "Type": "nose", "X": 0.8191410899162292, "Y": 0.2523227035999298 }, { "Type": "mouthLeft", "X": 0.8093273043632507, "Y": 0.29053622484207153 }, { "Type": "mouthRight", "X": 0.8366993069648743, "Y": 0.29101791977882385 } ], "Pose": { "Pitch": 3.165884017944336, "Roll": 1.4182015657424927, "Yaw": -11.151537895202637 }, "Quality": { "Brightness": 28.910892486572266, "Sharpness": 97.61507415771484 } }, "Index": 1 }, "Timestamp": 0 }, { "Person": { "BoundingBox": { "Height": 0.8388888835906982, "Left": 0, "Top": 0.15833333134651184, "Width": 0.2369791716337204 }, "Face": { "BoundingBox": { "Height": 0.20000000298023224, "Left": 0.029999999329447746, "Top": 0.2199999988079071, "Width": 0.11249999701976776 }, "Confidence": 99.85971069335938, "Landmarks": [ { "Type": "eyeLeft", "X": 0.06842322647571564, "Y": 0.3010137975215912 }, { "Type": "eyeRight", "X": 0.10543643683195114, "Y": 0.29697132110595703 }, { "Type": "nose", "X": 0.09569807350635529, "Y": 0.33701086044311523 }, { "Type": "mouthLeft", "X": 0.0732642263174057, "Y": 0.3757539987564087 }, { "Type": "mouthRight", "X": 0.10589495301246643, "Y": 0.3722417950630188 } ], "Pose": { "Pitch": -0.5589138865470886, "Roll": -5.1093974113464355, "Yaw": 18.69594955444336 }, "Quality": { "Brightness": 43.052337646484375, "Sharpness": 99.68138885498047 } }, "Index": 2 }, "Timestamp": 0 }...... ], "VideoMetadata": { "Codec": "h264", "DurationMillis": 67301, "Format": "QuickTime / MOV", "FrameHeight": 1080, "FrameRate": 29.970029830932617, "FrameWidth": 1920 } }