Menangani respons pemrosesan

Respons terhadap permintaan pemrosesan berisi objek Document yang menyimpan semua yang diketahui tentang dokumen yang diproses, termasuk semua informasi terstruktur yang dapat diekstrak oleh Document AI.

Halaman ini menjelaskan tata letak objek Document dengan memberikan contoh dokumen, lalu memetakan aspek hasil OCR ke elemen tertentu dari JSON objek Document. Selain itu, juga menyediakan library klien, contoh kode, dan contoh kode SDK Document AI Toolbox. Contoh kode ini menggunakan pemrosesan online, tetapi penguraian objek Document berfungsi sama untuk pemrosesan batch.

handle-response-1

Persegi panjang dan panah berwarna oranye dan biru menunjukkan bahwa setidaknya satu kolom dari objek yang terhubung adalah .layout atau detectedLanguage. Diagram menggunakan notasi kaki gagak.

Gunakan penampil atau utilitas pengeditan JSON yang dirancang khusus untuk meluaskan atau menciutkan elemen. Meninjau JSON mentah dalam utilitas teks biasa tidak efisien.

Teks, tata letak, dan skor kualitas

Berikut adalah contoh dokumen teks:

handle-response-2

Berikut adalah objek dokumen lengkap seperti yang ditampilkan oleh pemroses Enterprise Document OCR:

Download JSON

Output OCR ini juga selalu disertakan dalam output pemroses Document AI, karena OCR dijalankan oleh pemroses. Fitur ini menggunakan data OCR yang ada, sehingga Anda dapat memasukkan data JSON tersebut menggunakan opsi dokumen inline ke dalam pemroses Document AI.

  image=None, # all our samples pass this var
  mime_type="application/json",
  inline_document=document_response # pass OCR output to CDE input - undocumented

Berikut beberapa kolom penting:

Teks mentah

Kolom text berisi teks yang dikenali oleh Document AI. Teks ini tidak berisi struktur tata letak selain spasi, tab, dan feed baris. Kolom ini adalah satu-satunya kolom yang menyimpan informasi tekstual dokumen dan berfungsi sebagai sumber tepercaya teks dokumen. Kolom lain dapat merujuk ke bagian kolom teks berdasarkan posisi (startIndex dan endIndex).

  {
    text: "Sample Document\nHeading 1\nLorem ipsum dolor sit amet, ..."
  }

Ukuran halaman dan bahasa

Setiap page dalam objek dokumen sesuai dengan halaman fisik dari dokumen contoh. Output JSON contoh berisi satu halaman karena merupakan satu gambar PNG.

  {
    "pages:" [
      {
        "pageNumber": 1,
        "dimension": {
          "width": 679.0,
          "height": 460.0,
          "unit": "pixels"
        },
      }
    ]
  }
{
  "pages": [
    {
      "detectedLanguages": [
        {
          "confidence": 0.98009938,
          "languageCode": "en"
        },
        {
          "confidence": 0.01990064,
          "languageCode": "und"
        }
      ]
    }
  ]
}

Data OCR

OCR Document AI mendeteksi teks dengan berbagai perincian atau organisasi di halaman, seperti blok teks, paragraf, token, dan simbol (tingkat simbol bersifat opsional, jika dikonfigurasi untuk menghasilkan data tingkat simbol). Semua ini adalah anggota objek halaman.

Setiap elemen memiliki layout yang sesuai yang mendeskripsikan posisi dan teksnya. Elemen visual non-teks (seperti kotak centang) juga berada di tingkat halaman.

{
  "pages": [
    {
      "paragraphs": [
        {
          "layout": {
            "textAnchor": {
              "textSegments": [
                {
                  "endIndex": "16"
                }
              ]
            },
            "confidence": 0.9939527,
            "boundingPoly": {
              "vertices": [ ... ],
              "normalizedVertices": [ ... ]
            },
            "orientation": "PAGE_UP"
          }
        }
      ]
    }
  ]
}

Teks mentah dirujuk dalam objek textAnchor yang diindeks ke dalam string teks utama dengan startIndex dan endIndex.

  • Untuk boundingPoly, sudut kiri atas halaman adalah asal (0,0). Nilai X positif berada di sebelah kanan, dan nilai Y positif berada di bawah.

  • Objek vertices menggunakan koordinat yang sama dengan gambar asli, sedangkan normalizedVertices berada dalam rentang [0,1]. Ada matriks transformasi yang menunjukkan ukuran pelurusan dan atribut normalisasi gambar lainnya.

  • Untuk menggambar boundingPoly, gambar segmen garis dari satu verteks ke verteks berikutnya. Kemudian, tutup poligon dengan menggambar segmen garis dari verteks terakhir kembali ke verteks pertama. Elemen orientasi tata letak menunjukkan apakah teks telah diputar relatif terhadap halaman.

Untuk membantu Anda memvisualisasikan struktur dokumen, gambar berikut menggambar poligon pembatas untuk page.paragraphs, page.lines, page.tokens.

Paragraf

handle-response-3

Garis

handle-response-4

Token

handle-response-5

Blok

handle-response-6

Prosesor Enterprise Document OCR dapat melakukan penilaian kualitas dokumen berdasarkan keterbacaannya.

Penilaian kualitas ini adalah skor kualitas dalam [0, 1], dengan 1 berarti kualitas sempurna. Skor kualitas ditampilkan di kolom Page.imageQualityScores. Semua kerusakan yang terdeteksi dicantumkan sebagai quality/defect_* dan diurutkan secara menurun berdasarkan nilai keyakinan.

Berikut adalah PDF yang terlalu gelap dan buram sehingga tidak nyaman dibaca:

Download PDF

Berikut informasi kualitas dokumen yang ditampilkan oleh pemroses Enterprise Document OCR:

  {
    "pages": [
      {
        "imageQualityScores": {
          "qualityScore": 0.7811847,
          "detectedDefects": [
            {
              "type": "quality/defect_document_cutoff",
              "confidence": 1.0
            },
            {
              "type": "quality/defect_glare",
              "confidence": 0.97849524
            },
            {
              "type": "quality/defect_text_cutoff",
              "confidence": 0.5
            }
          ]
        }
      }
    ]
  }

Contoh kode

Contoh kode berikut menunjukkan cara mengirim permintaan pemrosesan, lalu membaca dan mencetak kolom ke terminal:

Java

Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Document AI.

Untuk melakukan autentikasi ke Document AI, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import com.google.cloud.documentai.v1beta3.Document;
import com.google.cloud.documentai.v1beta3.DocumentProcessorServiceClient;
import com.google.cloud.documentai.v1beta3.DocumentProcessorServiceSettings;
import com.google.cloud.documentai.v1beta3.ProcessRequest;
import com.google.cloud.documentai.v1beta3.ProcessResponse;
import com.google.cloud.documentai.v1beta3.RawDocument;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

public class ProcessOcrDocument {
  public static void processOcrDocument()
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String location = "your-project-location"; // Format is "us" or "eu".
    String processerId = "your-processor-id";
    String filePath = "path/to/input/file.pdf";
    processOcrDocument(projectId, location, processerId, filePath);
  }

  public static void processOcrDocument(
      String projectId, String location, String processorId, String filePath)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs
    // to be created
    // once, and can be reused for multiple requests. After completing all of your
    // requests, call
    // the "close" method on the client to safely clean up any remaining background
    // resources.
    String endpoint = String.format("%s-documentai.googleapis.com:443", location);
    DocumentProcessorServiceSettings settings =
        DocumentProcessorServiceSettings.newBuilder().setEndpoint(endpoint).build();
    try (DocumentProcessorServiceClient client = DocumentProcessorServiceClient.create(settings)) {
      // The full resource name of the processor, e.g.:
      // projects/project-id/locations/location/processor/processor-id
      // You must create new processors in the Cloud Console first
      String name =
          String.format("projects/%s/locations/%s/processors/%s", projectId, location, processorId);

      // Read the file.
      byte[] imageFileData = Files.readAllBytes(Paths.get(filePath));

      // Convert the image data to a Buffer and base64 encode it.
      ByteString content = ByteString.copyFrom(imageFileData);

      RawDocument document =
          RawDocument.newBuilder().setContent(content).setMimeType("application/pdf").build();

      // Configure the process request.
      ProcessRequest request =
          ProcessRequest.newBuilder().setName(name).setRawDocument(document).build();

      // Recognizes text entities in the PDF document
      ProcessResponse result = client.processDocument(request);
      Document documentResponse = result.getDocument();

      System.out.println("Document processing complete.");

      // Read the text recognition output from the processor
      // For a full list of Document object attributes,
      // please reference this page:
      // https://googleapis.dev/java/google-cloud-document-ai/latest/index.html

      // Get all of the document text as one big string
      String text = documentResponse.getText();
      System.out.printf("Full document text: '%s'\n", escapeNewlines(text));

      // Read the text recognition output from the processor
      List<Document.Page> pages = documentResponse.getPagesList();
      System.out.printf("There are %s page(s) in this document.\n", pages.size());

      for (Document.Page page : pages) {
        System.out.printf("Page %d:\n", page.getPageNumber());
        printPageDimensions(page.getDimension());
        printDetectedLanguages(page.getDetectedLanguagesList());
        printParagraphs(page.getParagraphsList(), text);
        printBlocks(page.getBlocksList(), text);
        printLines(page.getLinesList(), text);
        printTokens(page.getTokensList(), text);
      }
    }
  }

  private static void printPageDimensions(Document.Page.Dimension dimension) {
    String unit = dimension.getUnit();
    System.out.printf("    Width: %.1f %s\n", dimension.getWidth(), unit);
    System.out.printf("    Height: %.1f %s\n", dimension.getHeight(), unit);
  }

  private static void printDetectedLanguages(
      List<Document.Page.DetectedLanguage> detectedLangauges) {
    System.out.println("    Detected languages:");
    for (Document.Page.DetectedLanguage detectedLanguage : detectedLangauges) {
      String languageCode = detectedLanguage.getLanguageCode();
      float confidence = detectedLanguage.getConfidence();
      System.out.printf("        %s (%.2f%%)\n", languageCode, confidence * 100.0);
    }
  }

  private static void printParagraphs(List<Document.Page.Paragraph> paragraphs, String text) {
    System.out.printf("    %d paragraphs detected:\n", paragraphs.size());
    Document.Page.Paragraph firstParagraph = paragraphs.get(0);
    String firstParagraphText = getLayoutText(firstParagraph.getLayout().getTextAnchor(), text);
    System.out.printf("        First paragraph text: %s\n", escapeNewlines(firstParagraphText));
    Document.Page.Paragraph