Menu
Amazon Rekognition
Developer Guide

Searching Stored Videos for Faces

You can search a collection for faces that match faces of people who are detected in a stored video or a streaming video. This section covers searching for faces in a stored video. For information about searching for faces in a streaming video, see Working with Streaming Videos.

The faces that you search for must first be indexed into a collection by using IndexFaces. For more information, see Adding Faces to a Collection.

Amazon Rekognition Video face searching follows the same asynchronous workflow as other Amazon Rekognition Video operations that analyze videos stored in an Amazon S3 bucket. To start searching for faces in a stored video, call StartFaceSearch and provide the ID of the collection that you want to search. Amazon Rekognition Video publishes the completion status of the video analysis to an Amazon Simple Notification Service topic. If the video analysis is succesful, call GetFaceSearch to get the search results. For more information about starting video analysis and getting the results, see Calling Amazon Rekognition Video Operations.

The following procedure shows how to search a collection for faces that match the faces of people who are detected in a video. The procedure also shows how to get the tracking data for people who are matched in the video. The procedure expands on the code in Analyzing a Video Stored in an Amazon S3 Bucket with Java or Python (SDK), which uses an Amazon Simple Queue Service (Amazon SQS) queue to get the completion status of a video analysis request.

To search a video for matching faces (SDK)

  1. Create a collection.

  2. Index a face into the collection.

  3. Perform Analyzing a Video Stored in an Amazon S3 Bucket with Java or Python (SDK).

  4. Add the following code to the class VideoDetect that you created in step 3.

    JavaPython
    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) throws Exception{ StartFaceSearchRequest req = new StartFaceSearchRequest() .withCollectionId("CollectionId") .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 GetResultsFaceSearchCollection() 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); }

    4a. In the function main, replace the line:

    StartLabels(bucket,video);

    with

    StartFaceSearchCollection(bucket,video);

    4b. Replace the line:

    GetResultsLabels();

    with:

    GetResultsFaceSearchCollection();

    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.) def GetResultsFaceSearchCollection(self, jobId): maxResults = 10 paginationToken = '' finished = False while finished == False: response = self.rek.get_face_search(JobId=jobId, 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()

    4a. In the function main, replace the line:

    response = self.rek.start_label_detection(Video={'S3Object': {'Bucket': self.bucket, 'Name': self.video}}, NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.topicArn})

    with:

    response = self.rek.start_face_search(Video={'S3Object':{'Bucket':self.bucket,'Name':self.video}}, CollectionId='CollectionId', NotificationChannel={'RoleArn':self.roleArn, 'SNSTopicArn':self.topicArn})

    4b. Replace the line:

    self.GetResultsLabels(rekMessage['JobId'])

    with:

    self.GetResultsFaceSearchCollection(rekMessage['JobId'])

    If you've already run a video example other than Analyzing a Video Stored in an Amazon S3 Bucket with Java or Python (SDK), the function name to replace is different.

  5. Change the value of CollectionId to the name of the collection you created in step 1.

  6. Run the code. A list of people in the video whose faces match those in the input collection is displayed. The tracking data for each matched person is also displayed.

GetFaceSearch Operation Response

The following is an example JSON response from GetFaceSearch.

The response includes an array of people (Persons) detected in the video whose faces matches a face in the input collection. An array element, PersonMatch, exists for each time the person is matched in the video. Each PersonMatch includes an array of face matches from the input collection, FaceMatch, information about the matched person, PersonDetail, and the time the person was matched in the video.

{ "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 } }