Reconocimiento óptico de caracteres (OCR) con Document AI y Python

1. Resumen

Introducción al lab

¿Qué es Document AI?

Document AI es una solución de comprensión de documentos que toma datos no estructurados (p.ej., documentos, correos electrónicos, facturas, formularios, etc.) y facilita su comprensión, análisis y consumo. La API proporciona una estructura mediante la clasificación de contenido, la extracción de entidades, la búsqueda avanzada y mucho más.

En este lab, aprenderá a realizar el reconocimiento óptico de caracteres con la API de Document AI con Python.

Utilizaremos un archivo PDF de la novela clásica "Winnie the Pooh" de AA Milne, que recientemente forma parte del dominio público en Estados Unidos. Google Libros escaneó y digitalizó este archivo.

Qué aprenderá

  • Cómo habilitar la API de Document AI
  • Cómo autenticar solicitudes a la API
  • Cómo instalar la biblioteca cliente de Python
  • Cómo analizar texto de un archivo PDF
  • Cómo realizar solicitudes asíncronas con Google Cloud Storage

Requisitos

  • Un proyecto de Google Cloud
  • Un navegador, como Chrome o Firefox
  • Estar familiarizado con Python (3.7 o superior)

Encuesta

¿Cómo usarás este instructivo?

Leer Leer y completar los ejercicios

¿Cómo calificarías tu experiencia con Python?

Principiante Intermedio Avanzado

¿Cómo calificarías tu experiencia con los servicios de Google Cloud?

Principiante Intermedio Avanzado

2. Configuración y requisitos

cae48e4b2e19921d.png

En el diálogo siguiente, haz clic en el botón "Aceptar y continuar" para aceptar las Condiciones del Servicio:

27d87930a0daf2f8.png

Después de aceptar las condiciones del servicio, se te redireccionará a una página de resumen de facturación que incluye un panel como el que se muestra cerca de la esquina inferior derecha:

2076ea7aa9bf3f65.png

Por último, cuando crees tu primer proyecto, verás un cuadro de diálogo que te permitirá asignar una cuenta de facturación a tu proyecto. Selecciona la cuenta de facturación asociada con tus créditos gratuitos y haz clic en el botón de crear:

dd3b0e795843296.png

En resumen, ahora tienes una cuenta de facturación y un proyecto, y ambas entidades están vinculadas, de modo que cualquier trabajo que realices en el codelab de hoy se financiará con tus créditos gratuitos**.**

Configuración del entorno a su propio ritmo

  1. Accede a Cloud Console y crea un proyecto nuevo o reutiliza uno existente. (Si aún no tienes una cuenta de Gmail o Google Workspace, debes crear una).

Seleccionar proyecto

Nuevo proyecto

Obtén el ID del proyecto

Recuerde el ID del proyecto, un nombre único en todos los proyectos de Google Cloud. (El ID del proyecto anterior ya está en uso y no funcionará en tu nombre, lo sentimos). Debes proporcionar este ID más adelante como PROJECT_ID.

  1. Luego, debes habilitar la facturación en Cloud Console para usar los recursos de Google Cloud.

Asegúrate de seguir las instrucciones de la sección “Limpieza”. En la sección, se aconseja cómo cerrar recursos para que no se te facture más allá de este instructivo. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $300.

Iniciar Cloud Shell

Si bien Google Cloud puede operar Google Cloud de forma remota desde tu laptop, este codelab usa Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

Active Cloud Shell

  1. En Cloud Console, haga clic en Activar Cloud Shell Active Cloud Shell.

Active Cloud Shell

Si nunca has iniciado Cloud Shell, se mostrará una pantalla intermedia (mitad inferior) que describe qué es. Si ese es el caso, haz clic en Continuar (y no volverás a verlo). Así es como se ve la pantalla única:

Introducción a Cloud Shell

El aprovisionamiento y la conexión a Cloud Shell debería llevar solo unos minutos. Cloud Shell

Cloud Shell te brinda acceso de terminal a una máquina virtual alojada en la nube. La máquina virtual incluye todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Mucho de tu trabajo, en este codelab, se puede hacer con un solo navegador.

Una vez conectado a Cloud Shell, deberías ver que ya estás autenticado y que el proyecto ya tiene asignado el ID.

  1. En Cloud Shell, ejecute el siguiente comando para confirmar que está autenticado:
gcloud auth list

Resultado del comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*      <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

De lo contrario, puede configurarlo con este comando:

gcloud config set project <PROJECT_ID>

Resultado del comando

Updated property [core/project].

3. Habilita la API de Document AI

Antes de comenzar a usar Document AI, debes habilitar la API. Abre Cloud Console en tu navegador.

  1. Use la barra de búsqueda en la parte superior de Console, busque "Document AI API" y, luego, haga clic en Enable para usar la API en su proyecto de Google Cloud.

API de Búsqueda

  1. Como alternativa, la API se puede habilitar mediante el siguiente comando gcloud.
gcloud services enable documentai.googleapis.com

Debería ver algo como esto:

Operation "operations/..." finished successfully.

Ahora puedes usar Document AI.

4. Crea y prueba un procesador

Primero, debe crear una instancia del procesador OCR de documentos que realizará la extracción. Esto se puede completar mediante Cloud Console o la API de Processor Management.

Cloud Console

  1. En Console, navega a Descripción general de la plataforma de Document AI
  2. Haga clic en Create Processor y seleccione Document OCR.Procesadores
  3. Especifica el nombre del procesador y selecciona tu región en la lista.
  4. Haz clic en Crear para crear el procesador.
  5. Copie su ID de procesador. Debes usarla en tu código más adelante. ID del procesador

Para probar el procesador en la consola, sube un documento. Haz clic en Subir documento de prueba y selecciona un documento para analizar.

Puedes descargar el archivo PDF a continuación, que contiene las primeras 3 páginas de nuestra novela.

Página de título

El resultado debería ser el siguiente: Libro analizado

Biblioteca cliente de Python

Sigue este codelab para aprender a administrar procesadores de Document AI con la biblioteca cliente de Python:

Codelab: Cómo administrar procesadores de Document AI con Python

5. Autenticar solicitudes a la API

Para realizar solicitudes a la API de Document AI, debes usar una cuenta de servicio. Una cuenta de servicio pertenece a tu proyecto y la biblioteca cliente de Python la usa para realizar solicitudes a la API. Al igual que cualquier otra cuenta de usuario, una cuenta de servicio está representada por una dirección de correo electrónico. En esta sección, usará el SDK de Cloud a fin de crear una cuenta de servicio y, luego, crear las credenciales que necesita para autenticarse como la cuenta de servicio.

Primero, configura una variable de entorno con tu PROJECT_ID, que usarás en este codelab:

export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)

A continuación, crea una cuenta de servicio nueva para acceder a la API de Document AI mediante el siguiente comando:

gcloud iam service-accounts create my-docai-sa \
  --display-name "my-docai-service-account"

A continuación, crea las credenciales que tu código de Python usa para acceder como tu cuenta de servicio nueva. Crea estas credenciales y guárdalas como un archivo JSON “~/key.json” mediante el siguiente comando:

gcloud iam service-accounts keys create ~/key.json \
  --iam-account  my-docai-sa@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Por último, configura la variable de entorno GOOGLE_APPLICATION_CREDENTIALS, que se usa en la biblioteca para encontrar tus credenciales. Para obtener más información sobre la autenticación de este formulario, consulta la guía. La variable de entorno debe establecerse para la ruta completa del archivo JSON de credenciales que creó. Para ello, use lo siguiente:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"

6. Instala la biblioteca cliente

Instala las bibliotecas cliente:

pip3 install --upgrade google-cloud-documentai
pip3 install --upgrade google-cloud-storage

Debería ver algo como esto:

...
Installing collected packages: google-cloud-documentai
Successfully installed google-cloud-documentai-1.2.0
.
.
Installing collected packages: google-cloud-storage
Successfully installed google-cloud-storage-1.43.0

Ya está lista para usar la API de Document AI.

Iniciar Python interactivo

En este instructivo, usarás un intérprete de Python interactivo llamado IPython. Inicia una sesión mediante la ejecución de ipython en Cloud Shell. Este comando ejecuta el intérprete de Python en una sesión interactiva.

ipython

Debería ver algo como esto:

Python 3.7.3 (default, Jul 25 2020, 13:03:44)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.30.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

7. Descargar el PDF de muestra

Tenemos un documento de muestra que contiene las primeras 3 páginas de la novela.

Puedes descargar el PDF mediante el siguiente vínculo. Luego, súbala a la instancia de Cloud Shell.

También puedes descargarlo desde nuestro bucket público de Google Cloud Storage con gsutil.

gsutil cp gs://cloud-samples-data/documentai/codelabs/ocr/Winnie_the_Pooh_3_Pages.pdf .

8. Realiza una solicitud de documento de proceso síncrono

En este paso, procesarás las primeras 3 páginas de la novela con el extremo síncrono. Este método es más adecuado para documentos pequeños que se almacenan localmente. Consulta la lista completa de procesadores para conocer las páginas máximas y el tamaño de cada tipo de procesador.

Copie el siguiente código en su sesión de iPython:

from google.cloud import documentai_v1 as documentai

def process_document(project_id: str, location: str,
                     processor_id: str, file_path: str,
                     mime_type: str) -> documentai.Document:
    """
    Processes a document using the Document AI API.
    """

    # Instantiates a client
    documentai_client = documentai.DocumentProcessorServiceClient()

    # 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 main():
    """
    Run the codelab.
    """
    project_id = 'YOUR_PROJECT_ID'
    location = 'YOUR_PROJECT_LOCATION'  # Format is 'us' or 'eu'
    processor_id = 'YOUR_PROCESSOR_ID'  # Create processor in Cloud Console

    file_path = 'Winnie_the_Pooh_3_Pages.pdf'  # The local file in your current working directory
    # Refer to https://cloud.google.com/document-ai/docs/processors-list for the supported file types
    mime_type = 'application/pdf'

    document = process_document(project_id=project_id, location=location,
                                processor_id=processor_id, file_path=file_path,
                                mime_type=mime_type)

    print("Document processing complete.")
    print(f"Text: {document.text}")

Llama a la función principal. Deberías ver el texto extraído e impreso en tu consola.

main()

Deberías ver el siguiente resultado si usas nuestro documento de muestra:

Document processing complete.
Text: CHAPTER I
IN WHICH We Are Introduced to
Winnie-the-Pooh and Some
Bees, and the Stories Begin
Here is Edward Bear, coming
downstairs now, bump, bump, bump, on the back
of his head, behind Christopher Robin. It is, as far
as he knows, the only way of coming downstairs,
but sometimes he feels that there really is another
way, if only he could stop bumping for a moment
and think of it. And then he feels that perhaps there
isn't. Anyhow, here he is at the bottom, and ready
to be introduced to you. Winnie-the-Pooh.
When I first heard his name, I said, just as you
are going to say, "But I thought he was a boy?"
"So did I," said Christopher Robin.
"Then you can't call him Winnie?"
"I don't."
"But you said "

...

Digitized by
Google

9. Realiza una solicitud de documento de proceso asíncrono

Ahora, supongamos que quieres leer el texto de toda la novela.

  • El método process_documents() tiene límites respecto de la cantidad de páginas y tamaños de archivo que se pueden enviar y solo permite un archivo de documento por llamada a la API.
  • El método batch_process_documents() permite el procesamiento asíncrono de archivos más grandes y el procesamiento por lotes de varios archivos.

En este paso, procesaremos la novela “Winnie the Pooh” con la API asíncrona de Document AI y enviaremos el texto a un bucket de Google Cloud Storage.

Sube un PDF a Cloud Storage

Actualmente, el método batch_process_documents() acepta archivos de Google Cloud Storage. Puedes consultar documentai_v1.types.BatchProcessRequest para obtener más información sobre la estructura del objeto.

En este ejemplo, puede copiar el archivo desde nuestro bucket de datos de muestra.

gsutil cp gs://cloud-samples-data/documentai/codelabs/ocr/Winnie_the_Pooh.pdf gs://YOUR_BUCKET_NAME/

O bien, puedes descargar el archivo de muestra de la novela desde el siguiente vínculo y subirlo a tu propio bucket.

También necesitará un bucket de GCS para almacenar el resultado de la API.

Usa el método batch_process_documents()

Copie el siguiente código en su sesión de iPython:

import re

from google.api_core.operation import Operation
from google.cloud import documentai_v1 as documentai
from google.cloud import storage

def batch_process_documents(
    project_id: str,
    location: str,
    processor_id: str,
    gcs_input_uri: str,
    input_mime_type: str,
    gcs_output_uri: str,
) -> Operation:
    """
    Constructs a request to process a document using the Document AI
    Asynchronous API.
    """
    # You must set the api_endpoint if you use a location other than 'us', e.g.:
    opts = {}
    if location == "eu":
        opts = {"api_endpoint": "eu-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)

    # Cloud Storage URI for the Input Document
    input_document = documentai.GcsDocument(
        gcs_uri=gcs_input_uri, mime_type=input_mime_type
    )

    # Load GCS Input URI into a List of document files
    input_config = documentai.BatchDocumentsInputConfig(
        gcs_documents=documentai.GcsDocuments(documents=[input_document])
    )

    # Cloud Storage URI for Output directory
    gcs_output_config = documentai.DocumentOutputConfig.GcsOutputConfig(
        gcs_uri=gcs_output_uri
    )

    # Load GCS Output URI into OutputConfig object
    output_config = documentai.DocumentOutputConfig(gcs_output_config=gcs_output_config)

    # Configure Process Request
    request = documentai.BatchProcessRequest(
        name=resource_name,
        input_documents=input_config,
        document_output_config=output_config,
    )

    # Future for long-running operations returned from Google Cloud APIs.
    operation = documentai_client.batch_process_documents(request)

    return operation

def get_documents_from_gcs(
    gcs_output_uri: str, operation_name: str
) -> [documentai.Document]:
    """
    Download the document output from GCS.
    """

    # The GCS API requires the bucket name and URI prefix separately
    match = re.match(r"gs://([^/]+)/(.+)", gcs_output_uri)
    output_bucket = match.group(1)
    prefix = match.group(2)

    # The output files will be in a new subdirectory with the Operation ID as the name
    operation_id = re.search("operations\/(\d+)", operation_name, re.IGNORECASE).group(1)

    output_directory = f"{prefix}/{operation_id}"

    storage_client = storage.Client()

    # List of all of the files in the directory `gs://gcs_output_uri/operation_id`
    blob_list = list(storage_client.list_blobs(output_bucket, prefix=output_directory))

    output_documents = []

    for blob in blob_list:
        # Document AI should only output JSON files to GCS
        if ".json" in blob.name:
            document = documentai.types.Document.from_json(blob.download_as_bytes())
            output_documents.append(document)
        else:
            print(f"Skipping non-supported file type {blob.name}")

    return output_documents

def main():
    """
    Run the codelab.
    """

    project_id = 'YOUR_PROJECT_ID'
    location = 'YOUR_PROJECT_LOCATION'  # Format is 'us' or 'eu'
    processor_id = 'YOUR_PROCESSOR_ID'  # Create processor in Cloud Console

    # Format 'gs://input_bucket/directory/file.pdf'
    gcs_input_uri = "INPUT_BUCKET_URI"
    input_mime_type = "application/pdf"

    # Format 'gs://output_bucket/directory'
    gcs_output_uri = "YOUR_OUTPUT_BUCKET_URI"

    # Batch Process returns a Long Running Operation (LRO)
    operation = batch_process_documents(
        project_id=project_id,
        location=location,
        processor_id=processor_id,
        gcs_input_uri=gcs_input_uri,
        input_mime_type=input_mime_type,
        gcs_output_uri=gcs_output_uri,
    )

    # Format: projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID
    operation_name = operation.operation.name

    # Continually polls the operation until it is complete.
    # This could take some time for larger files
    print(f"Waiting for operation {operation_name} to complete...")
    result = operation.result(timeout=300)

    # NOTE: Can also use callbacks for asynchronous processing
    #
    # def my_callback(future):
    #   result = future.result()
    #
    # operation.add_done_callback(my_callback)

    print("Document processing complete.")

    # Get the Document Objects from the Output Bucket
    document_list = get_documents_from_gcs(
        gcs_output_uri=gcs_output_uri, operation_name=operation_name
    )

    for document in document_list:
        print(document.text)

Llama a la función principal. Deberías ver el texto completo de la novela impreso en tu consola.

main()

Este proceso puede tardar un poco en completarse, ya que el archivo es mucho más grande que el ejemplo anterior. (Oh, molesta...)

Sin embargo, con la API asíncrona, recibirá un ID de operación que se puede usar para obtener el resultado de GCS una vez que se complete la tarea.

This is a reproduction of a library book that was digitized
by Google as part of an ongoing effort to preserve the
information in books and make it universally accessible.
TM
Google books
https://books.google.com

.....

He nodded and went
out ... and in a moment
I heard Winnie-the-Pooh
-bump, bump, bump-go-ing up the stairs behind
him.
Digitized by
Google

10. Felicitaciones

Usó correctamente Document AI para extraer texto de una novela con las API síncronas y asíncronas.

Te recomendamos que experimentes con otros documentos y explores los otros procesadores disponibles en la plataforma.

Limpieza

Para evitar que se generen costos en tu cuenta de Google Cloud por los recursos que se usaron en este instructivo, sigue estos pasos:

  • En Cloud Console, ve a la página Administrar recursos.
  • En la lista de proyectos, selecciona tu proyecto y haz clic en Borrar.
  • En el cuadro de diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Más información

Licencia

Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.