Tutorial sul rilevamento del testo di documenti ad alta densità

Pubblico

Lo scopo di questo tutorial è aiutarti a sviluppare applicazioni utilizzando la funzionalità di rilevamento del testo nei documenti dell'API Cloud Vision di Google. Presuppone che tu abbia familiarità con i costrutti e le tecniche di programmazione di base, ma anche se sei un programmatore principiante, dovresti essere in grado di seguire ed eseguire questo tutorial senza difficoltà, quindi utilizzare la documentazione di riferimento dell'API Cloud Vision per creare applicazioni di base.

Prerequisiti

Annotare un'immagine utilizzando l'OCR per il testo del documento

Questo tutorial illustra un'applicazione API Vision di base che effettua una DOCUMENT_TEXT_DETECTION richiesta, quindi elabora la fullTextAnnotation risposta.

Un fullTextAnnotation è una risposta gerarchica strutturata per il testo UTF-8 estratto dall'immagine, organizzato come Pagine→Blocchi→Paragrafi→Parole→Simboli:

  • Page è una raccolta di blocchi, oltre a metainformazioni sulla pagina: dimensioni, risoluzioni (la risoluzione X e la risoluzione Y possono differire).

  • Block rappresenta un elemento "logico" della pagina, ad esempio un'area coperta da testo, un'immagine o un separatore tra le colonne. I blocchi di testo e tabella contengono le informazioni principali necessarie per estrarre il testo.

  • Paragraph è un'unità strutturale di testo che rappresenta una sequenza ordinata di parole. Per impostazione predefinita, le parole sono considerate separate da interruzioni di parola.

  • Word è l'unità di testo più piccola. È rappresentato come un array di simboli.

  • Symbol rappresenta un carattere o un segno di punteggiatura.

Il fullTextAnnotation può anche fornire URL a immagini web che corrispondono parzialmente o completamente all'immagine nella richiesta.

Elenco completo dei codici

Durante la lettura del codice, ti consigliamo di fare riferimento alla documentazione di riferimento di Python dell'API Cloud Vision.

import argparse
from enum import Enum

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



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


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

    Args:
        image: the input image object.
        bounds: list of coordinates for the boxes.
        color: the color of the box.

    Returns:
        An image with colored bounds added.
    """
    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):
    """Finds the document bounds given an image and feature type.

    Args:
        image_file: path to the image file.
        feature: feature type to detect.

    Returns:
        List of coordinates for the corresponding feature type.
    """
    client = vision.ImageAnnotatorClient()

    bounds = []

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

    image = vision.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)

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




def render_doc_text(filein, fileout):
    """Outlines document features (blocks, paragraphs and words) given an image.

    Args:
        filein: path to the input image.
        fileout: path to the output image.
    """
    image = Image.open(filein)
    bounds = get_document_bounds(filein, FeatureType.BLOCK)
    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 != 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)

Questa semplice applicazione esegue le seguenti attività:

  • Importa le librerie necessarie per eseguire l'applicazione
  • Accetta tre argomenti e li passa alla funzione main():
    • image_file: il file immagine di input da annotare
    • output_file: il nome del file di output in cui Cloud Vision genererà un'immagine di output con i riquadri disegnati
  • Crea un'istanza ImageAnnotatorClient per interagire con il servizio
  • Invia la richiesta e restituisce una risposta
  • Crea un'immagine di output con riquadri disegnati intorno al testo

Un'occhiata più da vicino al codice

Importazione di librerie

import argparse
from enum import Enum

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

Importiamo le librerie standard:

  • argparse per consentire all'applicazione di accettare i nomi dei file di input come argomenti
  • enum per l'enumerazione FeatureType
  • io per l'I/O dei file

Altre importazioni:

  • La classe ImageAnnotatorClient all'interno della libreria google.cloud.vision per accedere all'API Vision.
  • Il modulo types all'interno della libreria google.cloud.vision per la creazione di richieste.
  • Le librerie Image e ImageDraw della libreria PIL vengono utilizzate per creare l'immagine di output con i riquadri disegnati sull'immagine di input.

Esecuzione dell'applicazione

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)

Qui analizziamo semplicemente gli argomenti passati e li passiamo alla funzione render_doc_text().

Autenticazione nell'API

Prima di comunicare con il servizio API Vision, devi autenticare il tuo servizio utilizzando le credenziali acquisite in precedenza. All'interno di un'applicazione, il modo più semplice per ottenere le credenziali è utilizzare le Credenziali predefinite dell'applicazione (ADC). Per impostazione predefinita, la libreria client Cloud tenterà di ottenere le credenziali dalla variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS, che deve essere impostata in modo da puntare al file della chiave JSON del account di servizio (per maggiori informazioni, consulta Configurazione di un service account).

Effettuare la richiesta API e leggere i limiti del testo dalla risposta

Ora che il nostro servizio API Vision è pronto, possiamo accedervi chiamando il metodo document_text_detection dell'istanza ImageAnnotatorClient.

La libreria client incapsula i dettagli per le richieste e le risposte all'API. Consulta la documentazione di riferimento per l'API Vision per informazioni complete sulla struttura di una richiesta.

def get_document_bounds(image_file, feature):
    """Finds the document bounds given an image and feature type.

    Args:
        image_file: path to the image file.
        feature: feature type to detect.

    Returns:
        List of coordinates for the corresponding feature type.
    """
    client = vision.ImageAnnotatorClient()

    bounds = []

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

    image = vision.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)

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

Dopo che la libreria client ha gestito la richiesta, la nostra risposta conterrà un AnnotateImageResponse, che consiste in un elenco di risultati di annotazione delle immagini, uno per ogni immagine inviata nella richiesta. Poiché nella richiesta abbiamo inviato una sola immagine, esaminiamo l'intera TextAnnotation e raccogliamo i limiti della funzionalità del documento specificata.

Esecuzione dell'applicazione

Per eseguire l'applicazione, puoi scaricare questo file receipt.jpg (potresti dover fare clic con il tasto destro del mouse sul link), quindi passare la posizione in cui hai scaricato il file sulla tua macchina locale all'applicazione del tutorial (doctext.py).

Di seguito è riportato il comando Python, seguito dalle immagini di output dell'annotazione di testo.

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

La seguente immagine mostra le parole in riquadri gialli e le frasi in rosso.

Complimenti! Hai eseguito il rilevamento del testo utilizzando le annotazioni di testo completo di Google Cloud Vision.