Azure Computer Visionを用いて日本語画像から文字を出力してみた

2023.05.23

はじめに

データアナリティクス事業本部ビッグデータチームのkasamaです。
今回はAzure Computer Visionを用いて日本語画像から文字を出力してみたいと思います。 webサイトなどでわからない文面などがあり、それについて調べようと思った時や手書きのメモをPCで管理しようと思った時に、タイピングする作業って中々面倒ではないでしょうか。今回はそういった作業を自動化するためにAzure Computer Visionを用いて、文字出力をしてみたいと思います。

前提

OCR(テキスト抽出)

私の知る限り、OCRサービスとして、オープンソースのTesseract、AWS、GCP、Azure系のOCRサービス、Google Drive APIなどがありましたが、今回はAzure Computer Visionサービスを用いて使用することにしました。文字認識精度的にも申し分なく、かつ料金的にも1 分あたり 20 件のトランザクションかつ月5000回まで無料ですので、精度、コストパフォーマンスを考慮して選択しました。(Azureアカウントを最近新規で作成したという個人的な要因もありました。。)

Azure Computer Visionについて

Azure Computer Visionは、Microsoft Azureのクラウドベースの画像認識サービスです。以下に、主な機能と利点を説明します。

  • 画像分析: Azure Computer Visionは、画像内のオブジェクト、シーン、顔、テキストなどを認識し、分析する機能を提供します。

  • OCR(Optical Character Recognition): Azure Computer Visionは、画像内のテキストを自動的に検出し、OCRによる文字認識を行います。

  • 顔認識: Azure Computer Visionは、画像内の顔を検出し、属性(性別、年齢、感情など)を推定する顔認識機能を提供します。

  • イメージの検索: Azure Computer Visionは、画像の特徴を分析し、類似の画像を検索する機能を提供します。

Azure Computer Visionは、画像処理と認識に関連するさまざまな用途で利用されます。例えば、自動車業界では車両の損傷検出やナンバープレートの認識、小売業界では製品の分類や棚卸し、セキュリティ業界では顔認識によるアクセス制御など、さまざまな領域で活用されています。

セットアップ

それでは、Azure Computer Visionを使用するためのセットアップを行います。まずは、Azureポータルにログインします。Computer Visionを検索から、選択します。

作成ボタンから、Computer Visionを作成します。サブスクリプションモデル、リソースグループは作成した任意のものを選択し、リージョン、名前も任意の値を入力します。

価格レベルについては、画面上ではStandardと記載していますが、Freeプランを選択します。

今回は検証用のため、ネットワークはインターネットを含むすべてのネットワークがこのリソースにアクセスできます。を選択します。

作成ボタンを押下します。

作成完了後に、API Keyやエンドポイントが生成されます。こちらを後ほど使用していきますので、メモしておきます。

実装準備

環境変数の設定

先ほど作成したキーとエンドポイントを後ほど使用するため、環境変数に設定します。

Linux, macOS, or Unixの場合

export ACCOUNT_KEY=<your-api-key>
export END_POINT=<your-end-point>

Windowsの場合

set ACCOUNT_KEY=<your-api-key>
set END_POINT=<your-end-point>

Python環境のセットアップ

必要なパッケージをインストールします。コードでは azure-cognitiveservices-vision-computervision パッケージを使用しています。インストールは以下のコマンドで行えます。

pip install azure-cognitiveservices-vision-computervision

実装

20_azure_computer_vision

ディレクトリ構造

.
├── README.md
├── img
│   └── PXL_20230523_135425927.MP.jpg
├── main.py
└── output.txt

1 directory, 4 files
## main.py
import os
import time
from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.computervision.models import OperationStatusCodes
from azure.cognitiveservices.vision.computervision.models import ComputerVisionOcrErrorException


key = os.environ["ACCOUNT_KEY"]
endpoint = os.environ["END_POINT"]
image_path = "img/PXL_20230523_135425927.MP.jpg"  # ローカルの画像パス


def main(image_path):
    computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(key))
    local_image = open(image_path, "rb")
    try:
        recognize_results = computervision_client.read_in_stream(local_image, language="ja", raw=True)
    except ComputerVisionOcrErrorException as e:
        print("errors:", e.response)
        raise e
    # 結果を取得するための操作IDを取得
    operation_location_remote = recognize_results.headers["Operation-Location"]
    operation_id = operation_location_remote.split("/")[-1]

    # 結果が利用可能になるまで待つ
    while True:
        get_text_results = computervision_client.get_read_result(operation_id)
        if get_text_results.status not in ["notStarted", "running"]:
            break
        time.sleep(1)

    # テキストの出力
    if get_text_results.status == OperationStatusCodes.succeeded:
        with open("output.txt", "w", encoding="utf-8") as f:
            for text_result in get_text_results.analyze_result.read_results:
                for line in text_result.lines:
                    f.write(line.text + "\n")


print("Texts are written to output.txt")


if __name__ == "__main__":
    main(image_path)

まず、Pythonコードの先頭部分で必要なパッケージをインポートします。azure.cognitiveservices.vision.computervisionパッケージはAzureのComputer Visionサービスに接続するために使用します。 続いて、環境変数からAzureのアカウントキーとエンドポイントを取得し、処理対象の画像のパスを指定します。この部分は、自身が利用するAzureの情報とローカルの画像パスに合わせて変更してください。jpgファイル以外の拡張子でも可能です。 main()関数内で、先ほど取得したキーとエンドポイントを用いて、Computer Visionサービスへのクライアントを生成します。次に、指定されたパスの画像をバイトデータとして読み込み、Computer Visionサービスに渡します。ここでread_in_streamメソッドを使用しています。これにより、画像内のテキストを認識し、その結果を含むOperation-Locationを返します。 このOperation-Locationからoperation_idを取得し、そのoperation_idを用いて認識結果のステータスを確認します。結果がまだ利用可能でない場合(ステータスがnotStartedまたはrunningの場合)、スクリプトは結果が利用可能になるまで待機します。 最後に、認識結果のステータスがsucceededである場合、つまり画像からのテキスト認識が成功している場合、その結果をテキストファイルoutput.txtに書き出します。結果は行ごとに処理され、各行のテキストが改行コードとともにファイルに書き込まれます。 このコードを実行することで、任意の画像内のテキストを認識し、その結果をテキストファイルに保存することが可能になります。

使ってみた

では実際に使用してみたいと思います。

検証1

検証1として、Webサイトなどを想定し、私が記載したブログの画面キャプチャを撮り、画像から文字に起こす検証をしたいと思います。

実行結果

(blog_env) kasama.yoshiki@20_azure_computer_vision % python main.py
Texts are written to output.txt
(blog_env) kasama.yoshiki@20_azure_computer_vision %

ouput.txtファイルの出力になります。誤字がない素晴らしい出来でした。強いて言うなら箇条書きがと表現されてしまうぐらいですが、置換処理をかければ良いので、そこまで気にならない内容です。

検証2

検証2として手書きメモを想定し、私が学生時代に記載したノートを画像にし、文字に起こす検証をしたいと思います。字の粗さと写真の黒い影も相まって先ほどよりも難易度は高いです。

実行結果

(blog_env) kasama.yoshiki@20_azure_computer_vision % python main.py
Texts are written to output.txt
(blog_env) kasama.yoshiki@20_azure_computer_vision %

さすがにすべて正確な出力とはなりませんでしたが、それでもはっきりとメモしてある箇所は認識できている、十分な内容でした。

最後に

OCRで画像から文字を認識できたら、最近のLLM系のモデルと組み合わせてさらに面白いことができるのではと思いました。引き続き色々試していきます。