Tutorial sobre detecção de texto de documentos

Público

Nossa meta neste tutorial é ajudá-lo a desenvolver aplicativos usando a detecção de texto do documento da API Google Cloud Vision. Pressupomos que você tenha familiaridade com construtos e técnicas básicas de programação. No entanto, mesmo que seja um programador iniciante, você pode acompanhar e executar o tutorial sem dificuldade, além de usar a documentação de referência da API Cloud Vision para criar aplicativos básicos.

Pré-requisitos

Como anotar uma imagem usando o OCR de texto de documento

Veja, neste tutorial, um aplicativo básico da API Vision que faz uma solicitação DOCUMENT_TEXT_DETECTION e processa a resposta fullTextAnnotation.

fullTextAnnotation é uma resposta hierárquica estruturada do texto extraído da imagem. Ele é organizado como Pages (páginas) → Blocks (blocos) → Paragraphs (parágrafos) → Words (palavras) → Symbols (símbolos):

  • Page é um conjunto de blocos, além de metainformações sobre a página: tamanhos, resoluções (a X e a Y podem ser diferentes) etc.

  • Block representa um elemento "lógico" da página. Por exemplo, uma área coberta por texto, uma imagem ou um separador entre colunas. Os blocos de texto e tabela contêm as principais informações necessárias para extrair o texto.

  • Paragraph é uma unidade estrutural de texto que representa uma sequência ordenada de palavras. Por padrão, as palavras são separadas por quebras.

  • Word é a menor unidade do texto. Ela é representada como um conjunto de símbolos.

  • Symbol representa um caractere ou um sinal de pontuação.

fullTextAnnotation também fornece URLs para imagens da Web que correspondem em parte ou totalmente à imagem na solicitação.

Listagem de código completa

Durante a leitura do código, recomendamos que você consulte a referência da Cloud Vision API para Python.

import argparse
from enum import Enum
import io

from google.cloud import vision
from google.cloud.vision import types
from PIL import Image, ImageDraw

class FeatureType(Enum):
    PAGE = 1
    BLOCK = 2
    PARA = 3
    WORD = 4
    SYMBOL = 5

def draw_boxes(image, bounds, color):
    """Draw a border around the image using the hints in the vector list."""
    draw = ImageDraw.Draw(image)

    for bound in bounds:
        draw.polygon([
            bound.vertices[0].x, bound.vertices[0].y,
            bound.vertices[1].x, bound.vertices[1].y,
            bound.vertices[2].x, bound.vertices[2].y,
            bound.vertices[3].x, bound.vertices[3].y], None, color)
    return image

def get_document_bounds(image_file, feature):
    """Returns document bounds given an image."""
    client = vision.ImageAnnotatorClient()

    bounds = []

    with io.open(image_file, 'rb') as image_file:
        content = image_file.read()

    image = types.Image(content=content)

    response = client.document_text_detection(image=image)
    document = response.full_text_annotation

    # Collect specified feature bounds by enumerating all document features
    for page in document.pages:
        for block in page.blocks:
            for paragraph in block.paragraphs:
                for word in paragraph.words:
                    for symbol in word.symbols:
                        if (feature == FeatureType.SYMBOL):
                            bounds.append(symbol.bounding_box)

                    if (feature == FeatureType.WORD):
                        bounds.append(word.bounding_box)

                if (feature == FeatureType.PARA):
                    bounds.append(paragraph.bounding_box)

            if (feature == FeatureType.BLOCK):
                bounds.append(block.bounding_box)

        if (feature == FeatureType.PAGE):
            bounds.append(block.bounding_box)

    # The list `bounds` contains the coordinates of the bounding boxes.
    return bounds

def render_doc_text(filein, fileout):
    image = Image.open(filein)
    bounds = get_document_bounds(filein, FeatureType.PAGE)
    draw_boxes(image, bounds, 'blue')
    bounds = get_document_bounds(filein, FeatureType.PARA)
    draw_boxes(image, bounds, 'red')
    bounds = get_document_bounds(filein, FeatureType.WORD)
    draw_boxes(image, bounds, 'yellow')

    if fileout is not 0:
        image.save(fileout)
    else:
        image.show()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('detect_file', help='The image for text detection.')
    parser.add_argument('-out_file', help='Optional output file', default=0)
    args = parser.parse_args()

    render_doc_text(args.detect_file, args.out_file)

Esse aplicativo simples executa as seguintes tarefas:

  • Importa as bibliotecas necessárias para executar o aplicativo.
  • Transmite três argumentos para a função main():
    • image_file: o arquivo de imagem de entrada a ser anotado.
    • output_file: o nome do arquivo de saída em que a Cloud Vision produzirá uma imagem de saída com várias caixas desenhadas.
  • Cria uma instância ImageAnnotatorClient para interagir com o serviço.
  • Envia a solicitação e retorna uma resposta.
  • Cria uma imagem de saída com caixas desenhadas em torno do texto.

Mais detalhes sobre o código

Como importar bibliotecas

import argparse
from enum import Enum
import io

from google.cloud import vision
from google.cloud.vision import types
from PIL import Image, ImageDraw

Importamos bibliotecas padrão:

  • argparse para que o aplicativo aceite nomes de arquivo de entrada como argumentos
  • enum para a enumeração de FeatureType
  • io para E/S do arquivo

Outras importações:

  • A classe ImageAnnotatorClient na biblioteca google.cloud.vision para acessar a API Vision.
  • O módulo types na biblioteca google.cloud.vision para criar solicitações.
  • As bibliotecas Image e ImageDraw da PIL são usadas para criar a imagem de saída com caixas desenhadas na imagem de entrada.

Como executar o aplicativo

parser = argparse.ArgumentParser()
parser.add_argument('detect_file', help='The image for text detection.')
parser.add_argument('-out_file', help='Optional output file', default=0)
args = parser.parse_args()

render_doc_text(args.detect_file, args.out_file)

Aqui, simplesmente analisamos os argumentos transmitidos e encaminhamos para a função render_doc_text().

Como autenticar na API

Antes de se comunicar com a API do Vision, você precisa autenticar seu serviço usando as credenciais já adquiridas. A maneira mais simples de receber credenciais em um aplicativo é usar o Application Default Credentials (ADC). Por padrão, a biblioteca de cliente do Cloud tentará receber as credenciais da variável de ambiente GOOGLE_APPLICATION_CREDENTIALS. Ela precisa ser configurada para indicar o arquivo de chave JSON da conta de serviço. Para mais informações, consulte Como configurar uma conta de serviço.

Como fazer a solicitação da API e ler limites de texto da resposta

Agora que o serviço da Vision API está pronto, podemos acessá-lo chamando o método document_text_detection da instância ImageAnnotatorClient.

A biblioteca de cliente inclui os detalhes das solicitações e respostas para a API. Consulte a Referência da Vision API para saber informações sobre a estrutura de uma solicitação.

"""Returns document bounds given an image."""
client = vision.ImageAnnotatorClient()

bounds = []

with io.open(image_file, 'rb') as image_file:
    content = image_file.read()

image = types.Image(content=content)

response = client.document_text_detection(image=image)
document = response.full_text_annotation

# Collect specified feature bounds by enumerating all document features
for page in document.pages:
    for block in page.blocks:
        for paragraph in block.paragraphs:
            for word in paragraph.words:
                for symbol in word.symbols:
                    if (feature == FeatureType.SYMBOL):
                        bounds.append(symbol.bounding_box)

                if (feature == FeatureType.WORD):
                    bounds.append(word.bounding_box)

            if (feature == FeatureType.PARA):
                bounds.append(paragraph.bounding_box)

        if (feature == FeatureType.BLOCK):
            bounds.append(block.bounding_box)

    if (feature == FeatureType.PAGE):
        bounds.append(block.bounding_box)

# The list `bounds` contains the coordinates of the bounding boxes.

Depois que a solicitação tiver sido processada pela biblioteca de cliente, a resposta conterá um AnnotateImageResponse para cada imagem enviada. Ele consiste em uma lista de resultados das "Anotações de imagem". Como enviamos apenas uma imagem na solicitação, verificamos todo o TextAnnotation e coletamos os limites para o recurso do documento especificado.

Como executar o aplicativo

Para executar o aplicativo, faça o download do arquivo receipt.jpg. Talvez seja necessário clicar com o botão direito do mouse no link e depois adicionar, ao aplicativo do tutorial (doctext.py), o local em que você fez o download do arquivo na sua máquina local.

Este é o comando do Python, seguido das imagens de saída da anotação de texto.

$ python doctext.py receipt.jpg -out_file out.jpg

A imagem a seguir mostra palavras em caixas amarelas e frases em vermelhas.

Parabéns! Você fez a detecção de texto usando as anotações de texto completo do Google Cloud Vision.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação da API Cloud Vision
Precisa de ajuda? Acesse nossa página de suporte.