Анализ формы с помощью Document AI (Python)

1. Введение

В этой лабораторной работе вы узнаете, как использовать анализатор форм AI Document для анализа рукописной формы с помощью Python.

В качестве примера мы будем использовать простую медицинскую форму, но эта процедура будет работать с любой обобщенной формой, поддерживаемой DocAI.

Предварительные условия

Эта лаборатория кода основана на контенте, представленном в других лабораториях Document AI Codelabs.

Прежде чем продолжить, рекомендуется выполнить следующие лабораторные работы по коду.

Что вы узнаете

  • Как анализировать и извлекать данные из отсканированной формы с помощью анализатора форм Document AI.

Что вам понадобится

  • Облачный проект Google
  • Браузер, например Chrome или Firefox.
  • Знание Python 3.

Опрос

Как вы будете использовать этот урок?

Прочтите только до конца Прочитайте его и выполните упражнения.

Как бы вы оценили свой опыт работы с Python?

Новичок Средний Опытный

Как бы вы оценили свой опыт использования сервисов Google Cloud?

Новичок Средний Опытный

2. Настройка и требования

В этой лаборатории кода предполагается, что вы выполнили шаги по настройке Document AI, перечисленные в лаборатории кода Document AI OCR .

Прежде чем продолжить, выполните следующие действия:

Вам также потребуется установить Pandas , библиотеку анализа данных с открытым исходным кодом для Python.

pip3 install --upgrade pandas

3. Создайте обработчик синтаксического анализатора форм.

Сначала необходимо создать экземпляр процессора Form Parser для использования в Document AI Platform для этого руководства.

  1. В консоли перейдите к обзору платформы Document AI Platform.
  2. Нажмите «Создать процессор» и выберите «Парсер форм» . Процессоры
  3. Укажите имя процессора и выберите из списка свой регион.
  4. Нажмите «Создать» , чтобы создать свой процессор.
  5. Скопируйте идентификатор процессора. Вы должны будете использовать это в своем коде позже.

Тестовый процессор в Cloud Console

Вы можете протестировать свой процессор в консоли, загрузив документ. Нажмите «Загрузить документ» и выберите форму для анализа. Вы можете скачать и использовать этот образец формы, если у вас его нет.

Форма здоровья

Ваш вывод должен выглядеть так: Разобранная форма

4. Загрузите образец формы

У нас есть образец документа, который содержит простую форму приема на лечение.

Скачать PDF-файл можно по следующей ссылке. Затем загрузите его в экземпляр Cloud Shell .

Кроме того, вы можете загрузить его из нашей общедоступной корзины облачного хранилища Google с помощью gsutil .

gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/intake-form.pdf .

Подтвердите, что файл загружен в Cloud Shell, используя следующую команду:

ls -ltr intake-form.pdf

5. Извлечение пар ключ/значение формы.

На этом этапе вы будете использовать API онлайн-обработки для вызова созданного ранее процессора синтаксического анализатора форм. Затем вы извлечете пары «ключ-значение», найденные в документе.

Онлайн-обработка предназначена для отправки одного документа и ожидания ответа. Вы также можете использовать пакетную обработку, если хотите отправить несколько файлов или если размер файла превышает максимальное количество страниц онлайн-обработки . О том, как это сделать, можно прочитать в OCR Codelab .

Код для запроса процесса идентичен для каждого типа процессора, за исключением идентификатора процессора.

Объект ответа документа содержит список страниц входного документа.

Каждый объект page содержит список полей формы и их расположение в тексте.

Следующий код перебирает каждую страницу и извлекает каждый ключ, значение и оценку достоверности. Это структурированные данные, которые легче хранить в базах данных или использовать в других приложениях.

Создайте файл form_parser.py и используйте приведенный ниже код.

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)

Запустите свой код сейчас, и вы должны увидеть извлеченный и напечатанный текст в консоли.

Если вы используете наш образец документа, вы должны увидеть следующий результат:

$ 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. Анализ таблиц

Анализатор форм также может извлекать данные из таблиц внутри документов. На этом этапе мы загрузим новый образец документа и извлечем данные из таблицы. Поскольку мы загружаем данные в Pandas, эти данные можно вывести в файл CSV и многие другие форматы с помощью одного вызова метода.

Скачать образец формы с таблицами

У нас есть образец документа, который содержит образец формы и таблицу.

Скачать PDF-файл можно по следующей ссылке. Затем загрузите его в экземпляр Cloud Shell .

Кроме того, вы можете загрузить его из нашей общедоступной корзины облачного хранилища Google с помощью gsutil .

gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/form_with_tables.pdf .

Подтвердите, что файл загружен в Cloud Shell, используя следующую команду:

ls -ltr form_with_tables.pdf

Извлечь данные таблицы

Запрос на обработку табличных данных точно такой же, как и на извлечение пар ключ-значение. Разница в том, из каких полей мы извлекаем данные в ответе. Данные таблицы хранятся в pages[].tables[] .

В этом примере извлекается информация о строках заголовка и строках тела таблицы для каждой таблицы и страницы, затем распечатывается таблица и сохраняется в виде файла CSV.

Создайте файл с именем table_parsing.py и используйте приведенный ниже код.

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)

Запустите свой код сейчас, и вы должны увидеть извлеченный и напечатанный текст в консоли.

Если вы используете наш образец документа, вы должны увидеть следующий результат:

$ 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

У вас также должно быть два новых файла CSV в каталоге, из которого вы запускаете код.

$ ls
form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py

7. Поздравления

Поздравляем, вы успешно использовали API Document AI для извлечения данных из рукописной формы. Мы рекомендуем вам поэкспериментировать с другими формами документов.

Очистить

Чтобы избежать списания средств с вашей учетной записи Google Cloud за ресурсы, используемые в этом руководстве:

  • В Cloud Console перейдите на страницу «Управление ресурсами» .
  • В списке проектов выберите свой проект и нажмите «Удалить».
  • В диалоговом окне введите идентификатор проекта и нажмите «Завершить работу», чтобы удалить проект.

Узнать больше

Продолжайте изучать Document AI на следующих курсах Codelabs.

Ресурсы

Лицензия

Эта работа распространяется под лицензией Creative Commons Attribution 2.0 Generic License.