画像からのテキストの抽出は、長年ソフトウェア工学においてよく知られた課題です。そして光学式文字認識(OCR)は、この問題への対処に広く使用されている先駆的な技術。テキストを含む画像を機械が読み取り可能なデータに変換するOCRは、文書処理の自動化から言語翻訳まで、さまざまな業界に革命をもたらしました。

商用のOCRソリューションも存在しますが、汎用的で高性能なプログラミング言語であるPythonを使って独自のOCR APIを構築することで、カスタマイズ、データプライバシーの制御、コスト削減の可能性のような恩恵を受けることができます。

ということで、今回はPythonで独自のOCR APIを構築する手順をご紹介。効果的なOCR APIを開発するために必要なライブラリ、スキル、および考慮事項についても取り上げます。

前提条件

これからご紹介する内容は、PythonとFlaskの基礎知識、そしてシステムにPythonのローカルコピーがあることを前提とします。

OCR APIを構築する

POSTエンドポイントを通して画像をアップロードし、Pillowで読み込み、PyTesseractラッパー(OCRエンジンのTesseract)を使用して処理するFlaskアプリケーションを構築していきます。抽出したテキストは、リクエストに対するレスポンスとして返されます。

作成したAPIをカスタマイズし、テンプレートベースの分類(請求書からの行項目の抽出や税務フォームの入力など)や、OCRエンジンの選択(その他のOCRエンジンはこちら)などの機能を提供することも可能です。

まずは、プロジェクト用にディレクトリを作成しましょう。その後以下のコマンドを実行し、作成したフォルダ内に仮想環境をセットアップします。

python3 -m venv env
source env/bin/activate

続いて、以下のコマンドを実行して、Flask、PyTesseract、Gunicorn、Pillowをインストールします。

pip3 install pytesseract flask pillow gunicorn

インストールを終えたら、ホストOSにTesseract OCRエンジンをインストールします。Tesseractのインストール手順はこちらをご覧ください(ホストOSによって手順は異なる)。

例えば、macOSの場合は以下のコマンドを実行し、HomebrewでTesseractをインストールすることができます。

brew install tesseract

これを終えると、PyTesseractラッパーがOCRエンジンと通信し、OCRリクエストを処理できるようになります。

これで、Flaskアプリケーションの構築を始めることができます。「ocrapi」という名前のディレクトリを作成し、このディレクトリに「main.py」という名前でファイルを作成します。このファイルの中に、以下を貼り付けて保存してください。

from flask import Flask, request, jsonify
from PIL import Image
import pytesseract

app = Flask(__name__)

@app.route('/ocr', methods=['POST'])
def ocr_process():
    if request.method == 'POST':
        image_file = request.files['image']
        image_data = Image.open(image_file)

        # Perform OCR using PyTesseract
        text = pytesseract.image_to_string(image_data)

        response = {
            'status': 'success',
            'text': text
        }

        return jsonify(response)

上のコードにより、エンドポイント/ocrを持つ簡単なFlaskアプリを構築できます。このエンドポイントに画像ファイルで POSTリクエストを送ると、ファイルが抽出され、pytesseractラッパーを使用してcode_to_string()でOCRが実行され、抽出したテキストがレスポンスの一部として返されます。

続いて、同じocrapiディレクトリに「wsgi.py」ファイルを作成し、以下を貼り付けます。

from ocrapi.main import app as application

if __name__ == "__main__":
    application.run()

次のコマンドでアプリを実行します。

gunicorn ocrapi.wsgi

以上で基本的なOCR APIが完成です。早速テストを行いましょう。

OCR APIをローカルでテストする

APIへのリクエストを送信するには、組み込みのcURL CLIを使用するか、Postmanのような高度なAPIテストツールを使用することができます。APIをテストするには、テキストを含むサンプル画像をダウンロードします。シンプルなこちらの画像(またはこちらの走り書きバージョン)を使ってみてください。

いずれかをプロジェクトディレクトリにダウンロードし、「simple-image.png」や「scribbled-image.png」 といったわかりやすい名前をつけます。

ターミナルを開いて、プロジェクトのディレクトリに移動し、以下のコマンドを実行してAPIをテストしましょう。

curl -X POST -F “[email protected]” localhost:5000/ocr

これでOCR APIにリクエストが送信され、以下のようなレスポンスが返されます。

{
  "status": "success",
  "text": "This looks like it was written in a hucrynn"
}

これで、OCR APIが適切にセットアップされていることがわかります。もう一つの画像でも試してみてください。

{
  "status": "success",
  "text": "This looks like it was written with a steady handnn"
}

複数の画像を試すことで、Tesseract OCRエンジンの精度も確認できます。これで、Kinstaのアプリケーションホスティング上でOCR APIをホストし、オンラインでアクセスできるようにすることができます。

OCR APIをデプロイする

アプリをKinstaにデプロイするには、まずプロジェクトコードをGitサービス(BitbucketGitHub、またはGitLab)にプッシュしてください。

また、コードをプッシュする前に、ホストコンピュータでTesseractを別途設定し、PyTesseractラッパーを使用できる状態にする必要があります。Kinstaのアプリケーションホスティングでラッパーを使用できるようにするには、再度セットアップすることになります(これは他の一般的な環境でも然り)。

リモートコンピュートインスタンス(AWS EC2など)で作業する場合は、コンピュートインスタンスにSSHで接続し、パッケージをインストールするためのコマンドを実行します。

なお、Kinstaのアプリケーションホスティングでは、ホストへの直接アクセスを提供していません。NixpackBuildpack、またはDockerfileのようなソリューションを使用して、アプリケーションの環境の初期要件(ローカルでのTesseractパッケージのセットアップを含む)を設定し、アプリケーションをインストールしてください。

プロジェクトのディレクトリにnixpacks.tomlファイルを作成し、以下の内容を保存します。

# nixpacks.toml

providers = ["python"]

[phases.setup]
nixPkgs = ["...", "tesseract"]

[phases.build]
cmds = ["echo building!", "pip install -r requirements.txt", "..."]

[start]
cmd = "gunicorn ocrapi.wsgi"

上のコードは、ビルドプラットフォームに以下の指示を出します。

  1. アプリケーションのビルドと実行にPythonランタイムを使用する
  2. アプリケーションのコンテナにTesseractパッケージをセットアップする
  3. gunicornを使ってアプリを起動する

また、以下のコマンドを実行してrequirements.txtファイルを生成し、アプリケーションホスティングで、ビルド時に必要なPythonパッケージのインストールに使用できるようにします。

pip3 freeze > requirements.txt

Gitリポジトリの準備ができたら、以下の手順で、OCR APIをKinstaにデプロイします。

  1. ログインまたはアカウントを作成し、MyKinstaを開く
  2. 任意のGitサービスでKinstaを認証
  3. 左サイドバーで「アプリケーション」を選択し、「アプリケーションを追加」をクリック
  4. デプロイするリポジトリとブランチを選択
  5. 37箇所のデータセンターの中から、任意のリージョンを選択(Nixpackファイルでアプリケーションのビルド設定が自動検出されるため、startコマンドは空白のままでOK)
  6. RAMやディスク容量などのリソースを選択
  7. アプリケーションを作成」をクリック

デプロイが完了したら、デプロイされたアプリケーションのリンクをコピーし、CLIで次のコマンドを実行します。

curl -x POST -F “[email protected]” <your-deployed-app-link>/ocr

これにより、ローカルで受け取ったものと同じレスポンスが返されるはずです。

{"status":"success","text":"This looks like it was written with a steady handnn"}

Postmanを使ってAPIをテストすることもできます。

Postmanでアプリケーションをテスト
Postmanでアプリケーションをテスト

以上で、簡単なOCR APIの開発が終了です。このプロジェクトのコードの全貌はこちら(GitHub)からご覧いただけます。

まとめ

自分好みにカスタマイズ可能な自己ホスティング型のOCR APIを構築する手順を取り上げました。このAPIは画像からテキストを抽出してくれるため、データ抽出や文書のデジタル化など、さまざまなアプリケーションに優れた機能を提供します。

OCR APIの開発と改良を続けながら、多言語サポート、画像の前処理技術、画像の保存とアクセス用のクラウドストレージサービスとの統合など、より高度な機能も探ってみてください。

自己ホスティング型のOCR APIに欠かせない機能といえば?以下のコメント欄でぜひご意見をお聞かせください。

Kumar Harsh

インドを拠点とするソフトウェア開発者、テクニカルライター。JavaScriptとDevOpsが専門。詳しい仕事情報は自身のウェブサイトで公開している。