检测图像中的文本 - Amazon Rekognition

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

检测图像中的文本

您可以提供输入图像作为图像字节数组(base64 编码的图像字节)或 Amazon S3 对象。在此过程中,您将 JPEG 或 PNG 图像上传到您的 S3 存储桶并指定文件名称。

检测图像中的文本 (API)
  1. 如果您尚未完成,请完成以下先决条件。

    1. 使用 AmazonRekognitionFullAccessAmazonS3ReadOnlyAccess 权限创建或更新用户。有关更多信息,请参阅 步骤 1:设置AWS账户并创建用户

    2. 安装和配置 AWS Command Line Interface 和 AWS SDK。有关更多信息,请参阅 第 2 步:设置 AWS CLI 以及 AWS SDKs

  2. 将包含文本的图像上传到您的 S3 存储桶。

    有关说明,请参阅《Amazon Simple Storage Service 用户指南》中的将对象上传到 Amazon S3

  3. 使用以下示例调用 DetectText 操作。

    Java

    以下示例代码显示在图像中检测到的行和单词。

    bucketphoto的值替换为您在步骤 2 中使用的 S3 存储桶和图像的名称。

    //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.AmazonRekognitionException; import com.amazonaws.services.rekognition.model.Image; import com.amazonaws.services.rekognition.model.S3Object; import com.amazonaws.services.rekognition.model.DetectTextRequest; import com.amazonaws.services.rekognition.model.DetectTextResult; import com.amazonaws.services.rekognition.model.TextDetection; import java.util.List; public class DetectText { public static void main(String[] args) throws Exception { String photo = "inputtext.jpg"; String bucket = "bucket"; AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.defaultClient(); DetectTextRequest request = new DetectTextRequest() .withImage(new Image() .withS3Object(new S3Object() .withName(photo) .withBucket(bucket))); try { DetectTextResult result = rekognitionClient.detectText(request); List<TextDetection> textDetections = result.getTextDetections(); System.out.println("Detected lines and words for " + photo); for (TextDetection text: textDetections) { System.out.println("Detected: " + text.getDetectedText()); System.out.println("Confidence: " + text.getConfidence().toString()); System.out.println("Id : " + text.getId()); System.out.println("Parent Id: " + text.getParentId()); System.out.println("Type: " + text.getType()); System.out.println(); } } catch(AmazonRekognitionException e) { e.printStackTrace(); } } }
    Java V2

    此代码取自 AWS 文档 SDK 示例 GitHub 存储库。请在此处查看完整示例。

    /** * 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 */ //snippet-start:[rekognition.java2.detect_text.import] import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.rekognition.model.DetectTextRequest; import software.amazon.awssdk.services.rekognition.model.Image; import software.amazon.awssdk.services.rekognition.model.DetectTextResponse; import software.amazon.awssdk.services.rekognition.model.TextDetection; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.List; //snippet-end:[rekognition.java2.detect_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 DetectTextImage { public static void main(String[] args) { final String usage = "\n" + "Usage: " + " <sourceImage>\n\n" + "Where:\n" + " sourceImage - The path to the image that contains text (for example, C:\\AWS\\pic1.png). \n\n"; if (args.length != 1) { System.out.println(usage); System.exit(1); } String sourceImage = args[0] ; Region region = Region.US_WEST_2; RekognitionClient rekClient = RekognitionClient.builder() .region(region) .credentialsProvider(ProfileCredentialsProvider.create("default")) .build(); detectTextLabels(rekClient, sourceImage ); rekClient.close(); } // snippet-start:[rekognition.java2.detect_text.main] public static void detectTextLabels(RekognitionClient rekClient, String sourceImage) { try { InputStream sourceStream = new FileInputStream(sourceImage); SdkBytes sourceBytes = SdkBytes.fromInputStream(sourceStream); Image souImage = Image.builder() .bytes(sourceBytes) .build(); DetectTextRequest textRequest = DetectTextRequest.builder() .image(souImage) .build(); DetectTextResponse textResponse = rekClient.detectText(textRequest); List<TextDetection> textCollection = textResponse.textDetections(); System.out.println("Detected lines and words"); for (TextDetection text: textCollection) { System.out.println("Detected: " + text.detectedText()); System.out.println("Confidence: " + text.confidence().toString()); System.out.println("Id : " + text.id()); System.out.println("Parent Id: " + text.parentId()); System.out.println("Type: " + text.type()); System.out.println(); } } catch (RekognitionException | FileNotFoundException e) { System.out.println(e.getMessage()); System.exit(1); } } // snippet-end:[rekognition.java2.detect_text.main]
    AWS CLI

    此 AWS CLI 命令显示 detect-text CLI 操作的 JSON 输出。

    BucketName的值替换为您在步骤 2 中使用的 S3 存储桶和图像的名称。

    profile_name的值替换为您的开发人员资料的名称。

    aws rekognition detect-text --image "{"S3Object":{"Bucket":"bucket-name","Name":"image-name"}}" --profile default

    如果您在 Windows 设备上访问 CLI,请使用双引号代替单引号,并用反斜杠(即 \)对内部双引号进行转义,以解决可能遇到的任何解析器错误。例如,请参阅以下内容:

    aws rekognition detect-text --image "{\"S3Object\":{\"Bucket\":\"bucket-name\",\"Name\":\"image-name\"}}" --profile default
    Python

    以下示例代码显示在图像中检测到的行和单词。

    bucketphoto的值替换为您在步骤 2 中使用的 S3 存储桶和图像的名称。将创建 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 detect_text(photo, bucket): session = boto3.Session(profile_name='default') client = session.client('rekognition') response = client.detect_text(Image={'S3Object': {'Bucket': bucket, 'Name': photo}}) textDetections = response['TextDetections'] print('Detected text\n----------') for text in textDetections: print('Detected text:' + text['DetectedText']) print('Confidence: ' + "{:.2f}".format(text['Confidence']) + "%") print('Id: {}'.format(text['Id'])) if 'ParentId' in text: print('Parent Id: {}'.format(text['ParentId'])) print('Type:' + text['Type']) print() return len(textDetections) def main(): bucket = 'bucket-name' photo = 'photo-name' text_count = detect_text(photo, bucket) print("Text detected: " + str(text_count)) if __name__ == "__main__": main()
    .NET

    以下示例代码显示在图像中检测到的行和单词。

    bucketphoto的值替换为您在步骤 2 中使用的 S3 存储桶和图像的名称。

    //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 Amazon.Rekognition; using Amazon.Rekognition.Model; public class DetectText { public static void Example() { String photo = "input.jpg"; String bucket = "bucket"; AmazonRekognitionClient rekognitionClient = new AmazonRekognitionClient(); DetectTextRequest detectTextRequest = new DetectTextRequest() { Image = new Image() { S3Object = new S3Object() { Name = photo, Bucket = bucket } } }; try { DetectTextResponse detectTextResponse = rekognitionClient.DetectText(detectTextRequest); Console.WriteLine("Detected lines and words for " + photo); foreach (TextDetection text in detectTextResponse.TextDetections) { Console.WriteLine("Detected: " + text.DetectedText); Console.WriteLine("Confidence: " + text.Confidence); Console.WriteLine("Id : " + text.Id); Console.WriteLine("Parent Id: " + text.ParentId); Console.WriteLine("Type: " + text.Type); } } catch (Exception e) { Console.WriteLine(e.Message); } } }
    Node.JS

    以下示例代码显示在图像中检测到的行和单词。

    bucketphoto的值替换为您在步骤 2 中使用的 S3 存储桶和图像的名称。将region的值替换为在您的 .aws 凭证中找到的区域。将创建 Rekognition 会话的行中的profile_name值替换为您的开发人员资料的名称。

    var AWS = require('aws-sdk'); const bucket = 'bucket' // the bucketname without s3:// const photo = 'photo' // the name of file const config = new AWS.Config({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }) AWS.config.update({region:'region'}); const client = new AWS.Rekognition(); const params = { Image: { S3Object: { Bucket: bucket, Name: photo }, }, } client.detectText(params, function(err, response) { if (err) { console.log(err, err.stack); // handle error if an error occurred } else { console.log(`Detected Text for: ${photo}`) console.log(response) response.TextDetections.forEach(label => { console.log(`Detected Text: ${label.DetectedText}`), console.log(`Type: ${label.Type}`), console.log(`ID: ${label.Id}`), console.log(`Parent ID: ${label.ParentId}`), console.log(`Confidence: ${label.Confidence}`), console.log(`Polygon: `) console.log(label.Geometry.Polygon) } ) } });

DetectText 操作请求

DetectText 操作中,您可将输入图像作为 base64 编码的字节数组提供,也可将其作为 Amazon S3 存储桶中存储的图像提供。以下示例 JSON 请求显示从 Amazon S3 存储桶加载的图像。

{ "Image": { "S3Object": { "Bucket": "bucket", "Name": "inputtext.jpg" } } }

筛选条件

通过按文本区域、大小和置信度评分进行筛选,您可以更加灵活地控制文本检测输出。通过使用感兴趣的区域,您可以轻松地将文本检测限制到与您相关的区域,例如,在从机器的图像中读取零件编号时,档案照片的右上角或相对于参考点的固定位置。单词边界框大小筛选器可用于避免噪点或不相关的小背景文本。通过单词置信度筛选器,您可以移除因模糊或脏污导致的不可靠的结果。

有关筛选值的信息,请参阅 DetectTextFilters

您可以使用以下筛选器:

  • MinConfidence— 设置字词检测的置信度。从结果中排除检测置信度低于此级别的单词。值应介于 0 和 100 之间。

  • MinBoundingBoxWidth— 设置单词边界框的最小宽度。将从结果中排除其边界框小于此值的单词。该值是相对于图像帧宽度的。

  • MinBoundingBoxHeight— 设置单词边框的最小高度。将从结果中排除其边界框高度小于此值的单词。该值是相对于图像帧高度的。

  • RegionsOfInterest— 将检测范围限制在图像帧的特定区域。这些值是相对于帧的尺寸的。对于仅部分位于区域内的文本,响应是不确定的。

DetectText 操作响应

DetectText操作分析图像并返回一个数组 TextDetections,其中每个元素 (TextDetection) 表示图像中检测到的行或字。对于每个元素,DetectText 将返回以下信息:

  • 检测到的文本 (DetectedText)

  • 单词与行之间的关系(IdParentId

  • 图像上的文本的位置 (Geometry)

  • Amazon Rekognition 对检测到的文本和边界框的准确性的置信度(Confidence

  • 检测到的文本的类型 (Type)

检测到的文本

每个 TextDetection 元素均包含在 DetectedText 字段中识别的文本(单词或行)。单词是一个或多个字母字符,不用空格分隔。在一个图像中,DetectText 最多可以检测 100 个单词。返回的文本可能包含使单词无法被识别的字符。例如,用 C@t 替换 Cat。要确定某个 TextDetection 元素是表示一行文本还是一个单词,请使用 Type 字段。

每个 TextDetection 元素均包含一个百分比值,表示 Amazon Rekognition 对检测到的文本和文本周围的边界框的准确性的置信度。

单词与行的关系

每个 TextDetection 元素都有一个标识符字段 IdId 显示单词在行中的位置。如果元素是单词,父标识符字段 ParentId 将标识检测到单词的行。行的 ParentId 为 null。例如,示例图中的行“but keep”具有以下 IdParentId 值:

文本

ID

父级 ID

but keep

3

but

8

3

keep

9

3

文本在图像上的位置

要确定识别的文本在图像上的位置,请使用 DetectText 返回的边界框 (Geometry) 信息。Geometry 对象包含两种类型的边界框信息,分别适用于检测到的行和单词:

  • 物体中轴对齐的粗矩形轮廓 BoundingBox

  • 数组中由多个 X 坐标和 Y 坐标组成的更精细的多边形

边界框和多边形坐标将显示文本在源图像上的位置。坐标值是占图像总体尺寸的比率。有关更多信息,请参阅BoundingBox

来自 DetectText 操作的以下 JSON 响应显示了下图中检测到的单词和行。

在砖块背景上写着 “现在是星期一但要保持微笑” 的文字旁边微笑着的咖啡杯,上面有文字边框。
{ 'TextDetections': [{'Confidence': 99.35693359375, 'DetectedText': "IT'S", 'Geometry': {'BoundingBox': {'Height': 0.09988046437501907, 'Left': 0.6684935688972473, 'Top': 0.18226495385169983, 'Width': 0.1461552083492279}, 'Polygon': [{'X': 0.6684935688972473, 'Y': 0.1838926374912262}, {'X': 0.8141663074493408, 'Y': 0.18226495385169983}, {'X': 0.8146487474441528, 'Y': 0.28051772713661194}, {'X': 0.6689760088920593, 'Y': 0.2821454107761383}]}, 'Id': 0, 'Type': 'LINE'}, {'Confidence': 99.6207275390625, 'DetectedText': 'MONDAY', 'Geometry': {'BoundingBox': {'Height': 0.11442459374666214, 'Left': 0.5566731691360474, 'Top': 0.3525116443634033, 'Width': 0.39574965834617615}, 'Polygon': [{'X': 0.5566731691360474, 'Y': 0.353712260723114}, {'X': 0.9522717595100403, 'Y': 0.3525116443634033}, {'X': 0.9524227976799011, 'Y': 0.4657355844974518}, {'X': 0.5568241477012634, 'Y': 0.46693623065948486}]}, 'Id': 1, 'Type': 'LINE'}, {'Confidence': 99.6160888671875, 'DetectedText': 'but keep', 'Geometry': {'BoundingBox': {'Height': 0.08314694464206696, 'Left': 0.6398131847381592, 'Top': 0.5267938375473022, 'Width': 0.2021435648202896}, 'Polygon': [{'X': 0.640289306640625, 'Y': 0.5267938375473022}, {'X': 0.8419567942619324, 'Y': 0.5295097827911377}, {'X': 0.8414806723594666, 'Y': 0.609940767288208}, {'X': 0.6398131847381592, 'Y': 0.6072247624397278}]}, 'Id': 2, 'Type': 'LINE'}, {'Confidence': 88.95134735107422, 'DetectedText': 'Smiling', 'Geometry': {'BoundingBox': {'Height': 0.4326171875, 'Left': 0.46289217472076416, 'Top': 0.5634765625, 'Width': 0.5371078252792358}, 'Polygon': [{'X': 0.46289217472076416, 'Y': 0.5634765625}, {'X': 1.0, 'Y': 0.5634765625}, {'X': 1.0, 'Y': 0.99609375}, {'X': 0.46289217472076416, 'Y': 0.99609375}]}, 'Id': 3, 'Type': 'LINE'}, {'Confidence': 99.35693359375, 'DetectedText': "IT'S", 'Geometry': {'BoundingBox': {'Height': 0.09988046437501907, 'Left': 0.6684935688972473, 'Top': 0.18226495385169983, 'Width': 0.1461552083492279}, 'Polygon': [{'X': 0.6684935688972473, 'Y': 0.1838926374912262}, {'X': 0.8141663074493408, 'Y': 0.18226495385169983}, {'X': 0.8146487474441528, 'Y': 0.28051772713661194}, {'X': 0.6689760088920593, 'Y': 0.2821454107761383}]}, 'Id': 4, 'ParentId': 0, 'Type': 'WORD'}, {'Confidence': 99.6207275390625, 'DetectedText': 'MONDAY', 'Geometry': {'BoundingBox': {'Height': 0.11442466825246811, 'Left': 0.5566731691360474, 'Top': 0.35251158475875854, 'Width': 0.39574965834617615}, 'Polygon': [{'X': 0.5566731691360474, 'Y': 0.3537122905254364}, {'X': 0.9522718787193298, 'Y': 0.35251158475875854}, {'X': 0.9524227976799011, 'Y': 0.4657355546951294}, {'X': 0.5568241477012634, 'Y': 0.46693626046180725}]}, 'Id': 5, 'ParentId': 1, 'Type': 'WORD'}, {'Confidence': 99.96778869628906, 'DetectedText': 'but', 'Geometry': {'BoundingBox': {'Height': 0.0625, 'Left': 0.6402802467346191, 'Top': 0.5283203125, 'Width': 0.08027780801057816}, 'Polygon': [{'X': 0.6402802467346191, 'Y': 0.5283203125}, {'X': 0.7205580472946167, 'Y': 0.5283203125}, {'X': 0.7205580472946167, 'Y': 0.5908203125}, {'X': 0.6402802467346191, 'Y': 0.5908203125}]}, 'Id': 6, 'ParentId': 2, 'Type': 'WORD'}, {'Confidence': 99.26438903808594, 'DetectedText': 'keep', 'Geometry': {'BoundingBox': {'Height': 0.0818721204996109, 'Left': 0.7344760298728943, 'Top': 0.5280686020851135, 'Width': 0.10748066753149033}, 'Polygon': [{'X': 0.7349520921707153, 'Y': 0.5280686020851135}, {'X': 0.8419566750526428, 'Y': 0.5295097827911377}, {'X': 0.8414806127548218, 'Y': 0.6099407076835632}, {'X': 0.7344760298728943, 'Y': 0.6084995269775391}]}, 'Id': 7, 'ParentId': 2, 'Type': 'WORD'}, {'Confidence': 88.95134735107422, 'DetectedText': 'Smiling', 'Geometry': {'BoundingBox': {'Height': 0.4326171875, 'Left': 0.46289217472076416, 'Top': 0.5634765625, 'Width': 0.5371078252792358}, 'Polygon': [{'X': 0.46289217472076416, 'Y': 0.5634765625}, {'X': 1.0, 'Y': 0.5634765625}, {'X': 1.0, 'Y': 0.99609375}, {'X': 0.46289217472076416, 'Y': 0.99609375}]}, 'Id': 8, 'ParentId': 3, 'Type': 'WORD'}], 'TextModelVersion': '3.0'}