辨識已储存影片中的名人 - Amazon Rekognition

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

辨識已储存影片中的名人

Amazon Rekognition Video 在已储存影片中辨識名人是一種非同步操作。若要辨識儲存視訊中的名人,請使StartCelebrityRecognition用開始視訊分析。Amazon Rekognition Video 向其發佈影片分析操作的物件偵測結果和完成狀態的 Amazon Simple Notification Service 主題。如果影片分析成功,請呼叫 GetCelebrityRecognition 以取得分析結果。如需開始視訊分析並取得結果的詳細資訊,請參閱 呼叫 Amazon Rekognition Video 操作

此程序會展開 使用 Java 或 Python(SDK)分析存儲在 Amazon S3 存儲桶中的視頻 中的程式碼,該操作使用 Amazon SQS 佇列來取得影片分析要求的完成狀態。若要執行此程序,您需要含有一或多個名人臉部的影片檔案。

偵測存放在 Amazon S3 儲存貯體 (開發套件) 之影片中的名人
  1. 執行 使用 Java 或 Python(SDK)分析存儲在 Amazon S3 存儲桶中的視頻

  2. 將下列程式碼新增至您在步驟 1 中建立的類別 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.) // Celebrities===================================================================== private static void StartCelebrityDetection(String bucket, String video) throws Exception{ NotificationChannel channel= new NotificationChannel() .withSNSTopicArn(snsTopicArn) .withRoleArn(roleArn); StartCelebrityRecognitionRequest req = new StartCelebrityRecognitionRequest() .withVideo(new Video() .withS3Object(new S3Object() .withBucket(bucket) .withName(video))) .withNotificationChannel(channel); StartCelebrityRecognitionResult startCelebrityRecognitionResult = rek.startCelebrityRecognition(req); startJobId=startCelebrityRecognitionResult.getJobId(); } private static void GetCelebrityDetectionResults() throws Exception{ int maxResults=10; String paginationToken=null; GetCelebrityRecognitionResult celebrityRecognitionResult=null; do{ if (celebrityRecognitionResult !=null){ paginationToken = celebrityRecognitionResult.getNextToken(); } celebrityRecognitionResult = rek.getCelebrityRecognition(new GetCelebrityRecognitionRequest() .withJobId(startJobId) .withNextToken(paginationToken) .withSortBy(CelebrityRecognitionSortBy.TIMESTAMP) .withMaxResults(maxResults)); System.out.println("File info for page"); VideoMetadata videoMetaData=celebrityRecognitionResult.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("Job"); System.out.println("Job status: " + celebrityRecognitionResult.getJobStatus()); //Show celebrities List<CelebrityRecognition> celebs= celebrityRecognitionResult.getCelebrities(); for (CelebrityRecognition celeb: celebs) { long seconds=celeb.getTimestamp()/1000; System.out.print("Sec: " + Long.toString(seconds) + " "); CelebrityDetail details=celeb.getCelebrity(); System.out.println("Name: " + details.getName()); System.out.println("Id: " + details.getId()); System.out.println(); } } while (celebrityRecognitionResult !=null && celebrityRecognitionResult.getNextToken() != null); }

    在函數 main 中,將下行:

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

    取代為:

    StartCelebrityDetection(bucket, video); if (GetSQSMessageSuccess()==true) GetCelebrityDetectionResults();
    Java V2

    此代碼取自AWS文檔 SDK 示例 GitHub 存儲庫。請參閱此處的完整範例。

    //snippet-start:[rekognition.java2.recognize_video_celebrity.import] 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.S3Object; import software.amazon.awssdk.services.rekognition.model.NotificationChannel; import software.amazon.awssdk.services.rekognition.model.Video; import software.amazon.awssdk.services.rekognition.model.StartCelebrityRecognitionResponse; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import software.amazon.awssdk.services.rekognition.model.CelebrityRecognitionSortBy; import software.amazon.awssdk.services.rekognition.model.VideoMetadata; import software.amazon.awssdk.services.rekognition.model.CelebrityRecognition; import software.amazon.awssdk.services.rekognition.model.CelebrityDetail; import software.amazon.awssdk.services.rekognition.model.StartCelebrityRecognitionRequest; import software.amazon.awssdk.services.rekognition.model.GetCelebrityRecognitionRequest; import software.amazon.awssdk.services.rekognition.model.GetCelebrityRecognitionResponse; import java.util.List; //snippet-end:[rekognition.java2.recognize_video_celebrity.import] /** * To run this code example, ensure that you perform the Prerequisites as stated in the Amazon Rekognition Guide: * https://docs.aws.amazon.com/rekognition/latest/dg/video-analyzing-with-sqs.html * * Also, ensure that set up your development environment, including your credentials. * * For information, see this documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class RecognizeCelebritiesVideo { private static String startJobId =""; public static void main(String[] args) { final String usage = "\n" + "Usage: " + " <bucket> <video> <topicArn> <roleArn>\n\n" + "Where:\n" + " bucket - The name of the bucket in which the video is located (for example, (for example, myBucket). \n\n"+ " video - The name of video (for example, people.mp4). \n\n" + " topicArn - The ARN of the Amazon Simple Notification Service (Amazon SNS) topic. \n\n" + " roleArn - The ARN of the AWS Identity and Access Management (IAM) role to use. \n\n" ; 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) .credentialsProvider(ProfileCredentialsProvider.create("profile-name")) .build(); NotificationChannel channel = NotificationChannel.builder() .snsTopicArn(topicArn) .roleArn(roleArn) .build(); StartCelebrityDetection(rekClient, channel, bucket, video); GetCelebrityDetectionResults(rekClient); System.out.println("This example is done!"); rekClient.close(); } // snippet-start:[rekognition.java2.recognize_video_celebrity.main] public static void StartCelebrityDetection(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(); StartCelebrityRecognitionRequest recognitionRequest = StartCelebrityRecognitionRequest.builder() .jobTag("Celebrities") .notificationChannel(channel) .video(vidOb) .build(); StartCelebrityRecognitionResponse startCelebrityRecognitionResult = rekClient.startCelebrityRecognition(recognitionRequest); startJobId = startCelebrityRecognitionResult.jobId(); } catch(RekognitionException e) { System.out.println(e.getMessage()); System.exit(1); } } public static void GetCelebrityDetectionResults(RekognitionClient rekClient) { try { String paginationToken=null; GetCelebrityRecognitionResponse recognitionResponse = null; boolean finished = false; String status; int yy=0 ; do{ if (recognitionResponse !=null) paginationToken = recognitionResponse.nextToken(); GetCelebrityRecognitionRequest recognitionRequest = GetCelebrityRecognitionRequest.builder() .jobId(startJobId) .nextToken(paginationToken) .sortBy(CelebrityRecognitionSortBy.TIMESTAMP) .maxResults(10) .build(); // Wait until the job succeeds while (!finished) { recognitionResponse = rekClient.getCelebrityRecognition(recognitionRequest); status = recognitionResponse.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=recognitionResponse.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"); List<CelebrityRecognition> celebs= recognitionResponse.celebrities(); for (CelebrityRecognition celeb: celebs) { long seconds=celeb.timestamp()/1000; System.out.print("Sec: " + seconds + " "); CelebrityDetail details=celeb.celebrity(); System.out.println("Name: " + details.name()); System.out.println("Id: " + details.id()); System.out.println(); } } while (recognitionResponse.nextToken() != null); } catch(RekognitionException | InterruptedException e) { System.out.println(e.getMessage()); System.exit(1); } } // snippet-end:[rekognition.java2.recognize_video_celebrity.main] }
    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.) # ============== Celebrities =============== def StartCelebrityDetection(self): response=self.rek.start_celebrity_recognition(Video={'S3Object': {'Bucket': self.bucket, 'Name': self.video}}, NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.snsTopicArn}) self.startJobId=response['JobId'] print('Start Job Id: ' + self.startJobId) def GetCelebrityDetectionResults(self): maxResults = 10 paginationToken = '' finished = False while finished == False: response = self.rek.get_celebrity_recognition(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 celebrityRecognition in response['Celebrities']: print('Celebrity: ' + str(celebrityRecognition['Celebrity']['Name'])) print('Timestamp: ' + str(celebrityRecognition['Timestamp'])) print() if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True

    在函數 main 中,將下行:

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

    取代為:

    analyzer.StartCelebrityDetection() if analyzer.GetSQSMessageSuccess()==True: analyzer.GetCelebrityDetectionResults()
    Node.JS

    在下列 Node.Js 程式碼範例中,將 bucket 的值取代為包含您視訊的 S3 儲存貯體的名稱,並以視訊檔案的名稱取代 videoName 的值。您也需要將 roleArn 的值取代為與 IAM 服務角色相關聯的 Arn。最後,將 region 的值替換為與您帳戶關聯的操作區域的名稱。將建立 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 required AWS SDK clients and commands for Node.js import { CreateQueueCommand, GetQueueAttributesCommand, GetQueueUrlCommand, SetQueueAttributesCommand, DeleteQueueCommand, ReceiveMessageCommand, DeleteMessageCommand } from "@aws-sdk/client-sqs"; import {CreateTopicCommand, SubscribeCommand, DeleteTopicCommand } from "@aws-sdk/client-sns"; import { SQSClient } from "@aws-sdk/client-sqs"; import { SNSClient } from "@aws-sdk/client-sns"; import { RekognitionClient, StartLabelDetectionCommand, GetLabelDetectionCommand, StartCelebrityRecognitionCommand, GetCelebrityRecognitionCommand} from "@aws-sdk/client-rekognition"; import { stdout } from "process"; import {fromIni} from '@aws-sdk/credential-providers'; // Set the AWS Region. const REGION = "region-name"; //e.g. "us-east-1" // Set the profile name const profileName = "profile-name" // Name the collection // Create SNS service object. const sqsClient = new SQSClient({ region: REGION, credentials: fromIni({profile: profileName,}), }); const snsClient = new SNSClient({ region: REGION, credentials: fromIni({profile: profileName,}), }); const rekClient = new RekognitionClient({region: REGION, credentials: fromIni({profile: profileName,}), }); // Set bucket and video variables const bucket = "bucket-name"; const videoName = "video-name"; const roleArn = "role-arn" var startJobId = "" var ts = Date.now(); const snsTopicName = "AmazonRekognitionExample" + ts; const snsTopicParams = {Name: snsTopicName} const sqsQueueName = "AmazonRekognitionQueue-" + ts; // Set the parameters const sqsParams = { QueueName: sqsQueueName, //SQS_QUEUE_URL Attributes: { DelaySeconds: "60", // Number of seconds delay. MessageRetentionPeriod: "86400", // Number of seconds delay. }, }; const createTopicandQueue = async () => { try { // Create SNS topic const topicResponse = await snsClient.send(new CreateTopicCommand(snsTopicParams)); const topicArn = topicResponse.TopicArn console.log("Success", topicResponse); // Create SQS Queue const sqsResponse = await sqsClient.send(new CreateQueueCommand(sqsParams)); console.log("Success", sqsResponse); const sqsQueueCommand = await sqsClient.send(new GetQueueUrlCommand({QueueName: sqsQueueName})) const sqsQueueUrl = sqsQueueCommand.QueueUrl const attribsResponse = await sqsClient.send(new GetQueueAttributesCommand({QueueUrl: sqsQueueUrl, AttributeNames: ['QueueArn']})) const attribs = attribsResponse.Attributes console.log(attribs) const queueArn = attribs.QueueArn // subscribe SQS queue to SNS topic const subscribed = await snsClient.send(new SubscribeCommand({TopicArn: topicArn, Protocol:'sqs', Endpoint: queueArn})) const policy = { Version: "2012-10-17", Statement: [ { Sid: "MyPolicy", Effect: "Allow", Principal: {AWS: "*"}, Action: "SQS:SendMessage", Resource: queueArn, Condition: { ArnEquals: { 'aws:SourceArn': topicArn } } } ] }; const response = sqsClient.send(new SetQueueAttributesCommand({QueueUrl: sqsQueueUrl, Attributes: {Policy: JSON.stringify(policy)}})) console.log(response) console.log(sqsQueueUrl, topicArn) return [sqsQueueUrl, topicArn] } catch (err) { console.log("Error", err); } }; const startCelebrityDetection = async(roleArn, snsTopicArn) =>{ try { //Initiate label detection and update value of startJobId with returned Job ID const response = await rekClient.send(new StartCelebrityRecognitionCommand({Video:{S3Object:{Bucket:bucket, Name:videoName}}, NotificationChannel:{RoleArn: roleArn, SNSTopicArn: snsTopicArn}})) startJobId = response.JobId console.log(`Start Job ID: ${startJobId}`) return startJobId } catch (err) { console.log("Error", err); } }; const getCelebrityRecognitionResults = async(startJobId) =>{ try { //Initiate label detection and update value of startJobId with returned Job ID var maxResults = 10 var paginationToken = '' var finished = false while (finished == false){ var response = await rekClient.send(new GetCelebrityRecognitionCommand({JobId: startJobId, MaxResults: maxResults, NextToken: paginationToken})) console.log(response.VideoMetadata.Codec) console.log(response.VideoMetadata.DurationMillis) console.log(response.VideoMetadata.Format) console.log(response.VideoMetadata.FrameRate) response.Celebrities.forEach(celebrityRecognition => { console.log(`Celebrity: ${celebrityRecognition.Celebrity.Name}`) console.log(`Timestamp: ${celebrityRecognition.Timestamp}`) console.log() }) // Searh for pagination token, if found, set variable to next token if (String(response).includes("NextToken")){ paginationToken = response.NextToken }else{ finished = true } } } catch (err) { console.log("Error", err); } }; // Checks for status of job completion const getSQSMessageSuccess = async(sqsQueueUrl, startJobId) => { try { // Set job found and success status to false initially var jobFound = false var succeeded = false var dotLine = 0 // while not found, continue to poll for response while (jobFound == false){ var sqsReceivedResponse = await sqsClient.send(new ReceiveMessageCommand({QueueUrl:sqsQueueUrl, MaxNumberOfMessages:'ALL', MaxNumberOfMessages:10})); if (sqsReceivedResponse){ var responseString = JSON.stringify(sqsReceivedResponse) if (!responseString.includes('Body')){ if (dotLine < 40) { console.log('.') dotLine = dotLine + 1 }else { console.log('') dotLine = 0 }; stdout.write('', () => { console.log(''); }); await new Promise(resolve => setTimeout(resolve, 5000)); continue } } // Once job found, log Job ID and return true if status is succeeded for (var message of sqsReceivedResponse.Messages){ console.log("Retrieved messages:") var notification = JSON.parse(message.Body) var rekMessage = JSON.parse(notification.Message) var messageJobId = rekMessage.JobId if (String(rekMessage.JobId).includes(String(startJobId))){ console.log('Matching job found:') console.log(rekMessage.JobId) jobFound = true console.log(rekMessage.Status) if (String(rekMessage.Status).includes(String("SUCCEEDED"))){ succeeded = true console.log("Job processing succeeded.") var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle})); } }else{ console.log("Provided Job ID did not match returned ID.") var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle})); } } } return succeeded } catch(err) { console.log("Error", err); } }; // Start label detection job, sent status notification, check for success status // Retrieve results if status is "SUCEEDED", delete notification queue and topic const runCelebRecognitionAndGetResults = async () => { try { const sqsAndTopic = await createTopicandQueue(); //const startLabelDetectionRes = await startLabelDetection(roleArn, sqsAndTopic[1]); //const getSQSMessageStatus = await getSQSMessageSuccess(sqsAndTopic[0], startLabelDetectionRes) const startCelebrityDetectionRes = await startCelebrityDetection(roleArn, sqsAndTopic[1]); const getSQSMessageStatus = await getSQSMessageSuccess(sqsAndTopic[0], startCelebrityDetectionRes) console.log(getSQSMessageSuccess) if (getSQSMessageSuccess){ console.log("Retrieving results:") const results = await getCelebrityRecognitionResults(startCelebrityDetectionRes) } const deleteQueue = await sqsClient.send(new DeleteQueueCommand({QueueUrl: sqsAndTopic[0]})); const deleteTopic = await snsClient.send(new DeleteTopicCommand({TopicArn: sqsAndTopic[1]})); console.log("Successfully deleted.") } catch (err) { console.log("Error", err); } }; runCelebRecognitionAndGetResults()
    CLI

    執行以下 AWS CLI 命令來開始偵測影片中的標籤。

    aws rekognition start-celebrity-recognition --video "{"S3Object":{"Bucket":"bucket-name","Name":"video-name"}}" \ --notification-channel "{"SNSTopicArn":"topic-arn","RoleArn":"role-arn"}" \ --region region-name --profile profile-name

    更新下列的值:

    • bucket-namevideo-name 變更為您在步驟 2 中指定的 Amazon S3 儲存貯體與視訊檔名稱。

    • region-name 變更為您正在使用的 AWS 區域。

    • 使用您開發人員設定檔的名稱取代 profile-name 的值。

    • topic-ARN 變更為您在 設定 Amazon Rekognition Video 中的步驟 3 建立的 Amazon SNS 主題的 ARN。

    • role-ARN 變更為您在步驟 7 建立的 設定 Amazon Rekognition Video 服務角色的 ARN。

    如果您在 Windows 裝置上存取 CLI,請使用雙引號而非單引號,並以反斜線 (即\) 替代內部雙引號,以解決您可能遇到的任何剖析器錯誤。如需範例,請參閱下列內容:

    aws rekognition start-celebrity-recognition --video "{\"S3Object\":{\"Bucket\":\"bucket-name\",\"Name\":\"video-name\"}}" \ --notification-channel "{\"SNSTopicArn\":\"topic-arn\",\"RoleArn\":\"role-arn\"}" \ --region region-name --profile profile-name

    執行正在進行的程式碼範例之後,複製傳回的程式碼 jobID,並將其提供給下列 GetCelebrityRecognition 命令,以 job-id-number 取代您之前收到的 jobID 結果:

    aws rekognition get-celebrity-recognition --job-id job-id-number --profile profile-name
    注意

    如果您已執行 使用 Java 或 Python(SDK)分析存儲在 Amazon S3 存儲桶中的視頻 以外的視訊範例,要取代的程式碼可能會不同。

  3. 執行程式碼。在影片中辨識出之名人的資訊便會顯示。

GetCelebrityRecognition 作業回應

以下是 JSON 回應的範例。回應包含下列內容:

  • 已辨識的名人Celebrities 是影片中已辨識之名人的陣列與辨識時間。每當在影片中辨識出該名人時,就會有一個 CelebrityRecognition 物件。每個 CelebrityRecognition​ 包含經識別名人的資訊 (CelebrityDetail) 和名人在影片中識別的時間 (Timestamp​)。會在影片開頭量測 Timestamp (單位:毫秒)。

  • CelebrityDetail— 包含有關公認名人的信息。其包括名人姓名 (Name)、識別符 (ID)、名人的已知性別 (KnownGender) 與指向相關內容的 URL 清單 (Urls)。它還包括 Amazon Rekognition Video 在識別準確性方面具有的信心水平,以及有關名人臉部的詳細信息。FaceDetail如果您之後需要取得相關內容,可以搭配 getCelebrityInfo 使用 ID

  • VideoMetadata— 已分析視訊的相關資訊。

{ "Celebrities": [ { "Celebrity": { "Confidence": 0.699999988079071, "Face": { "BoundingBox": { "Height": 0.20555555820465088, "Left": 0.029374999925494194, "Top": 0.22333332896232605, "Width": 0.11562500149011612 }, "Confidence": 99.89837646484375, "Landmarks": [ { "Type": "eyeLeft", "X": 0.06857934594154358, "Y": 0.30842265486717224 }, { "Type": "eyeRight", "X": 0.10396526008844376, "Y": 0.300625205039978 }, { "Type": "nose", "X": 0.0966852456331253, "Y": 0.34081998467445374 }, { "Type": "mouthLeft", "X": 0.075217105448246, "Y": 0.3811396062374115 }, { "Type": "mouthRight", "X": 0.10744428634643555, "Y": 0.37407416105270386 } ], "Pose": { "Pitch": -0.9784082174301147, "Roll": -8.808176040649414, "Yaw": 20.28228759765625 }, "Quality": { "Brightness": 43.312068939208984, "Sharpness": 99.9305191040039 } }, "Id": "XXXXXX", "KnownGender": { "Type": "Female" }, "Name": "Celeb A", "Urls": [] }, "Timestamp": 367 },...... ], "JobStatus": "SUCCEEDED", "NextToken": "XfXnZKiyMOGDhzBzYUhS5puM+g1IgezqFeYpv/H/+5noP/LmM57FitUAwSQ5D6G4AB/PNwolrw==", "VideoMetadata": { "Codec": "h264", "DurationMillis": 67301, "FileExtension": "mp4", "Format": "QuickTime / MOV", "FrameHeight": 1080, "FrameRate": 29.970029830932617, "FrameWidth": 1920 } }