2023年6月28日水曜日

GoogleのDocument AIのAPIを呼び出してOCRを実行する

 GoogleのDocument AIのAPIを呼び出してOCRを実行してみます。

GoogleのDocument AIですが、料金のページにあるようにCloud Vision、Cloud Natural Language API、Vertex AIの料金が適用されます。ドキュメントOCRプロセッサではCloud Visionが使用されるため、Cloud Visionの料金を確認します。

Cloud Visionの料金を確認すると、すべての機能について最初の 1,000 ユニット/月無料となっています。APEXのアプリケーションを作ってAPIの呼び出しを確認する程度であれば、費用が発生することはなさそうです。

将来に無料枠が無くなる、または、条件が変わる可能性はあります。お金が関わることですし、Googleが提供している情報はご自身で確認してください。

Document AIのAPIは、サービス・アカウントを作成して、その権限で呼び出します。サービス・アカウントの作成は、以前にIndexing APIの呼び出しで紹介したことがあります。少し手順を変更するため、繰り返しにはなりますが、サービス・アカウントの作成も含めて作業手順を記述します。

作成したAPEXアプリケーションは以下のように動作します。

スタバのレシートから文字を抽出しています。文字や数値は、すべて抽出されていることが確認できます。

以下よりGoogle Cloud側の作業手順を記述します。

プロジェクトは作成済みとします。


Google側での準備


APIとサービスを開き、APIとサービスの有効化をクリックします。


今回使用するCloud Document AI APIを検索し、選択します。


Cloud Document AI API有効にするをクリックし、有効にします。料金のNumber of pages processed for OCR processorを選択すると、OCRには無料枠があることが確認できます。


APIが有効になります。タブの認証情報を開いて、サービス・アカウントを作成します。認証情報を作成をクリックするとウィザードが開始しますが、今回は使用しません。


認証情報の作成をクリックし、作成する認証情報としてサービスアカウントを選択します。


サービスアカウント名サービスアカウントIDを指定します。サービスアカウントIDの下に表示されるメールアドレスは、APEXアプリケーションからDocument AI APIを呼び出す際に使用します。そのため、コピーをとって記録しておきます。

作成して続行をクリックします。


このサービスアカウントにプロジェクトへのアクセスを許可する(省略可)のステップで、ロールオーナーを選択します。

ステップ3のユーザーにこのサービスアカウントへのアクセスを許可(省略可)は省略するので続行はせず、ここで完了をクリックします。


サービスアカウントが作成されます。


IAMと管理IAMを開くと、作成したサービスアカウント権限に含まれていることが確認できます。


サービスアカウントを開き、作成したサービスアカウントを選択します。サービスアカウントにキーを作成します。


キーのタブを開き、鍵を追加から新しい鍵を作成を選択します。


キーのタイプとしてP12(PKCS#12形式)を選択し、作成を実行します。この鍵はPL/SQLのパッケージDBMS_CRYPTOで使用するため、PKCS#1またはPKCS#8形式に変換します。JSONが推奨となっていますが、opensslコマンドを使用するため扱いやすいP12を選択しています。

作成をクリックします。


秘密鍵が手元のPCにダウンロードされます。opensslで形式変換する際に、秘密鍵のパスワードを聞かれるため、表示されている秘密鍵のパスワードをクリップボードにコピーし、保存しておきます。

閉じるをクリックします。


ダウンロードされたPKCS#12形式のファイルをPKCS#8形式に変換します。openssl pkcs12コマンドを使用します。

openssl pkcs12 -in ダウンロードされたファイル -nocerts -nodes -out 出力ファイル

Enter Import Password:には秘密鍵のパスワードを入力します。

以下の例では、秘密鍵をdocument-ai-api.keyというファイルに出力しています。

$ openssl pkcs12 -in <秘密鍵のファイル> -nocerts -nodes -out document-ai-api.key

Enter Import Password: 秘密鍵のパスワード

MAC verified OK

$ 


以上でサービス・アカウントに関する準備は完了です。

これからOCRを準備します。

Document AIプロセッサギャラリーを開きます。


Document OCRプロセッサを作成しますをクリックします。


画面右にドロワーが開きます。

プロセッサ名は任意ですが、今回はOCRとしました。リージョンUS(米国)を選択しています。

作成をクリックします。


プロセッサOCRが作成されます。

予測エンドポイントは、APEX側からREST APIとして呼び出すURLになります。コピーして記録しておきます。



動作確認をしてみます。テストドキュメントをアップロードをクリックし、以下のJPEG画像をアップロードしてみます。


以下の結果になりました。文字や数値は、すべて抽出されていることが確認できます。


以上でGoogle側の準備は完了です。


APEX側の準備



Document AI APIを呼び出す際に使用するWeb資格証明を作成します。

ワークスペース・ユーティリティWeb資格証明を開きます。


作成済みのWeb資格証明が一覧されます。作成をクリックします。


作成するWeb資格証明の名前Google Document AI API Token静的IDGOOGLE_DOCUMENT_AI_API_TOKENとします。

認証タイプとしてHTTPヘッダーを選択します。

資格証明名としてHTTPヘッダー名であるAuthorization、資格証明シークレットとしてAuthorizationヘッダーの値になる任意の文字列を入力します。資格証明名、資格証明シークレットはPL/SQLコードを実行して更新するため、現時点では何を入力してもかまいません

URLに対して有効は必須ではありませんが、OCRプロセッサをUSに作成したため、以下の値を指定しています。

https://us-documentai.googleapis.com/

以上で作成をクリックします。


静的IDGOOGLE_DOCUMENT_AI_API_TOKENであるWeb資格証明が作成されました。


パッケージUTIL_GOOGLE_APIを作成します。

以下のコードを実行します。

サービス・アカウントの秘密鍵よりJWTを生成し、それを使ってアクセス・トークンを取得します。取得したアクセス・トークンをWeb資格証明GOOGLE_DOCUMENT_AI_API_TOKENに設定しています。

サービス・アカウントの秘密鍵やメール・アドレスはそれぞれ置き換えます。

このコードは、SQLclなどでワークスペース・スキーマに接続して実行することを想定しています。そのため、APEX_CREDENTIAL.SET_PERSISTENT_CREDENTIALSを呼び出す前にAPEX_UTIL.SET_SECURITY_GROUP_IDを呼び出しワークスペースを設定しています。

SQLワークスペースSQLコマンドSQLスクリプトからも実行できますが、秘密鍵の情報がSQLの実行履歴として残るといった、できれば避けたい状況が発生します。秘密鍵を安全に保存した上でJWTを生成するには、特別な作り込みが必要です。

OCIのボールトではできず(こちらの記事で説明しています)、APEXでは23.1よりWeb資格証明認証タイプキー・ペアが新たに追加されていますが、保存した秘密キーを使って署名を行なう機能は提供されていません。


Googleのサービス・アカウントの秘密鍵なので、GoogleのCloud Key Managementに秘密鍵を保存して、それを使ってJWTを生成するのが合理的だろうと思います。微々たる金額ですが、無料枠が見つからなかったのと、今回の主題からは外れるため実装からは外しました。


APEXアプリケーションの作成



GoogleのDocument AI APIを呼び出してOCRを実行するAPEXアプリケーションを作成します。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前Google Document AI OCRとします。


OCRを呼び出すURLを、アプリケーション定義置換に定義します。

置換文字列G_PROCESS_URL置換値は作成したOCRプロセッサの予測エンドポイントです。


OCRの処理はホーム・ページに実装します。

ページ・デザイナホーム・ページを開きます。

最初にOCRを実行するイメージ・ファイルを指定するためのページ・アイテムを作成します。

識別名前P1_IMAGEタイプとしてファイル参照...ラベルImageとします。

設定表示形式Inline Dropzone記憶域タイプとして事前準備の不要なTable APEX_APPLICATION_TEMP_FILESを選択します。ファイルをパージするタイミングEnd of Sessionです。

セッション・ステートストレージとしてセッションごと(永続)を選択します。


OCRを実行する(OCRを実行するREST APIを呼び出す)ボタンを作成します。

識別ボタン名SUBMITラベルSubmitとします。動作アクションはデフォルトのページの送信です。


デバッグ用途として、REST APIが返すレスポンスをそのまま表示するページ・アイテムを作成します。

識別名前P1_RESPONSEタイプテキスト領域ラベルResponseとします。セッション・ステートデータ型CLOBストレージとしてセッションごと(永続)を選択します。


OCRによって抽出された文字列を表示するページ・アイテムを作成します。

識別名前P1_TEXTタイプテキスト領域ラベルTextとします。セッション・ステートデータ型CLOBストレージとしてセッションごと(永続)を選択します。


OCRにかけたイメージを表示するページ・アイテムを作成します。

識別名前P1_DISPLAY_IMAGEタイプイメージの表示ラベルImageとします。

設定基準としてBLOB Column returned by SQL statementを選択し、SQL文に以下を記述します。

select blob_content from apex_application_temp_files where name = :P1_IMAGE

レイアウト新規行の開始オフにして、抽出された文字列の右にイメージを配置します。セッション・ステートストレージとしてリクエストごと(メモリーのみ)を選択します。


プロセス・ビューを開き、OCRを実行するプロセスを作成します。

識別名前Extract Text from Imageタイプとしてコードを実行を選択します。ソースPL/SQLコードとして以下を記述します。

サーバー側の条件ボタン押下時SUBMITを指定します。


以上でAPEXアプリケーションは完成です。

アプリケーションを実行すると記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/google-document-ai-ocr.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

追記

Oracle CloudにはDocument Understandingというサービスがあり、その中のText extractionがOCRにあたる処理をします。こちらも無料枠は提供されているため、アップグレードする必要がある、とバナーに表示されていても動作確認は可能です。

同じイメージでテキスト抽出を行ってみましたが、日本語の抽出はできませんでした。