Processar resposta de processamento

A resposta a um pedido de processamento contém um Document objeto que contém tudo o que se sabe sobre o documento processado, incluindo todas as informações estruturadas que a IA Documental conseguiu extrair.

Esta página explica o esquema do objeto Document através de documentos de exemplo e, em seguida, mapeia os aspetos dos resultados de OCR para os elementos específicos do JSON do objeto Document. Também fornece bibliotecas cliente, exemplos de código e exemplos de código do SDK Document AI Toolbox. Estes exemplos de código usam o processamento online, mas a análise de objetos Document funciona da mesma forma para o processamento em lote.

handle-response-1

Os retângulos e as setas laranja e azuis representam que, respetivamente, pelo menos um campo dos objetos ligados é .layout ou detectedLanguage. O diagrama usa a notação de pé de galinha.

Use um visualizador JSON ou um utilitário de edição especificamente concebido para expandir ou reduzir elementos. A revisão de JSON não processado numa utilidade de texto simples é ineficiente.

Texto, esquema e índices de qualidade

Segue-se um exemplo de um documento de texto:

handle-response-2

Segue-se o objeto de documento completo devolvido pelo processador Enterprise Document OCR:

Transferir JSON

Este resultado do OCR também está sempre incluído no resultado do processador do Document AI, uma vez que o OCR é executado pelos processadores. Usa os dados de OCR existentes, pelo que pode introduzir esses dados JSON através da opção de documento inline nos processadores do 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

Seguem-se alguns dos campos importantes:

Texto não processado

O campo text contém o texto reconhecido pela IA Documental. Este texto não contém nenhuma estrutura de esquema além de espaços, tabulações e mudanças de linha. Este é o único campo que armazena informações textuais de um documento e serve como fonte de informações fidedignas do texto do documento. Outros campos podem referir-se a partes do campo de texto por posição (startIndex e endIndex).

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

Tamanho de página e idiomas

Cada page no objeto document corresponde a uma página física do documento de exemplo. O resultado JSON de exemplo contém uma página porque é uma única imagem PNG.

  {
    "pages:" [
      {
        "pageNumber": 1,
        "dimension": {
          "width": 679.0,
          "height": 460.0,
          "unit": "pixels"
        },
      }
    ]
  }
  • O campo pages[].detectedLanguages[] contém os idiomas encontrados numa determinada página, juntamente com a pontuação de confiança.
{
  "pages": [
    {
      "detectedLanguages": [
        {
          "confidence": 0.98009938,
          "languageCode": "en"
        },
        {
          "confidence": 0.01990064,
          "languageCode": "und"
        }
      ]
    }
  ]
}

Dados de OCR

O OCR da Document AI deteta texto com vários níveis de detalhe ou organização na página, como blocos de texto, parágrafos, tokens e símbolos (o nível de símbolo é opcional, se estiver configurado para gerar dados ao nível do símbolo). Estes são todos os membros do objeto de página.

Cada elemento tem um layout correspondente que descreve a respetiva posição e texto. Os elementos visuais que não são texto (como caixas de verificação) também estão ao nível da página.

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

O texto não processado é referido no objeto textAnchor que é indexado na string de texto principal com startIndex e endIndex.

  • Para boundingPoly, o canto superior esquerdo da página é a origem (0,0). Os valores X positivos estão à direita e os valores Y positivos estão para baixo.

  • O objeto vertices usa as mesmas coordenadas que a imagem original, enquanto que normalizedVertices estão no intervalo [0,1]. Existe uma matriz de transformação que indica as medidas de correção da distorção e outros atributos da normalização da imagem.

  • Para desenhar o boundingPoly, desenhe segmentos de linha de um vértice para o seguinte. Em seguida, feche o polígono desenhando um segmento de linha do último vértice de volta ao primeiro. O elemento orientation do esquema indica se o texto foi rodado relativamente à página.

Para ajudar a visualizar a estrutura do documento, as seguintes imagens desenham polígonos delimitadores para page.paragraphs, page.lines e page.tokens.

Parágrafos

handle-response-3

Linhas

handle-response-4

Tokens

handle-response-5

Blocos

handle-response-6

O processador Enterprise Document OCR pode realizar uma avaliação de qualidade de um documento com base na respetiva legibilidade.

Esta avaliação de qualidade é um índice de qualidade em [0, 1], em que 1 significa qualidade perfeita. O índice de qualidade é devolvido no campo Page.imageQualityScores. Todos os defeitos detetados são apresentados como quality/defect_* e ordenados por ordem descendente pelo valor de confiança.

Segue-se um PDF demasiado escuro e desfocado para ser lido confortavelmente:

Transferir PDF

Seguem-se as informações de qualidade do documento devolvidas pelo processador 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
            }
          ]
        }
      }
    ]
  }

Exemplos de código

Os seguintes exemplos de código demonstram como enviar um pedido de processamento e, em seguida, ler e imprimir os campos no terminal:

Java

Para mais informações, consulte a documentação de referência da API Java Document AI.

Para se autenticar no Document AI, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.


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.