機械学習APIで画像からテキストを抽出する文字認識プログラムをPythonで作る

機械学習APIを用いて画像からテキストを抽出する文字認識(OCR)プログラムをPythonで作る

Google Cloud Vison APIとは

Vision API - 画像コンテンツ分析  I  Google Cloud P_ - https___cloud.google.com_vision_

Google Cloud Vision API は、使いやすい REST API にパワフルな機械学習モデルが組み込まれており、画像の内容を認識するアプリケーションの開発を可能にします。Google Cloud Vision API は、膨大な数のカテゴリ(「ヨット」や「ライオン」、「エッフェル塔」など)に各画像を素早く分類する機能や、画像内の個々の物体や人の顔を検出する機能、画像内に含まれているテキストを検出して読み取る機能を備えています。

CLOUD VISION API の活用方法

ラベル検出 乗り物や動物など、画像に写っているさまざまなカテゴリの物体を検出できます。
顔検出 画像に含まれる複数の人物の顔を検出できます。感情や帽子の着用といった主要な顔の属性についても識別されます。 ただし、個人を特定する顔認識には対応していません。
不適切なコンテンツの検出 アダルト コンテンツや暴力的コンテンツなど、画像に含まれる不適切なコンテンツを検出できます。
ロゴ検出 画像に含まれる一般的な商品ロゴを検出できます。
ランドマーク検出 画像に含まれる一般的な自然のランドマークや人工建造物を検出できます。
光学式文字認識(OCR) 画像内のテキストを検出、抽出できます。幅広い言語がサポートされており、言語の種類も自動で判別されます。
画像属性 画像のドミナント カラーや切り抜きのヒントなど、画像の一般的な属性を検出できます。
ウェブ検出 類似の画像をインターネットで検索できます。
統合された REST API REST API を通じてアクセスし、画像ごとにアノテーション タイプをリクエストできます。リクエストで画像をアップロードすることも、Google Cloud Storage と統合することもできます。

 

今回は、ブラウザ上からアップロードした画像内のテキストに対して光学式文字認識(OCR)を実行し、
テキスト情報をブラウザ上に出力します。

今回行うテキスト検出では、1~1,000 ユニット/月までは無料です。

Google Cloud Vison APIにアクセスするためのAPIキーを取得する。

  1. In Cloud Platform Console で、[プロジェクト] ページに移動し、新しいプロジェクトを選択または作成します。[プロジェクト] ページに移動
  2. プロジェクトの課金を有効にします。課金の有効化
  3. Cloud Vision API を有効にする。Enable the
    API

    API を有効にすると、認証情報を得る必要はありません。

Google Cloud Vison APIで扱うjsonデータ

Cloud Vision API は使いやすい REST API で、リクエスト内で送信した画像のデータ解析を HTTP POST オペレーションにより実行します。この API ではリクエストとレスポンスの両方で JSON を使用します。一般的な Vision API JSON リクエストには、検出対象の画像(1 つまたは複数)の内容と、各画像に対して行う一連のオペレーション(「機能」)が含まれます。

 

現時点では、Vision API は 1 つのコレクション(images)で構成されます。このコレクションは 1 つの HTTP リクエスト メソッド(annotate)をサポートしています。

 

この POST リクエストの認証には、API キーまたは OAuth トークンを POST リクエストのヘッダー内から直接渡しす必要があります。API では(GET リクエストではなく)POST リクエストを使用する必要があります。これにより、認証パラメータを、リクエスト URL に埋め込むかわりにリクエスト ペイロード内で渡せるようになります。POST リクエストおよびレスポンスの JSON 形式については以下で説明します。

https://cloud.google.com/vision/docs/detecting-text?hl=ja#vision-text-detection-python

注意事項

  • 推奨の画像サイズは「横1024 x 縦768」。
  • また、OCRで文字を検出するには、さらに高い解像度が必要です。
  • Google Cloud Vision API に送信される画像ファイルは 4MB を超えないようにしてください。
  • PHP標準ライブラリのbase64をインポートし、エンコードします。
    import base64
  • リクエスト時に送信する画像は、エンコード化されたASCIIテキストデータである必要があります。

サポートされている画像の種類

  • JPEG
  • PNG8
  • PNG24
  • GIF
  • アニメーション GIF(最初のフレームのみ)
  • BMP
  • WEBP
  • RAW
  • ICO

ディレクトリ構成

最終的なディレクトリ構成は以下のようになっています。
アセット関連は実際どうでも良く、myapp.pyと画像を書き出すディレクトリがあれば良いかと思います。
app/
├ dist/ — アセット関連(css, js)などの公開用にデプロイされた静的ファイル。
├ node_modules/ — gulpで使用するライブラリが入ったディレクトリ。
├ src/ — アセット関連(css, js)などのデプロイ前のスクリプトが入ったフォルダ。
├ views/ — HTML表示用のテンプレートが入ったディレクトリ。
├ gulpfile.js — タスクランナーgulp用の記述ファイル。
├ myapp.py — メインファイル。ここにガツガツ記述していく。
└ package.json — ラスクランナーgulpで使用するライブラリが記載されているファイル。
以下に、最終的なmyapp.pyの内容をほぼコピペで記載します。

スクリプト全文

今回はローカル内でのみの使用を想定しております。
‘YOUR_API_KEY’にはご自身で取得されたAPIキーを入力してください。

 

以下のスクリプトをコピペで最後にコマンドを実行してBottleを起動させ、ブラウザでlocalhost:8080を開けば動作します。

 

pythonの標準ライブラリ以外のものも使用しているので事前にpip等でインストールしておく必要があります。
事前に必要となるのは今回はBottleとrequestsくらいでしょうか。


import os
import requests
from bottle import route, run, template, request, static_file, url, get, post, response, error, abort, redirect, os
import base64
import json

# Google Cloud Vison APIにアクセスするためのAPIキーを取得
YOUR_API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
# エンドポイント
REQUEST_URL = 'https://vision.googleapis.com/v1/images:annotate?key={}'.format(YOUR_API_KEY)
# ヘッダー情報
headers = {'Content-Type': 'application/json'}

# 検出の種類
DETECTION_TYPES = [
    'TYPE_UNSPECIFIED',
    'FACE_DETECTION',
    'LANDMARK_DETECTION',
    'LOGO_DETECTION',
    'LABEL_DETECTION',
    'TEXT_DETECTION',
    'SAFE_SEARCH_DETECTION',
]

# 画像ファイルからテキストを抽出するメソッド
def get_text_from_image(image_file):

    with open(image_file, 'rb') as image_file:
        TARGET_IMAGE = base64.b64encode(image_file.read()).decode('UTF-8')

    requests_json = {
        "requests" : [
            {
                "image": {
                    "content" : TARGET_IMAGE
                },
                "features" : [
                    {
                        "type": DETECTION_TYPES[5],
                        "maxResults" : 1
                    }
                ]
            }
        ]
    }

    res = requests.post(REQUEST_URL, headers=headers, json=requests_json).json()
    text = res['responses'][0]['textAnnotations'][0]['description'] if len(res['responses'][0]) > 0 else ''
    return text

# TOPページのパス
@route('/')
def get_index():
    return template('index_template', text='', image='')

# 静的ファイルのパス
@route('/dist/<filepath:path>', name='static_file')
def get_static(filepath):
    return static_file(filepath, root='./dist')

@route("/dist/img/<img_filepath:path>", name="static_img")
def get_static_img(img_filepath):
    return static_img(img_filepath, root="./dist/img/")

# 画像アップロード用のパス
@route('/upload', method='POST')
def post_image():
    try:
        upload = request.files.get('upload', '')
        if not upload.filename.lower().endswith(('.png', '.jpg', '.jpeg')):
            return 'そのファイルは許可されていません。'
        save_path = get_save_path()
        upload.save(save_path)
        image_path = save_path + upload.filename
        text = get_text_from_image(image_path)
        return template('index_template', text = text, image = image_path)
    except OSError:
        return template('index_template', text = '内部エラーが発生しました。', image = '')

def get_save_path():
    path_dir = "./dist/img/"
    return path_dir


# Bottleアプリの起動
run(host='localhost', port=8080, debug=True, reloader=True)

そして、以下のコマンドを実行し、ブラウザでhttp://localhost:8080にアクセスしてください。


python3 main.py

最終的なアウトプット

ネットから拾った定型文の画像からテキストを抽出してみましたが、
結構かなりの高精度でテキストを読み取ってくれました!

機械学習APIを用いて画像からテキストを抽出する文字認識(OCR)プログラムをPythonで作る

DBと連携させたりすれば色々な用途に使えそうで夢が広がりますね!