Document AI 및 Python을 사용한 광학 문자 인식 (OCR)

1. 개요

실습 소개

Document AI란 무엇인가요?

Document AI는 구조화되지 않은 데이터 (예: 문서, 이메일, 인보이스, 양식 등)를 사용하고 데이터를 더 쉽게 이해, 분석, 소비할 수 있는 문서 이해 솔루션입니다. API는 콘텐츠 분류, 항목 추출, 고급검색 등을 통해 구조를 제공합니다.

이 실습에서는 Python에서 Document AI API를 사용하여 광학 문자 인식을 수행하는 방법을 알아봅니다.

AA Milne의 고전 소설 'Winnie the Pooh'의 PDF 파일을 사용합니다. 이 파일은 최근 미국 내 공개 도메인에 등록되었습니다. 이 파일은 Google 도서에서 스캔하고 디지털화했습니다.

과정 내용

  • Document AI API를 사용 설정하는 방법
  • API 요청 인증 방법
  • Python용 클라이언트 라이브러리 설치 방법
  • PDF 파일에서 텍스트를 파싱하는 방법
  • Google Cloud Storage를 사용하여 비동기 요청을 수행하는 방법

필요한 항목

  • Google Cloud 프로젝트
  • 브라우저(Chrome, Firefox 등)
  • Python을 사용한 관련 지식 (3.7 이상)

설문조사

본 가이드를 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다. 읽은 다음 연습 활동을 완료할 계획입니다.

귀하의 Python 사용 경험이 어떤지 평가해 주세요.

초급 중급 고급

귀하의 Google Cloud 서비스 사용 경험을 평가해 주세요.

초급 중급 고급

2 설정 및 요구사항

cae48e4b2e19921d.png

다음 대화상자에서 '동의 및 계속' 버튼을 클릭하여 서비스 약관에 동의합니다.

27d87930a0daf2f8.png

서비스 약관에 동의하면 오른쪽 하단에 다음과 같은 패널이 포함된 결제 요약 페이지로 리디렉션됩니다.

2076ea7aa9bf3f65.png

마지막으로 첫 번째 프로젝트를 만들 때 프로젝트에 결제 계정을 할당할 수 있는 대화상자가 표시됩니다. 무료 크레딧과 연결된 결제 계정을 선택하고 만들기 버튼을 클릭합니다.

dd3b0e795843296.png

요약하자면, 이제 결제 계정과 프로젝트가 있고 이 두 항목은 연결되어 있어 오늘날의 Codelab에서 여러분이 하는 모든 작업이 무료 크레딧으로부터 지원받을 수 있습니다**.**

자습형 환경 설정

  1. Cloud Console에 로그인하고 새 프로젝트를 만들거나 기존 프로젝트를 다시 사용합니다. (아직 Gmail 또는 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.)

프로젝트 선택

새 프로젝트

프로젝트 ID 가져오기

모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요. (위의 프로젝트 ID는 이미 사용되었으며 작동하지 않습니다.) 나중에 PROJECT_ID ID를 제공해야 합니다.

  1. 다음으로 Google Cloud 리소스를 사용하려면 Cloud Console에서 결제를 사용 설정해야 합니다.

'삭제' 섹션의 안내를 따르세요. 이 섹션에서는 이 가이드를 마친 후 비용이 결제되지 않도록 리소스를 종료하는 방법을 알려줍니다 Google Cloud 새 사용자에게는 $300USD 상당의 무료 평가판 프로그램 참여 자격이 부여됩니다.

Cloud Shell 시작

노트북에서 원격으로 Google Cloud를 작동할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Cloud Shell 활성화

  1. Cloud Console에서 Cloud Shell 활성화 를 클릭합니다.Cloud Shell 활성화

Cloud Shell 활성화

이전에 Cloud Shell을 시작하지 않았으면 설명이 포함된 중간 화면(스크롤해야 볼 수 있는 부분)이 제공됩니다. 이 경우 계속을 클릭합니다(이후 다시 표시되지 않음). 이 일회성 화면은 다음과 같습니다.

Cloud Shell 소개

Cloud Shell을 프로비저닝하고 연결하는 데 몇 분밖에 걸리지 않습니다. Cloud Shell걸음

Cloud Shell을 사용하면 클라우드에 호스팅되는 가상 머신에 대한 터미널 액세스를 제공할 수 있습니다. 가상 머신에 필요한 모든 개발 도구가 포함됩니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 전부는 아니지만 이 Codelab의 모든 작업을 브라우저만으로 할 수 있는 것은 아닙니다.

Cloud Shell에 연결되면 인증이 이미 완료되어 있고 프로젝트가 이미 프로젝트 ID로 설정되어 있음을 확인할 수 있습니다.

  1. Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list

명령어 결과

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

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

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

3. Document AI API 사용 설정

Document AI를 사용하려면 먼저 API를 사용 설정해야 합니다. 브라우저에서 Cloud Console을 엽니다.

  1. 콘솔 상단의 검색창에서 'Document AI API'를 검색한 다음 사용 설정을 클릭하여 Google Cloud 프로젝트에서 API를 사용합니다.

Search API

  1. 또는 다음 gcloud 명령어를 사용하여 API를 사용 설정할 수 있습니다.
gcloud services enable documentai.googleapis.com

다음과 같이 표시됩니다.

Operation "operations/..." finished successfully.

이제 Document AI를 사용할 수 있습니다.

4. 프로세서 만들기 및 테스트

먼저, 추출을 실행할 문서 OCR 프로세서 인스턴스를 만들어야 합니다. Cloud Console 또는 프로세서 관리 API를 사용하여 완료할 수 있습니다.

Cloud Console

  1. 콘솔에서 Document AI Platform 개요로 이동합니다.
  2. Create Processor(프로세서 만들기)를 클릭하고 Document OCR(문서 OCR)을 선택합니다.프로세서
  3. 프로세서 이름을 지정하고 목록에서 리전을 선택합니다.
  4. 만들기를 클릭하여 프로세서를 만듭니다.
  5. 프로세서 ID를 복사합니다. 나중에 코드에서 이 변수를 사용해야 합니다. 프로세서 ID걸음

문서를 업로드하여 콘솔에서 프로세서를 테스트할 수 있습니다. 테스트 문서 업로드를 클릭하고 파싱할 문서를 선택합니다.

소설의 처음 3페이지가 포함된 PDF 파일을 아래에서 다운로드할 수 있습니다.

제목 페이지

다음과 같이 출력됩니다. 파싱된 책

Python 클라이언트 라이브러리

이 Codelab에 따라 Python 클라이언트 라이브러리로 Document AI 프로세서를 관리하는 방법을 알아보세요.

Python으로 Document AI 프로세서 관리 - Codelab

5 API 요청 인증

Document AI API에 요청하려면 서비스 계정을 사용해야 합니다. 서비스 계정은 프로젝트에 속하며 Python 클라이언트 라이브러리에서 API 요청을 수행하는 데 사용됩니다. 다른 사용자 계정과 마찬가지로 서비스 계정은 이메일 주소로 표시됩니다. 이 섹션에서는 Cloud SDK를 사용하여 서비스 계정을 만든 다음 서비스 계정으로 인증해야 하는 사용자 인증 정보를 만듭니다.

먼저 이 Codelab 전체에서 사용할 PROJECT_ID로 환경 변수를 설정합니다.

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

그런 후, 다음을 사용하여 Document AI API에 액세스할 새 서비스 계정을 만듭니다.

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

다음으로, Python 코드가 새 서비스 계정으로 로그인할 때 사용하는 사용자 인증 정보를 만듭니다. 이러한 사용자 인증 정보를 만들고, 다음 명령어를 사용하여 JSON 파일 '~/key.json'으로 저장합니다.

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

마지막으로 라이브러리에서 사용자 인증 정보를 찾는 데 사용하는 GOOGLE_APPLICATION_CREDENTIALS 환경 변수를 설정합니다. 이 양식 인증에 관한 자세한 내용은 가이드를 참고하세요. 환경 변수는 다음을 사용하여 만든 사용자 인증 정보 JSON 파일의 전체 경로로 설정해야 합니다.

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

6. 클라이언트 라이브러리 설치

클라이언트 라이브러리를 설치합니다.

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

다음과 같이 표시됩니다.

...
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

이제 Document AI API를 사용할 준비가 되었습니다.

양방향 Python 시작

이 튜토리얼에서는 IPython이라는 대화형 Python 인터프리터를 사용합니다. Cloud Shell에서 ipython를 실행하여 세션을 시작합니다. 이 명령어는 대화형 세션에서 Python 인터프리터를 실행합니다.

ipython

다음과 같은 결과를 확인할 수 있습니다.

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 샘플 PDF 다운로드

소설의 처음 3페이지가 포함된 샘플 문서가 있습니다.

다음 링크를 사용하여 PDF를 다운로드할 수 있습니다. 그런 다음 Cloud Shell 인스턴스에 업로드합니다.

gsutil를 사용하여 공개 Google Cloud Storage 버킷에서 다운로드할 수도 있습니다.

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

8 동기 프로세스 문서 요청

이 단계에서는 동기식 엔드포인트를 사용하여 소설의 처음 3페이지를 처리합니다. 이 방법은 로컬에 저장된 더 작은 문서에 가장 적합합니다. 각 프로세서 유형의 최대 페이지 및 파일 크기는 전체 프로세서 목록을 확인하세요.

다음 코드를 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}")

기본 함수를 호출하면 콘솔에 추출되고 텍스트가 출력됩니다.

main()

샘플 문서를 사용하는 경우 다음과 같은 출력이 표시됩니다.

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. 비동기 프로세스 문서 요청

이제 전체 소설의 텍스트를 읽으려 한다고 가정해 보겠습니다.

  • process_documents() 메서드에는 전송할 수 있는 페이지 및 파일 크기에 제한이 있으며 API 호출당 하나의 문서 파일만 사용할 수 있습니다.
  • batch_process_documents() 메서드를 사용하면 더 큰 파일을 비동기적으로 처리하고 여러 파일을 일괄 처리할 수 있습니다.

이 단계에서는 Document AI A비동기식 API를 통해 'Winnie the Pooh' 소설 전체를 처리하고 텍스트를 Google Cloud Storage 버킷에 출력합니다.

Cloud Storage에 PDF 업로드

batch_process_documents() 메서드는 현재 Google Cloud Storage의 파일을 허용합니다. 객체 구조에 대한 자세한 내용은 documentai_v1.types.BatchProcessRequest를 참조할 수 있습니다.

이 예시에서는 샘플 데이터 버킷에서 파일을 복사할 수 있습니다.

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

또는 아래 링크에서 소설의 샘플 파일을 다운로드하여 자체 버킷에 업로드할 수 있습니다.

API의 출력을 저장할 GCS 버킷도 필요합니다.

batch_process_documents() 메서드 사용

다음 코드를 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)

기본 함수를 호출하면 콘솔에 추출된 전체 새 텍스트가 표시됩니다.

main()

파일이 이전 예보다 훨씬 커서 완료하는 데 다소 시간이 걸릴 수 있습니다. (죄송합니다.

하지만 비동기 API를 사용하면 작업이 완료된 후 GCS에서 출력을 가져오는 데 사용할 수 있는 작업 ID를 받게 됩니다.

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. 축하합니다

동기식 API와 비동기식 API를 사용하여 Document AI를 사용하여 소설에서 텍스트를 추출했습니다.

다른 문서를 실험해 보고 플랫폼에서 사용 가능한 다른 프로세서를 살펴보는 것이 좋습니다.

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 안내를 따르세요.

  • Cloud Console에서 리소스 관리 페이지로 이동합니다.
  • 프로젝트 목록에서 프로젝트를 선택한 다음 '삭제'를 클릭합니다.
  • 대화상자에서 프로젝트 ID를 입력한 다음 종료를 클릭하여 프로젝트를 삭제합니다.

자세히 알아보기

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.