1. Introdução
Neste codelab, você vai aprender a usar o analisador de formulários da Document AI para analisar um formulário escrito à mão com Python.
Usaremos um formulário de admissão médica simples como exemplo, mas esse procedimento funcionará com qualquer forma generalizada compatível com o DocAI.
Pré-requisitos
Este codelab se baseia no conteúdo apresentado em outros codelabs da Document AI.
Recomendamos que você conclua os codelabs a seguir antes de continuar.
O que você vai aprender
- Como analisar e extrair dados de um formulário digitalizado usando o analisador de formulários da Document AI.
O que é necessário
Pesquisa
Como você vai usar este tutorial?
Como você classificaria sua experiência com Python?
Como você classificaria sua experiência de uso dos serviços do Google Cloud?
2. Configuração e requisitos
Este codelab presume que você concluiu as etapas de configuração da Document AI listadas no Codelab da OCR da Document AI.
Conclua as etapas a seguir antes de continuar:
Também é necessário instalar o Pandas, uma biblioteca de análise de dados de código aberto para Python.
pip3 install --upgrade pandas
3. Criar um processador do analisador de formulários
Primeiro, é necessário criar uma instância do processador do analisador de formulários para usar na Document AI Platform neste tutorial.
- No console, navegue até a Visão geral do Document AI Platform.
- Clique em Criar processador e selecione Form Parser
- Especifique um nome de processador e selecione sua região na lista.
- Clique em Criar para criar seu processador.
- Copie o ID do processador. Você precisará usá-la em seu código mais tarde.
Testar o processador no console do Cloud
É possível fazer upload de um documento para testar o processador no console. Clique em Fazer upload do documento e selecione um formulário para analisar. É possível fazer o download e usar este formulário de exemplo se você não tiver um disponível.
A resposta será parecida com esta:
4. Faça o download do formulário de amostra
Temos um documento de amostra que contém um formulário de admissão médica simples.
Faça o download do PDF usando o link abaixo. Em seguida, faça o upload dele na instância do Cloud Shell.
Como alternativa, é possível fazer o download dele pelo bucket público do Google Cloud Storage usando gsutil
.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/intake-form.pdf .
Confirme se o download do arquivo foi feito no Cloud Shell usando o comando abaixo:
ls -ltr intake-form.pdf
5. Extrair pares de chave-valor de formulários
Nesta etapa, você vai usar a API de processamento on-line para chamar o processador analisador de formulários criado anteriormente. Depois, você vai extrair os pares de chave-valor encontrados no documento.
O processamento on-line serve para enviar um único documento e aguardar a resposta. Também é possível usar o processamento em lote se quiser enviar vários arquivos ou se o tamanho do arquivo exceder o máximo de páginas do processamento on-line. Veja como fazer isso no Codelab de OCR.
O código para fazer uma solicitação de processo é idêntico para todos os tipos de processador, exceto o ID do processador.
O objeto de resposta Document contém uma lista de páginas do documento de entrada.
Cada objeto page
contém uma lista de campos de formulário e os respectivos locais no texto.
O código a seguir itera em cada página e extrai cada chave, valor e pontuação de confiança. São dados estruturados que podem ser armazenados em bancos de dados ou usados em outros aplicativos com mais facilidade.
Crie um arquivo chamado form_parser.py
e use o código abaixo.
form_parser.py
import pandas as pd
from google.cloud import documentai_v1 as documentai
def online_process(
project_id: str,
location: str,
processor_id: str,
file_path: str,
mime_type: str,
) -> documentai.Document:
"""
Processes a document using the Document AI Online Processing API.
"""
opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}
# Instantiates a client
documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)
# 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
resource_name = documentai_client.processor_path(project_id, location, processor_id)
# Read the file into memory
with open(file_path, "rb") as image:
image_content = image.read()
# Load Binary Data into Document AI RawDocument Object
raw_document = documentai.RawDocument(
content=image_content, mime_type=mime_type
)
# Configure the process request
request = documentai.ProcessRequest(
name=resource_name, raw_document=raw_document
)
# Use the Document AI client to process the sample form
result = documentai_client.process_document(request=request)
return result.document
def trim_text(text: str):
"""
Remove extra space characters from text (blank, newline, tab, etc.)
"""
return text.strip().replace("\n", " ")
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION" # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID" # Create processor in Cloud Console
# The local file in your current working directory
FILE_PATH = "intake-form.pdf"
# Refer to https://cloud.google.com/document-ai/docs/processors-list
# for supported file types
MIME_TYPE = "application/pdf"
document = online_process(
project_id=PROJECT_ID,
location=LOCATION,
processor_id=PROCESSOR_ID,
file_path=FILE_PATH,
mime_type=MIME_TYPE,
)
names = []
name_confidence = []
values = []
value_confidence = []
for page in document.pages:
for field in page.form_fields:
# Get the extracted field names
names.append(trim_text(field.field_name.text_anchor.content))
# Confidence - How "sure" the Model is that the text is correct
name_confidence.append(field.field_name.confidence)
values.append(trim_text(field.field_value.text_anchor.content))
value_confidence.append(field.field_value.confidence)
# Create a Pandas Dataframe to print the values in tabular format.
df = pd.DataFrame(
{
"Field Name": names,
"Field Name Confidence": name_confidence,
"Field Value": values,
"Field Value Confidence": value_confidence,
}
)
print(df)
Execute o código agora para ver o texto extraído e impresso no console.
Você vai ver a resposta a seguir se estiver usando o documento de amostra:
$ python3 form_parser.py Field Name Field Name Confidence Field Value Field Value Confidence 0 Phone #: 0.999982 (906) 917-3486 0.999982 1 Emergency Contact: 0.999972 Eva Walker 0.999972 2 Marital Status: 0.999951 Single 0.999951 3 Gender: 0.999933 F 0.999933 4 Occupation: 0.999914 Software Engineer 0.999914 5 Referred By: 0.999862 None 0.999862 6 Date: 0.999858 9/14/19 0.999858 7 DOB: 0.999716 09/04/1986 0.999716 8 Address: 0.999147 24 Barney Lane 0.999147 9 City: 0.997718 Towaco 0.997718 10 Name: 0.997345 Sally Walker 0.997345 11 State: 0.996944 NJ 0.996944 ...
6. Analisar tabelas
O Analisador de formulários também é capaz de extrair dados de tabelas dentro de documentos. Nesta etapa, vamos fazer o download de um novo documento de amostra e extrair dados da tabela. Como estamos carregando os dados no Pandas, eles podem ser enviados para um arquivo CSV e muitos outros formatos com uma única chamada de método.
Faça o download do formulário de amostra com tabelas
Temos um documento de amostra que contém um formulário de amostra e uma tabela.
Faça o download do PDF usando o link abaixo. Em seguida, faça o upload dele na instância do Cloud Shell.
Como alternativa, é possível fazer o download dele pelo bucket público do Google Cloud Storage usando gsutil
.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/form_with_tables.pdf .
Confirme se o download do arquivo foi feito no Cloud Shell usando o comando abaixo:
ls -ltr form_with_tables.pdf
Extrair dados da tabela
A solicitação de processamento de dados de tabela é exatamente igual à extração de pares de chave-valor. A diferença é de quais campos extraímos os dados na resposta. Os dados da tabela são armazenados no campo pages[].tables[]
.
Este exemplo extrai informações sobre as linhas do cabeçalho e do corpo da tabela para cada tabela e página, depois imprime a tabela e salva como um arquivo CSV.
Crie um arquivo chamado table_parsing.py
e use o código abaixo.
table_parsing.py
# type: ignore[1]
"""
Uses Document AI online processing to call a form parser processor
Extracts the tables and data in the document.
"""
from os.path import splitext
from typing import List, Sequence
import pandas as pd
from google.cloud import documentai
def online_process(
project_id: str,
location: str,
processor_id: str,
file_path: str,
mime_type: str,
) -> documentai.Document:
"""
Processes a document using the Document AI Online Processing API.
"""
opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}
# Instantiates a client
documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)
# 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
resource_name = documentai_client.processor_path(project_id, location, processor_id)
# Read the file into memory
with open(file_path, "rb") as image:
image_content = image.read()
# Load Binary Data into Document AI RawDocument Object
raw_document = documentai.RawDocument(
content=image_content, mime_type=mime_type
)
# Configure the process request
request = documentai.ProcessRequest(
name=resource_name, raw_document=raw_document
)
# Use the Document AI client to process the sample form
result = documentai_client.process_document(request=request)
return result.document
def get_table_data(
rows: Sequence[documentai.Document.Page.Table.TableRow], text: str
) -> List[List[str]]:
"""
Get Text data from table rows
"""
all_values: List[List[str]] = []
for row in rows:
current_row_values: List[str] = []
for cell in row.cells:
current_row_values.append(
text_anchor_to_text(cell.layout.text_anchor, text)
)
all_values.append(current_row_values)
return all_values
def text_anchor_to_text(text_anchor: documentai.Document.TextAnchor, text: str) -> str:
"""
Document AI identifies table data by their offsets in the entirety of the
document's text. This function converts offsets to a string.
"""
response = ""
# If a text segment spans several lines, it will
# be stored in different text segments.
for segment in text_anchor.text_segments:
start_index = int(segment.start_index)
end_index = int(segment.end_index)
response += text[start_index:end_index]
return response.strip().replace("\n", " ")
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION" # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID" # Create processor before running sample
# The local file in your current working directory
FILE_PATH = "form_with_tables.pdf"
# Refer to https://cloud.google.com/document-ai/docs/file-types
# for supported file types
MIME_TYPE = "application/pdf"
document = online_process(
project_id=PROJECT_ID,
location=LOCATION,
processor_id=PROCESSOR_ID,
file_path=FILE_PATH,
mime_type=MIME_TYPE,
)
header_row_values: List[List[str]] = []
body_row_values: List[List[str]] = []
# Input Filename without extension
output_file_prefix = splitext(FILE_PATH)[0]
for page in document.pages:
for index, table in enumerate(page.tables):
header_row_values = get_table_data(table.header_rows, document.text)
body_row_values = get_table_data(table.body_rows, document.text)
# Create a Pandas Dataframe to print the values in tabular format.
df = pd.DataFrame(
data=body_row_values,
columns=pd.MultiIndex.from_arrays(header_row_values),
)
print(f"Page {page.page_number} - Table {index}")
print(df)
# Save each table as a CSV file
output_filename = f"{output_file_prefix}_pg{page.page_number}_tb{index}.csv"
df.to_csv(output_filename, index=False)
Execute o código agora para ver o texto extraído e impresso no console.
Você vai ver a resposta a seguir se estiver usando o documento de amostra:
$ python3 table_parsing.py Page 1 - Table 0 Item Description 0 Item 1 Description 1 1 Item 2 Description 2 2 Item 3 Description 3 Page 1 - Table 1 Form Number: 12345678 0 Form Date: 2020/10/01 1 Name: First Last 2 Address: 123 Fake St
Você também precisa ter dois novos arquivos CSV no diretório do qual está executando o código.
$ ls form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py
7. Parabéns
Parabéns! Você usou a API Document AI para extrair dados de um formulário escrito à mão. Incentivamos você a testar outros documentos de formulário.
Limpeza
Para evitar cobranças dos recursos usados neste tutorial na conta do Google Cloud, siga estas etapas:
- No console do Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto e clique em "Excluir".
- Na caixa de diálogo, digite o ID do projeto e clique em "Encerrar" para excluí-lo.
Saiba mais
Saiba mais sobre a Document AI com estes codelabs de acompanhamento.
- Processadores especializados com a Document AI (Python)
- Gerenciamento de processadores da Document AI com Python
- Document AI: human in the loop
Recursos
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.