View a markdown version of this page

Analysieren von Rechnungen und Belegen mit Amazon Textract - Amazon Textract

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Analysieren von Rechnungen und Belegen mit Amazon Textract

Verwenden Sie zur Analyse von Rechnungs- und Belegdokumenten die AnalyzeExpense API-Operationen und übergeben Sie eine Dokumentdatei als Eingabe. AnalyzeExpenseist eine synchrone Operation, die eine JSON-Struktur zurückgibt, die den analysierten Text enthält. Weitere Informationen finden Sie unter Rechnungen und Quittungen werden analysiert.

Um Rechnungen und Belege asynchron zu analysieren, verwenden Sie, StartExpenseAnalysis um mit der Verarbeitung einer Eingabedokumentdatei zu beginnen und die Ergebnisse abzurufenGetExpenseAnalysis.

Sie können ein Eingabedokument als Bildbyte-Array (base64-kodierte Bildbytes) oder als Amazon S3-Objekt bereitstellen. In diesem Verfahren laden Sie eine Bilddatei in Ihren S3-Bucket hoch und geben den Dateinamen an.

Um eine Rechnung oder Quittung (API) zu analysieren
  1. Wenn Sie dies noch nicht getan haben:

    1. Erteilen Sie einem Benutzer die AmazonTextractFullAccess und AmazonS3ReadOnlyAccess -Berechtigungen. Weitere Informationen finden Sie unter Schritt 1: Einrichten eines AWS-Kontos und Erstellen eines Benutzers.

    2. Installieren und konfigurieren Sie die SDKs AWS CLI und die AWS SDKs. Weitere Informationen finden Sie unter Schritt 2: Richten Sie das ein AWS CLI und AWS SDKs.

  2. Laden Sie ein Bild, das ein Dokument enthält, in Ihren S3-Bucket hoch.

    Weitere Anleitungen finden Sie unter Upload eines Objekts in Amazon S3 im Benutzerhandbuch für Amazon Simple Storage Service.

  3. Verwenden Sie die folgenden Beispiele zum Aufrufen der AnalyzeExpense-Operation.

    AWS CLI

    Dieser AWS CLI Befehl zeigt die JSON-Ausgabe für den analyze-expense CLI-Vorgang an.

    Ersetzen Sie die Werte von Bucket und Name durch die Namen des Amazon S3-Buckets und Dokuments, das Sie in Schritt 2 verwendet haben. profile-nameErsetzen Sie durch den Namen eines Profils, das die Rolle übernehmen kann, und region durch die Region, in der Sie den Code ausführen möchten.

    aws textract analyze-expense \ --document '{"S3Object": {"Bucket": "bucket","Name": "object"}}' \ --profile profile-name \ --region region
    Python

    Im folgenden Beispielcode werden das Dokument und die Felder rund um die erkannten Elemente angezeigt.

    Ersetzen Sie in der Funktion main die Werte von bucket und document durch die Namen des Amazon S3-Buckets und Dokuments, die Sie in Schritt 2 verwendet haben. profile-nameErsetzen Sie durch den Namen eines Profils, das die Rolle übernehmen kann, und region durch die Region, in der Sie den Code ausführen möchten.

    import boto3 import io from PIL import Image, ImageDraw def draw_bounding_box(key, val, width, height, draw): # If a key is Geometry, draw the bounding box info in it if "Geometry" in key: # Draw bounding box information box = val["BoundingBox"] left = width * box['Left'] top = height * box['Top'] draw.rectangle([left, top, left + (width * box['Width']), top + (height * box['Height'])], outline='black') # Takes a field as an argument and prints out the detected labels and values def print_labels_and_values(field): # Only if labels are detected and returned if "LabelDetection" in field: print("Summary Label Detection - Confidence: {}".format( str(field.get("LabelDetection")["Confidence"])) + ", " + "Summary Values: {}".format(str(field.get("LabelDetection")["Text"]))) print(field.get("LabelDetection")["Geometry"]) else: print("Label Detection - No labels returned.") if "ValueDetection" in field: print("Summary Value Detection - Confidence: {}".format( str(field.get("ValueDetection")["Confidence"])) + ", " + "Summary Values: {}".format(str(field.get("ValueDetection")["Text"]))) print(field.get("ValueDetection")["Geometry"]) else: print("Value Detection - No values returned") def process_expense_analysis(s3_connection, client, bucket, document): # Get the document from S3 s3_object = s3_connection.Object(bucket, document) s3_response = s3_object.get() # opening binary stream using an in-memory bytes buffer stream = io.BytesIO(s3_response['Body'].read()) # loading stream into image image = Image.open(stream) # Analyze document # process using S3 object response = client.analyze_expense( Document={'S3Object': {'Bucket': bucket, 'Name': document}}) # Set width and height to display image and draw bounding boxes # Create drawing object width, height = image.size draw = ImageDraw.Draw(image) for expense_doc in response["ExpenseDocuments"]: for line_item_group in expense_doc["LineItemGroups"]: for line_items in line_item_group["LineItems"]: for expense_fields in line_items["LineItemExpenseFields"]: print_labels_and_values(expense_fields) print() print("Summary:") for summary_field in expense_doc["SummaryFields"]: print_labels_and_values(summary_field) print() #For draw bounding boxes for line_item_group in expense_doc["LineItemGroups"]: for line_items in line_item_group["LineItems"]: for expense_fields in line_items["LineItemExpenseFields"]: for key, val in expense_fields["ValueDetection"].items(): if "Geometry" in key: draw_bounding_box(key, val, width, height, draw) for label in expense_doc["SummaryFields"]: if "LabelDetection" in label: for key, val in label["LabelDetection"].items(): draw_bounding_box(key, val, width, height, draw) # Display the image image.show() def main(): session = boto3.Session(profile_name='profile-name') s3_connection = session.resource('s3') client = session.client('textract', region_name='region') bucket = 'bucket' document = 'document' process_expense_analysis(s3_connection, client, bucket, document) if __name__ == "__main__": main()
    Java

    Im folgenden Beispielcode werden das Dokument und die Felder rund um die erkannten Elemente angezeigt.

    Ersetzen Sie in der Funktion main die Werte von bucket und document durch die Namen des Amazon S3-Buckets und des Dokumentbilds, die Sie in Schritt 2 verwendet haben.

    package com.amazonaws.samples; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.List; import java.util.concurrent.CompletableFuture; import javax.imageio.ImageIO; import javax.swing.*; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.core.ResponseBytes; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.*; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.GetObjectResponse; import software.amazon.awssdk.services.textract.TextractClient; import software.amazon.awssdk.services.textract.model.AnalyzeExpenseRequest; import software.amazon.awssdk.services.textract.model.AnalyzeExpenseResponse; import software.amazon.awssdk.services.textract.model.BoundingBox; import software.amazon.awssdk.services.textract.model.Document; import software.amazon.awssdk.services.textract.model.ExpenseDocument; import software.amazon.awssdk.services.textract.model.ExpenseField; import software.amazon.awssdk.services.textract.model.LineItemFields; import software.amazon.awssdk.services.textract.model.LineItemGroup; import software.amazon.awssdk.services.textract.model.S3Object; import software.amazon.awssdk.services.textract.model.Point; /** * * Demo code to parse Textract AnalyzeExpense API * */ public class TextractAnalyzeExpenseSample extends JPanel { private static final long serialVersionUID = 1L; BufferedImage image; static AnalyzeExpenseResponse result; public TextractAnalyzeExpenseSample(AnalyzeExpenseResponse documentResult, BufferedImage bufImage) throws Exception { super(); result = documentResult; // Results of analyzeexpense summaryfields and lineitemgroups detection. image = bufImage; // The image containing the document. } // Draws the image and text bounding box. public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; // Create a Java2D version of g. // Draw the image. g2d.drawImage(image, 0, 0, image.getWidth(this), image.getHeight(this), this); // Iterate through summaryfields and lineitemgroups and display boundedboxes around lines of detected label and value. List<ExpenseDocument> expenseDocuments = result.expenseDocuments(); for (ExpenseDocument expenseDocument : expenseDocuments) { if (expenseDocument.hasSummaryFields()) { DisplayAnalyzeExpenseSummaryInfo(expenseDocument); List<ExpenseField> summaryfields = expenseDocument.summaryFields(); for (ExpenseField summaryfield : summaryfields) { if (summaryfield.valueDetection() != null) { ShowBoundingBox(image.getHeight(this), image.getWidth(this), summaryfield.valueDetection().geometry().boundingBox(), g2d, new Color(0, 0, 0)); } if (summaryfield.labelDetection() != null) { ShowBoundingBox(image.getHeight(this), image.getWidth(this), summaryfield.labelDetection().geometry().boundingBox(), g2d, new Color(0, 0, 0)); } } } if (expenseDocument.hasLineItemGroups()) { DisplayAnalyzeExpenseLineItemGroupsInfo(expenseDocument); List<LineItemGroup> lineitemgroups = expenseDocument.lineItemGroups(); for (LineItemGroup lineitemgroup : lineitemgroups) { if (lineitemgroup.hasLineItems()) { List<LineItemFields> lineItems = lineitemgroup.lineItems(); for (LineItemFields lineitemfield : lineItems) { if (lineitemfield.hasLineItemExpenseFields()) { List<ExpenseField> expensefields = lineitemfield.lineItemExpenseFields(); for (ExpenseField expensefield : expensefields) { if (expensefield.valueDetection() != null) { ShowBoundingBox(image.getHeight(this), image.getWidth(this), expensefield.valueDetection().geometry().boundingBox(), g2d, new Color(0, 0, 0)); } if (expensefield.labelDetection() != null) { ShowBoundingBox(image.getHeight(this), image.getWidth(this), expensefield.labelDetection().geometry().boundingBox(), g2d, new Color(0, 0, 0)); } } } } } } } } } // Show bounding box at supplied location. private void ShowBoundingBox(float imageHeight, float imageWidth, BoundingBox box, Graphics2D g2d, Color color) { float left = imageWidth * box.left(); float top = imageHeight * box.top(); // Display bounding box. g2d.setColor(color); g2d.drawRect(Math.round(left), Math.round(top), Math.round(imageWidth * box.width()), Math.round(imageHeight * box.height())); } private void ShowSelectedElement(float imageHeight, float imageWidth, BoundingBox box, Graphics2D g2d, Color color) { float left = (float) imageWidth * (float) box.left(); float top = (float) imageHeight * (float) box.top(); System.out.println(left); System.out.println(top); // Display bounding box. g2d.setColor(color); g2d.fillRect(Math.round(left), Math.round(top), Math.round(imageWidth * box.width()), Math.round(imageHeight * box.height())); } // Shows polygon at supplied location private void ShowPolygon(int imageHeight, int imageWidth, List<Point> points, Graphics2D g2d) { g2d.setColor(new Color(0, 0, 0)); Polygon polygon = new Polygon(); // Construct polygon and display for (Point point : points) { polygon.addPoint((Math.round(point.x() * imageWidth)), Math.round(point.y() * imageHeight)); } g2d.drawPolygon(polygon); } private void DisplayAnalyzeExpenseSummaryInfo(ExpenseDocument expensedocument) { System.out.println(" ExpenseId : " + expensedocument.expenseIndex()); System.out.println(" Expense Summary information:"); if (expensedocument.hasSummaryFields()) { List<ExpenseField> summaryfields = expensedocument.summaryFields(); for (ExpenseField summaryfield : summaryfields) { System.out.println(" Page: " + summaryfield.pageNumber()); if (summaryfield.type() != null) { System.out.println(" Expense Summary Field Type:" + summaryfield.type().text()); } if (summaryfield.labelDetection() != null) { System.out.println(" Expense Summary Field Label:" + summaryfield.labelDetection().text()); System.out.println(" Geometry"); System.out.println(" Bounding Box: " + summaryfield.labelDetection().geometry().boundingBox().toString()); System.out.println( " Polygon: " + summaryfield.labelDetection().geometry().polygon().toString()); } if (summaryfield.valueDetection() != null) { System.out.println(" Expense Summary Field Value:" + summaryfield.valueDetection().text()); System.out.println(" Geometry"); System.out.println(" Bounding Box: " + summaryfield.valueDetection().geometry().boundingBox().toString()); System.out.println( " Polygon: " + summaryfield.valueDetection().geometry().polygon().toString()); } } } } private void DisplayAnalyzeExpenseLineItemGroupsInfo(ExpenseDocument expensedocument) { System.out.println(" ExpenseId : " + expensedocument.expenseIndex()); System.out.println(" Expense LineItemGroups information:"); if (expensedocument.hasLineItemGroups()) { List<LineItemGroup> lineitemgroups = expensedocument.lineItemGroups(); for (LineItemGroup lineitemgroup : lineitemgroups) { System.out.println(" Expense LineItemGroupsIndexID :" + lineitemgroup.lineItemGroupIndex()); if (lineitemgroup.hasLineItems()) { List<LineItemFields> lineItems = lineitemgroup.lineItems(); for (LineItemFields lineitemfield : lineItems) { if (lineitemfield.hasLineItemExpenseFields()) { List<ExpenseField> expensefields = lineitemfield.lineItemExpenseFields(); for (ExpenseField expensefield : expensefields) { if (expensefield.type() != null) { System.out.println(" Expense LineItem Field Type:" + expensefield.type().text()); } if (expensefield.valueDetection() != null) { System.out.println( " Expense Summary Field Value:" + expensefield.valueDetection().text()); System.out.println(" Geometry"); System.out.println(" Bounding Box: " + expensefield.valueDetection().geometry().boundingBox().toString()); System.out.println(" Polygon: " + expensefield.valueDetection().geometry().polygon().toString()); } if (expensefield.labelDetection() != null) { System.out.println( " Expense LineItem Field Label:" + expensefield.labelDetection().text()); System.out.println(" Geometry"); System.out.println(" Bounding Box: " + expensefield.labelDetection().geometry().boundingBox().toString()); System.out.println(" Polygon: " + expensefield.labelDetection().geometry().polygon().toString()); } } } } } } } } public static void main(String arg[]) throws Exception { // Creates a default async client with credentials and AWS Region loaded from // the // environment S3AsyncClient client = S3AsyncClient.builder().region(Region.US_EAST_1).build(); System.out.println("Creating the S3 Client"); // Start the call to Amazon S3, not blocking to wait for the result CompletableFuture<ResponseBytes<GetObjectResponse>> responseFuture = client.getObject( GetObjectRequest.builder().bucket("textractanalyzeexpense").key("input/sample-receipt.jpg").build(), AsyncResponseTransformer.toBytes()); System.out.println("Successfully read the object"); // When future is complete (either successfully or in error), handle the // response CompletableFuture<ResponseBytes<GetObjectResponse>> operationCompleteFuture = responseFuture .whenComplete((getObjectResponse, exception) -> { if (getObjectResponse != null) { // At this point, the file my-file.out has been created with the data // from S3; let's just print the object version // Convert this into Async call and remove the below block from here and put it // outside TextractClient textractclient = TextractClient.builder().region(Region.US_EAST_1).build(); AnalyzeExpenseRequest request = AnalyzeExpenseRequest.builder() .document( Document.builder().s3Object(S3Object.builder().name("YOURObjectName") .bucket("YOURBucket").build()).build()) .build(); AnalyzeExpenseResponse result = textractclient.analyzeExpense(request); System.out.print(result.toString()); ByteArrayInputStream bais = new ByteArrayInputStream(getObjectResponse.asByteArray()); try { BufferedImage image = ImageIO.read(bais); System.out.println("Successfully read the image"); JFrame frame = new JFrame("Expense Image"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); TextractAnalyzeExpense panel = new TextractAnalyzeExpense(result, image); panel.setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); frame.setContentPane(panel); frame.pack(); frame.setVisible(true); } catch (IOException e) { throw new RuntimeException(e); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { // Handle the error exception.printStackTrace(); } }); // We could do other work while waiting for the AWS call to complete in // the background, but we'll just wait for "whenComplete" to finish instead operationCompleteFuture.join(); } }
    Node.js

    Im folgenden Beispielcode werden das Dokument und die Felder rund um die erkannten Elemente angezeigt.

    Ersetzen Sie in der Funktion main die Werte von bucket und photo durch die Namen des Amazon S3-Buckets und Dokuments, die Sie in Schritt 2 verwendet haben. profileNameErsetzen Sie durch den Namen eines Profils, das die Rolle übernehmen kann, und region durch die Region, in der Sie den Code ausführen möchten.

    // Import required AWS SDK clients and commands for Node.js import { AnalyzeExpenseCommand } from "@aws-sdk/client-textract"; import { TextractClient } from "@aws-sdk/client-textract"; import {fromIni} from '@aws-sdk/credential-providers'; // Set the AWS Region. const REGION = "region-name"; //e.g. "us-east-1" const profileName = "profile-name"; // Create SNS service object. const textractClient = new TextractClient({region: REGION, credentials: fromIni({profile: profileName,}), }); const bucket = 'bucket-name' const photo = 'photo-name' // Set params const params = { Document: { S3Object: { Bucket: bucket, Name: photo }, }, } const process_text_detection = async () => { try { const aExpense = new AnalyzeExpenseCommand(params); const response = await textractClient.send(aExpense); //console.log(response) response.ExpenseDocuments.forEach(doc => { doc.LineItemGroups.forEach(items => { items.LineItems.forEach(fields => { fields.LineItemExpenseFields.forEach(expenseFields =>{ console.log(expenseFields) }) } )} ) } ) return response; // For unit tests. } catch (err) { console.log("Error", err); } } process_text_detection()
  4. Dadurch erhalten Sie die JSON-Ausgabe für den AnalyzeExpense Vorgang.