ドキュメント テキストのチュートリアル

対象

このチュートリアルの目的は、Google Cloud Vision API のドキュメント テキスト検出機能を使用してアプリケーションを開発する方法を学ぶことです。このチュートリアルは、基本的なプログラミング構成やテクニックの知識があることを前提としていますが、プログラミングの初心者の方にも簡単に操作できるように設計されており、Cloud Vision API リファレンス ドキュメントを参照しながらチュートリアルに従うことで、基本的なアプリケーションを作成できるようになります。

前提条件

Python

ドキュメント テキスト OCR を使用して画像にアノテーションを付ける

このチュートリアルでは、DOCUMENT_TEXT_DETECTION リクエストを出して fullTextAnnotation レスポンスを処理する基本的な Vision API アプリケーションについて段階的に説明します。

fullTextAnnotation は、画像から抽出されたテキストを階層構造で表現したレスポンスで、ページ→ブロック→段落→語→記号のように編成されています。

  • Page は、ブロックの集まりに、ページについてのメタ情報、つまりサイズ、解像度(X 解像度と Y 解像度が違う場合がある)を付加したものです。

  • Block は、ページの 1 つの「論理的」要素を表します。たとえば、テキストで埋め尽くされている領域や、列と列の間にある図や区切りなどです。テキスト ブロックと表ブロックには、テキスト抽出に必要な主要な情報が含まれています。

  • Paragraph は、順序付けられた単語列を表すテキストの構造単位です。デフォルトで単語は、単語区切りで区切られているものとみなされます。

  • Word は、テキストの最小単位です。これは、記号の配列として表記されます。

  • Symbol は、文字または句読点記号を表します。

また、fullTextAnnotation は、リクエスト中の画像に部分一致または完全一致するウェブ画像を参照する URL を示すこともあります。

完全なコードリスト

Cloud Vision API 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()

    parser = argparse.ArgumentParser()
    render_doc_text(args.detect_file, args.out_file)

この単純なアプリケーションでは、次のタスクを実行します。

  • アプリケーションの実行に必要なライブラリをインポートする
  • 3 つの引数を main() 関数に渡す:
    • image_file - アノテーションを付ける入力画像ファイル
    • output_file - Cloud Vision が生成する、描画された多重ボックスを含む出力画像の出力ファイル名
  • サービスとのやり取りをする ImageAnnotatorClient インスタンスを作成する
  • リクエストを送信し、レスポンスを返す
  • テキストの周囲にボックスが描画された出力画像を作成する

コードの詳細

ライブラリのインポート

import argparse
from enum import Enum
import io

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

標準ライブラリをインポートします。

  • argparse: アプリケーションが入力ファイル名を引数として受け取れるようにする
  • enum: FeatureType の列挙
  • io: ファイル I/O

その他のインポート:

  • google.cloud.vision ライブラリ内の ImageAnnotatorClient クラス: Vision API へのアクセスを提供する
  • google.cloud.vision ライブラリ内の types モジュール: リクエストを作成する
  • PIL ライブラリの Image ライブラリと ImageDraw ライブラリ: 入力画像にボックスが描かれた出力画像を作成するために使用する

アプリケーションの実行

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()

parser = argparse.ArgumentParser()
render_doc_text(args.detect_file, args.out_file)

ここでは、渡された引数を解析し、それを render_doc_text() 関数に渡します。

API に対する認証

Vision API サービスと通信する前に、事前に取得した認証情報を使用してサービスを認証する必要があります。アプリケーション内で認証情報を取得する最も簡単な方法は、アプリケーションのデフォルト認証情報(ADC)を使用することです。デフォルトで、クライアント ライブラリは GOOGLE_APPLICATION_CREDENTIALS 環境変数から認証情報の取得を試みます。この環境変数はサービス アカウントの JSON キーファイル(詳しくはサービス アカウントの設定を参照)を指している必要があります。

API リクエストの作成とレスポンスからのテキスト境界の読み取り

Vision API サービスの準備ができたら、ImageAnnotatorClient インスタンスの document_text_detection メソッドを呼び出すことにより、サービスにアクセスできます。

API へのリクエストとそのレスポンスの詳細は、クライアント ライブラリによりカプセル化されています。リクエストの構造の詳しい情報については、Vision API リファレンスをご覧ください。

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

クライアント ライブラリによるリクエスト処理後のレスポンスには、AnnotateImageResponse が含まれます。これは、リクエストで渡された各画像の画像アノテーション結果のリストで構成されます。今回はリクエストで画像を 1 つだけ送信したため、full TextAnnotation を扱い、指定されたドキュメント機能のための境界を収集します。

アプリケーションの実行

アプリケーションを実行するには、この receipt.jpg ファイルをダウンロードし(場合によってはリンクを右クリックすることが必要)、ローカルマシン上のファイルのダウンロード場所をチュートリアル アプリケーション(doctext.py)に渡します。

Python コマンドと、テキスト アノテーション出力画像を以下に示します。

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

次の画像では、単語が黄色で、文が赤で示されています。

これで完成です。Google Cloud Vision のフルテキスト アノテーションを使用してテキスト検出を実行しました。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud Vision API ドキュメント
ご不明な点がありましたら、Google のサポートページをご覧ください。