저장된 비디오에서 텍스트 감지 - Amazon Rekognition

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

저장된 비디오에서 텍스트 감지

Amazon Rekognition Video의 저장된 비디오 속 텍스트 감지는 비동기 작업입니다. 문자 감지를 시작하려면 전화하세요. StartTextDetection Amazon Rekognition Video는 비디오 분석의 완료 상태를 Amazon SNS 주제에 게시합니다. 비디오 분석에 성공하면 전화를 GetTextDetection걸어 분석 결과를 받아보세요. 비디오 분석 시작 및 결과 가져오기에 대한 자세한 내용은 Amazon Rekognition Video 작업 직접 호출 단원을 참조하십시오.

이 절차는 Java 또는 Python (SDK) 을 사용하여 Amazon S3 버킷에 저장된 비디오 분석의 코드를 확장하여 Amazon SQS 대기열을 사용해 비디오 분석 요청의 완료 상태를 가져옵니다.

Amazon S3 버킷에 저장된 비디오에서 텍스트를 감지하려면(SDK)
  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.) private static void StartTextDetection(String bucket, String video) throws Exception{ NotificationChannel channel= new NotificationChannel() .withSNSTopicArn(snsTopicArn) .withRoleArn(roleArn); StartTextDetectionRequest req = new StartTextDetectionRequest() .withVideo(new Video() .withS3Object(new S3Object() .withBucket(bucket) .withName(video))) .withNotificationChannel(channel); StartTextDetectionResult startTextDetectionResult = rek.startTextDetection(req); startJobId=startTextDetectionResult.getJobId(); } private static void GetTextDetectionResults() throws Exception{ int maxResults=10; String paginationToken=null; GetTextDetectionResult textDetectionResult=null; do{ if (textDetectionResult !=null){ paginationToken = textDetectionResult.getNextToken(); } textDetectionResult = rek.getTextDetection(new GetTextDetectionRequest() .withJobId(startJobId) .withNextToken(paginationToken) .withMaxResults(maxResults)); VideoMetadata videoMetaData=textDetectionResult.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()); //Show text, confidence values List<TextDetectionResult> textDetections = textDetectionResult.getTextDetections(); for (TextDetectionResult text: textDetections) { long seconds=text.getTimestamp()/1000; System.out.println("Sec: " + Long.toString(seconds) + " "); TextDetection detectedText=text.getTextDetection(); System.out.println("Text Detected: " + detectedText.getDetectedText()); System.out.println("Confidence: " + detectedText.getConfidence().toString()); System.out.println("Id : " + detectedText.getId()); System.out.println("Parent Id: " + detectedText.getParentId()); System.out.println("Bounding Box" + detectedText.getGeometry().getBoundingBox().toString()); System.out.println("Type: " + detectedText.getType()); System.out.println(); } } while (textDetectionResult !=null && textDetectionResult.getNextToken() != null); }

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

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

    다음으로 바꿉니다.

    StartTextDetection(bucket, video); if (GetSQSMessageSuccess()==true) GetTextDetectionResults();
    Java V2

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

    //snippet-start:[rekognition.java2.recognize_video_text.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.StartTextDetectionRequest; import software.amazon.awssdk.services.rekognition.model.StartTextDetectionResponse; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import software.amazon.awssdk.services.rekognition.model.GetTextDetectionResponse; import software.amazon.awssdk.services.rekognition.model.GetTextDetectionRequest; import software.amazon.awssdk.services.rekognition.model.VideoMetadata; import software.amazon.awssdk.services.rekognition.model.TextDetectionResult; import java.util.List; //snippet-end:[rekognition.java2.recognize_video_text.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 DetectTextVideo { 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(); startTextLabels(rekClient, channel, bucket, video); GetTextResults(rekClient); System.out.println("This example is done!"); rekClient.close(); } // snippet-start:[rekognition.java2.recognize_video_text.main] public static void startTextLabels(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(); StartTextDetectionRequest labelDetectionRequest = StartTextDetectionRequest.builder() .jobTag("DetectingLabels") .notificationChannel(channel) .video(vidOb) .build(); StartTextDetectionResponse labelDetectionResponse = rekClient.startTextDetection(labelDetectionRequest); startJobId = labelDetectionResponse.jobId(); } catch (RekognitionException e) { System.out.println(e.getMessage()); System.exit(1); } } public static void GetTextResults(RekognitionClient rekClient) { try { String paginationToken=null; GetTextDetectionResponse textDetectionResponse=null; boolean finished = false; String status; int yy=0 ; do{ if (textDetectionResponse !=null) paginationToken = textDetectionResponse.nextToken(); GetTextDetectionRequest recognitionRequest = GetTextDetectionRequest.builder() .jobId(startJobId) .nextToken(paginationToken) .maxResults(10) .build(); // Wait until the job succeeds. while (!finished) { textDetectionResponse = rekClient.getTextDetection(recognitionRequest); status = textDetectionResponse.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=textDetectionResponse.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<TextDetectionResult> labels= textDetectionResponse.textDetections(); for (TextDetectionResult detectedText: labels) { System.out.println("Confidence: " + detectedText.textDetection().confidence().toString()); System.out.println("Id : " + detectedText.textDetection().id()); System.out.println("Parent Id: " + detectedText.textDetection().parentId()); System.out.println("Type: " + detectedText.textDetection().type()); System.out.println("Text: " + detectedText.textDetection().detectedText()); System.out.println(); } } while (textDetectionResponse !=null && textDetectionResponse.nextToken() != null); } catch(RekognitionException | InterruptedException e) { System.out.println(e.getMessage()); System.exit(1); } } // snippet-end:[rekognition.java2.recognize_video_text.main] }
    Python
    #Copyright 2019 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 StartTextDetection(self): response=self.rek.start_text_detection(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 GetTextDetectionResults(self): maxResults = 10 paginationToken = '' finished = False while finished == False: response = self.rek.get_text_detection(JobId=self.startJobId, MaxResults=maxResults, NextToken=paginationToken) print('Codec: ' + response['VideoMetadata']['Codec']) print('Duration: ' + str(response['VideoMetadata']['DurationMillis'])) print('Format: ' + response['VideoMetadata']['Format']) print('Frame rate: ' + str(response['VideoMetadata']['FrameRate'])) print() for textDetection in response['TextDetections']: text=textDetection['TextDetection'] print("Timestamp: " + str(textDetection['Timestamp'])) print(" Text Detected: " + text['DetectedText']) print(" Confidence: " + str(text['Confidence'])) print (" Bounding box") print (" Top: " + str(text['Geometry']['BoundingBox']['Top'])) print (" Left: " + str(text['Geometry']['BoundingBox']['Left'])) print (" Width: " + str(text['Geometry']['BoundingBox']['Width'])) print (" Height: " + str(text['Geometry']['BoundingBox']['Height'])) print (" Type: " + str(text['Type']) ) print() if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True

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

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

    다음으로 바꿉니다.

    analyzer.StartTextDetection() if analyzer.GetSQSMessageSuccess()==True: analyzer.GetTextDetectionResults()
    CLI

    다음 AWS CLI 명령어를 실행하여 동영상의 텍스트 감지를 시작합니다.

    aws rekognition start-text-detection --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-ARNAmazon Rekognition Video 구성의 3단계에서 생성한 Amazon SNS 주제의 ARN으로 변경합니다.

    • role-ARNAmazon Rekognition Video 구성의 7단계에서 생성한 IAM 서비스 역할의 ARN으로 변경합니다.

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

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

    진행 중인 코드 예제를 실행한 후 반환된 jobID를 복사하여 다음 GetTextDetection 명령에 제공하여 결과를 가져오고,job-id-number를 이전에 받은 jobID로 바꾸세요.

    aws rekognition get-text-detection --job-id job-id-number --profile profile-name
    참고

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

  3. 코드를 실행합니다. 비디오에서 감지된 텍스트가 목록에 표시됩니다.

필터

필터는 StartTextDetection을 호출할 때 사용할 수 있는 선택적 요청 파라미터입니다. 텍스트 영역, 크기 및 신뢰도 점수로 필터링하면 텍스트 감지 출력을 제어할 수 있는 추가적인 유연성이 제공됩니다. 관심 영역을 사용하면 텍스트 감지를 사용자와 관련된 영역으로 쉽게 제한할 수 있습니다. 그래픽에서 하단 자막 영역 또는 축구 경기에서 득점판이 보이는 왼쪽 상단 코너를 예로 들 수 있습니다. 단어 경계 상자 크기 필터는 정보 전달을 방해하거나 관련이 없는 작은 배경 텍스트를 피하는 데 사용할 수 있습니다. 마지막으로, 단어 신뢰도 필터를 사용하면 흐릿하거나 번져서 신뢰할 수 없는 결과를 제거할 수 있습니다.

필터 값에 대한 자세한 내용은 DetectTextFilters 섹션을 참조하세요.

다음 필터를 사용할 수 있습니다.

  • MinConfidence—단어 탐지의 신뢰 수준을 설정합니다. 이 수준보다 감지 신뢰도가 낮은 단어는 결과에서 제외됩니다. 값은 0과 100 사이여야 합니다.

  • MinBoundingBoxWidth— 단어 경계 상자의 최소 너비를 설정합니다. 경계 상자 너비가 이 값보다 작은 단어는 결과에서 제외됩니다. 이 값은 비디오 프레임 너비를 기준으로 합니다.

  • MinBoundingBoxHeight— 단어 경계 상자의 최소 높이를 설정합니다. 경계 상자 높이가 이 값보다 작은 단어는 결과에서 제외됩니다. 이 값은 비디오 프레임 높이를 기준으로 합니다.

  • RegionsOfInterest— 탐지를 프레임의 특정 영역으로 제한합니다. 값은 프레임 치수를 기준으로 합니다. 영역 내에 일부만 있는 객체의 경우 응답이 정의되지 않습니다.

GetTextDetection 응답

GetTextDetection은 비디오에서 감지된 텍스트에 대한 정보가 포함된 배열(TextDetectionResults)을 반환합니다. 배열 요소 TextDetection은 비디오에서 단어 또는 줄이 감지될 때마다 존재합니다. 배열 요소는 비디오 시작 후 시간별로(밀리초) 정렬됩니다.

다음은 GetTextDetection의 부분 JSON 응답입니다. 응답에서 다음에 유의하십시오.

  • 텍스트 정보TextDetectionResult 배열 요소에는 감지된 텍스트 (TextDetection) 와 비디오에서 텍스트가 감지된 시간 (Timestamp) 에 대한 정보가 들어 있습니다.

  • 페이징 정보 - 이 예제는 텍스트 감지 정보의 페이지 하나를 보여줍니다. GetTextDetectionMaxResults 입력 파라미터에 반환될 텍스트 요소의 수를 지정할 수 있습니다. MaxResults보다 많은 결과가 있거나 기본 최대값보다 많은 결과가 있는 경우 GetTextDetection은 결과의 다음 페이지를 가져올 때 사용되는 토큰(NextToken)을 반환합니다. 자세한 정보는 Amazon Rekognition Video 분석 결과 가져오기을 참조하세요.

  • 비디오 정보 - 응답에는 GetTextDetection에서 반환된 정보의 각 페이지에 있는 비디오 형식(VideoMetadata)에 관한 정보가 포함되어 있습니다.

{ "JobStatus": "SUCCEEDED", "VideoMetadata": { "Codec": "h264", "DurationMillis": 174441, "Format": "QuickTime / MOV", "FrameRate": 29.970029830932617, "FrameHeight": 480, "FrameWidth": 854 }, "TextDetections": [ { "Timestamp": 967, "TextDetection": { "DetectedText": "Twinkle Twinkle Little Star", "Type": "LINE", "Id": 0, "Confidence": 99.91780090332031, "Geometry": { "BoundingBox": { "Width": 0.8337579369544983, "Height": 0.08365312218666077, "Left": 0.08313830941915512, "Top": 0.4663468301296234 }, "Polygon": [ { "X": 0.08313830941915512, "Y": 0.4663468301296234 }, { "X": 0.9168962240219116, "Y": 0.4674469828605652 }, { "X": 0.916861355304718, "Y": 0.5511001348495483 }, { "X": 0.08310343325138092, "Y": 0.5499999523162842 } ] } } }, { "Timestamp": 967, "TextDetection": { "DetectedText": "Twinkle", "Type": "WORD", "Id": 1, "ParentId": 0, "Confidence": 99.98338317871094, "Geometry": { "BoundingBox": { "Width": 0.2423887550830841, "Height": 0.0833333358168602, "Left": 0.08313817530870438, "Top": 0.46666666865348816 }, "Polygon": [ { "X": 0.08313817530870438, "Y": 0.46666666865348816 }, { "X": 0.3255269229412079, "Y": 0.46666666865348816 }, { "X": 0.3255269229412079, "Y": 0.550000011920929 }, { "X": 0.08313817530870438, "Y": 0.550000011920929 } ] } } }, { "Timestamp": 967, "TextDetection": { "DetectedText": "Twinkle", "Type": "WORD", "Id": 2, "ParentId": 0, "Confidence": 99.982666015625, "Geometry": { "BoundingBox": { "Width": 0.2423887550830841, "Height": 0.08124999701976776, "Left": 0.3454332649707794, "Top": 0.46875 }, "Polygon": [ { "X": 0.3454332649707794, "Y": 0.46875 }, { "X": 0.5878220200538635, "Y": 0.46875 }, { "X": 0.5878220200538635, "Y": 0.550000011920929 }, { "X": 0.3454332649707794, "Y": 0.550000011920929 } ] } } }, { "Timestamp": 967, "TextDetection": { "DetectedText": "Little", "Type": "WORD", "Id": 3, "ParentId": 0, "Confidence": 99.8787612915039, "Geometry": { "BoundingBox": { "Width": 0.16627635061740875, "Height": 0.08124999701976776, "Left": 0.6053864359855652, "Top": 0.46875 }, "Polygon": [ { "X": 0.6053864359855652, "Y": 0.46875 }, { "X": 0.7716627717018127, "Y": 0.46875 }, { "X": 0.7716627717018127, "Y": 0.550000011920929 }, { "X": 0.6053864359855652, "Y": 0.550000011920929 } ] } } }, { "Timestamp": 967, "TextDetection": { "DetectedText": "Star", "Type": "WORD", "Id": 4, "ParentId": 0, "Confidence": 99.82640075683594, "Geometry": { "BoundingBox": { "Width": 0.12997658550739288, "Height": 0.08124999701976776, "Left": 0.7868852615356445, "Top": 0.46875 }, "Polygon": [ { "X": 0.7868852615356445, "Y": 0.46875 }, { "X": 0.9168618321418762, "Y": 0.46875 }, { "X": 0.9168618321418762, "Y": 0.550000011920929 }, { "X": 0.7868852615356445, "Y": 0.550000011920929 } ] } } } ], "NextToken": "NiHpGbZFnkM/S8kLcukMni15wb05iKtquu/Mwc+Qg1LVlMjjKNOD0Z0GusSPg7TONLe+OZ3P", "TextModelVersion": "3.0" }