Vision APIのBatchAnnotateFilesメソッド(ファイルからの同期特徴抽出)を少し深堀りする

Vision APIの利用には、クライアントライブラリの利用が推奨されていますが、クライアントライブラリの理解を深めるためにも、まずはVision APIが提供するメソッドの基本的な仕様を押さえておきたいと思います。

本記事では、『Vision API クライアントライブラリの概要(Python編)』に続いて、 Vision APIの RPCで定義されているImageAnnotatorサービスのBatchAnnotateFilesメソッド(ファイルからの同期特徴抽出)について少し深堀します。なお、内容的にはREST/HTTP APIのfiles.annotateメソッドも同様かと思います。

【目次】

[1]BatchAnnotateFilesメソッドの概要

ファイル(PDF、TIFF、アニメーションGIF)から同期処理で特徴検出を行うメソッドです。

BatchAnnotateFilesメソッドは、Vision APIのRPCで定義されるImageAnnotatorサービスが提供する4つのメソッドのうちの1つす。(『Vision API クライアントライブラリの概要(Python編)』も参照してください。)

(1)特徴

  • 1つのファイルに複数のページやフレームを含めることが出来るファイル形式から特徴検出します。具体的には、PDF、TIFF、アニメーションGIFファイルです。
    • JPEG、PNG、BMP、WEBP、RAW、ICOの画像形式を送信するとエラーになります。
  • 検出できる特徴は、Vision APIの機能リストにあるものです。一つの画像に対して同時に複数の特徴を検出できます。
  • PDFファイルのOCRについては、ページ内の画像だけでなく、テキスト情報も検出対象になっているようです。(画像がないPDFファイルも扱えます。)
  • 送信できるのは1ファイルのみですが、ファイル内にあるページのうち、5ページ分まで同時に処理できます。(これはファイル全体のページ数の制限ではなく、特徴検出対象とするページ数の制限です。)
  • 同期処理のため、メソッドの戻り値として指定した特徴検出の結果を得ることができます。このため、非同期版に比べて手軽に利用できます。

(2)メソッド定義

rpc BatchAnnotateFiles(BatchAnnotateFilesRequest) returns (BatchAnnotateFilesResponse)
対応するRESTでのメソッドはfiles.annotateメソッドになります。

(3)動作イメージ

動作の流れを大雑把に図で表すと以下のようになります。



  1. BatchAnnotateFileRequestに、1つの解析対象のファイル情報と1つ以上の検出したい特徴(AnnotateFileRequest)を設定して、BatchAnnotateFilesメソッドを呼び出します。
  2. 同期処理され、BatchAnnotateFilesメソッドのレスポンス(戻り値)として検出結果(BatchAnnotateFilesResponse)が得られます。
  3. BatchAnnotateFilesResponseから、AnnotateFileRequestに対応するAnnotateFileResponseが得られます。ここにファイル内のページ毎の特徴検出結果(AnnotateImageResponse)が格納されています。

(4)BatchAnnotateImagesメソッドとの違い

ImageAnnotatorサービスのBatchAnnotateImagesメソッドは、複数の画像ファイルをまとめてリクエストして、その検出結果を画像ファイルごとに受け取ります。
(BatchAnnotateImagesメソッドについては『Vision APIのBatchAnnotateImagesメソッド(画像からの同期特徴抽出)を少し深堀りする』を参照してください。)


一方、BatchAnnotateFilesメソッドは、1つのファイルに複数のページやフレームを含めることが出来るファイル形式(PDF,TIFF,GIF)が対象となっているため、いわば1つのファイル内に複数の画像ファイルを含んでいると考えることができます。

「ファイル内のページ=画像ファイル」という簡単な対応付けを考えると、PDFファイルなどは、複数画像をバッチ解析するコンテナと考えられるため、AnnotateFileRequestはBatchAnnotateImageRequestに対応付けて考えることもできます。

BatchAnnotateImageRequestは、解析する画像をAnnotateImageRequestとして指定しますが、AnnotateFileRequestでは、ファイル内の解析するページ(画像に相当)をpagesフィールドで指定します(pagesフィールドを省略すると、先頭から5ページまでが解析対象となります)。

異なる点として、BatchAnnotateImageRequestは、画像(AnnotateImageRequest)毎に検出したい特徴タイプを指定できますが、AnnotateFileRequestはファイル単位で特徴タイプを指定します。よって、ファイル内のページ毎に異なる特徴タイプは指定できません。

同様に、検出結果についても、AnnotateFileResponseは、BatchAnnotateImagesResponseに対応すると考えることができます。
AnnotateFileResponseのresponsesフィールドには、ファイル内の指定したページ(画像に相当)毎に、検出結果(AnnotateImageResponse)が格納されます。
AnnotateImageResponse以下の構造は、BatchAnnotateImagesメソッドと基本的には同じとなります。

[2]リクエストデータ:BatchAnnotateFilesRequest

リクエスト(入力)データであるBatchAnnotateFilesRequestの構造を図にしてみました。


1つのファイル(複数ページ可)に対する特徴検出リクエストをAnnotateFileRequestで定義します。これは4つのフィールドを持ちます。
  • input_config:(必須)解析したい1つのファイルを指定します。
  • features:(必須)検出したい特徴タイプを指定します。(複数指定可能)
  • image_context:(オプション)検出したい特徴タイプ固有のパラメータ
  • pages:(オプション)検出対象ページを指定します。(実用上は必須かも)
そして、BatchAnnotateFilesRequestのrequestsフィールドにのAnnotateFileRequestを1つ設定します。
これにより、1つのファイルの5ページ以内から、ランドマーク、ロゴ、文字認識などの複数の特徴検出を一括して行うことが出来ます。

(注意)
BatchAnnotateFilesRequestのrequestsフィールドはリストなので、構造上は複数のAnnotateFileRequestを指定できるように見えますが、2つ以上のAnnotateFileRequestを設定するとエラーになります。

以下にAnnotateFileRequestの各フィールドを見ていきます。

(1)ファイルの指定(InputConfig)

解析対象のファイルは、AnnotateFileRequestのinput_configフィールド(InputConfig型)に指定します。

指定できるファイル形式は、PDF、TIFF、アニメーションGIFで、mime_typeフィールドに指定します。
  • PDF=application/pdf
  • TIFF=image/tiff
  • GIF=image/gif
なお、mime_typeフィールドを設定しないか、上記以外の値を設定するとエラーになります。

ファイルのデータは、以下の2つの方法から1つを選んで指定します。
  • バイナリデータを送信する方法
    • contentフィールドに、ファイルのバイナリデータを設定します。(ファイルデータそのものを送信する方法です。)
    • なお、JSON APIでは画像データをbase64で表現する必要がありますが、PythonクライアントライブラリはRPCを利用しているため、バイナリデータを指定します。
  • Google Cloud Storageのパスを指定する方法
    • gcs_sourceフィールドに、uriフィールドをもつオブジェクト(GcsSource型)を設定します。
    • uriフィールドには、Google Cloud Storage URI形式(gs://bucket_name/object_name)で、画像オブジェクトのパスを指定します。
なお、contentフィールドとsourceフィールドを同時に指定した場合は、エラーになるようです。

(2)検出したい特徴の指定(Feature)

解析対象のファイルから検出したい特徴は、featuresフィールドで複数指定できます(Feature型オブジェクトのリストで指定します)。なお、ここで指定する特徴は、検出対象の全てのページに適用されます。(検出するページ毎に異なる特徴は指定できません。)

Featureオブジェクトは3つのフィールドを持ちます。
  • type:(必須)検出する特徴。機能リストに対応する定数を1つ指定します。
    • FACE_DETECTION = 1
    • LANDMARK_DETECTION = 2
    • LOGO_DETECTION = 3
    • LABEL_DETECTION = 4
    • TEXT_DETECTION = 5
    • DOCUMENT_TEXT_DETECTION = 11
    • SAFE_SEARCH_DETECTION = 6
    • IMAGE_PROPERTIES = 7
    • CROP_HINTS = 9
    • WEB_DETECTION = 10
    • PRODUCT_SEARCH = 12
    • OBJECT_LOCALIZATION = 19
  • max_results:(オプション)typeで指定した特徴検出の最大数を指定します。
    • なお、TEXT_DETECTION、DOCUMENT_TEXT_DETECTION、CROP_HINTSには適用されないとされています。
  • model:(オプション)typeで指定した特徴検出のモデルを指定します。

(3)特徴タイプ固有のパラメータ(ImageContext)

指定した特徴(Feature)のタイプ固有のパラメータをオプションで指定することができます。

(4)検出対象ページの指定(pagesフィールド)

ファイル内の特徴検出したいページをpagesフィールドで指定します。

pagesを省略すると、デフォルトの動作として、ファイルの最初の1ページから5ページまで(最大5ページ)が検出対象となります。

ページは、最初のページが1となり、次のページを2として指定します。
また、マイナスのページ指定もできます。例えば、-1を指定すると、最後のページを指定したことになり、-2を指定すると、最後のページの前のページを指定したことになります。
(但し、マイナスのページ指定を指定した場合、後述のレスポンスデータのpage_numberフィールドには、マイナスのページ番号ではなく、通しページ番号が設定されます。)

以下はpagesを指定する場合の例です。
  • 3ページ目のみ検出対象にする例
    • [3]
  • 1ページ目、3ページ目、5ページ目、最後から2ページ目、最後のページを検出対象にする例
    • [1,3,5,-2,-1]

なお、ファイル内に存在しないページを指定した場合は条件により挙動が変わります。指定したページのうち、1ページ以上指定したページが存在すれば、存在するページのみ結果が得られますが(存在しないページは無視される)、1ページも指定したページが存在しない場合はメソッド全体のエラーになります。

ところで、pagesフィールドは省略可能ですが、殆どのケースでは、明示的にページを指定するのが良いと思います。
複数ページを含むPDFファイルの場合は、1ページ目のみ解析したいと思っても無駄に5ページ解析されてしまいますし、利用ケースに応じて正またはマイナスのページ番号を明示したほうが良いように思います。

プログラミングにおいても、pagesフィールドで指定したページと、レスポンスのpage_numberフィールド(必要に応じてtotal_pagesも)と突き合わせて照合することで、意図したページであることを確認しやすいと思います。
なお、全ページを対象に特徴抽出したい場合は、非同期版のAsyncBatchAnnotateFilesを検討したほうが良いかもしれません。

[3]レスポンス:BatchAnnotateFilesResponse

レスポンス(検出結果)データであるBatchAnnotateFilesResponseの構造を図にしてみました。



BatchAnnotateFilesResponseのresponsesフィールドには、AnnotateFileRequest(1つのファイルに対する特徴検出リクエスト)に対応する検出結果(AnnotateFileResponse)が格納されます。
実際には、BatchAnnotateFilesメソッドは、1つのAnnotateFileRequestしか受け付けないため、結果としてAnnotateFileResponseも1つです。

以下にAnnotateFileResponseから階層的に見ていきます。

(1)AnnotateFileResponse

①input_configフィールド

BatchAnnotateFilesメソッドでは、input_configフィールド(InputConfig型)は未設定で返却されるようです。(リクエスト時のInputConfigの内容がコピーされるわけではありません。)

②responsesフィールド

ファイル内の検出対象としたページ毎に、その検出結果がAnnotateImageResponseに格納されます。

検出結果(AnnotateImageResponse)の並び順は、AnnotateFileRequestのpagesフィールドで指定した検出対象ページが、昇順に並びます。
例えば、pagesフィールドに[1,3,5]と指定すると、AnnotateImageResponseも[1,3,5]の順で返却されます。もし、pagesフィールドに[5,3,1]と逆順に指定しても、AnnotateImageResponseは[1,3,5]の順で返却されます。

AnnotateImageResponseのcontextフィールドのpage_numberに、検出対象のページ番号が格納されています。これを利用することで、意図したページのAnnotateImageResponseを特定することができます。

なお、マイナスのページ番号を指定した場合は、page_numberには実際のページ番号が格納されているため、直接page_numberと照合することはできません。しかし、total_pagesフィールドで全ページ数が得られますので、total_pagesから指定したマイナスのページ番号とあわせて計算することで、照合することができます。

③total_pagesフィールド

ファイル内の全ページ数が設定されます。

④errorフィールド

AnnotateFileRequestに対する処理全般についてのエラー情報は、AnnotateFileResponseのerrorフィールド(Status型)で得られることになっています。(Status型については、『Vision APIのBatchAnnotateImagesメソッド(画像からの同期特徴抽出)を少し深堀りする/[4]Status型のエラー情報』を参照してください。)

AnnotateFileResponseのerrorフィールドのcode値が0の場合は成功であり、responsesフィールドに各ページ毎の検出結果が格納されます。
なお、各ページ毎のエラー情報は、AnnotateImageResponseのerrorフィールドに格納されるため、AnnotateFileResponseのerrorフィールドが成功だったとしても、各ページレベルでは、エラーが発生している可能性はあります。

一方、AnnotateFileResponseのerrorフィールドのcode値がエラー値(0ではない値)の場合は、responsesフィールドは設定されないと仕様にはあります。しかし、code値が0でない値になる場合は、BatchAnnotateFilesメソッド全体が失敗したことを意味しており、Pythonクライアントライブラリでは、errorフィールドの内容を含んだ例外がスローされるようです。

以下はメソッド全体が失敗となる例です。
  • リクエストにmime_typeを指定しなかった場合
    • code=INVALID_ARGUMENT
    • MimeType is required.
  • PDF、TIFF、GIF以外のmime_typeを指定した場合
    • code=INVALID_ARGUMENT
    • At this time, the only MIME types supported are 'application/pdf', 'image/gif' and 'image/tiff'.
  • 壊れた、あるいは異なる画像形式を 'application/pdf'として送信した場合
    • code=INVALID_ARGUMENT
    • Unsupported input file format.
  • リクエストのfeatureを省略した場合
    • code=INVALID_ARGUMENT
    • Request must specify image and features.
  • BatchAnnotateFilesRequestに2つ以上のAnnotateFileRequestを設定した場合
    • code=INVALID_ARGUMENT
    • Right now only one AnnotateFileRequest in BatchAnnotateFilesRequest is supported.
  • 存在しないgcs_sourceを指定した場合
    • code=NOT_FOUND
    • Error opening file: {指定したCloud StorageのURI}
  • 1ページしかないPDFファイルに対して、pages=[2]を指定した場合
    • code=INVALID_ARGUMENT
    • No pages found.

なお、pagesで存在しないページを指定した場合でも、1ページ以上、検出結果がある場合はエラーにはなりません。ただし、存在しないページは対応するAnnotateImageResponseのエントリが無く、検出要求したページ数より少ない結果が返ってくる、という形となります。

(2)AnnotateImageResponse

ページ毎の検出結果です。画像に対するBatchAnnotateImagesメソッドの検出結果の構造と基本的には同じです。

①指定した特徴に対応する検出結果フィールド

AnnotateFileRequestのfeaturesフィールドで指定した特徴タイプに応じて、AnnotateImageResponseに設定されるフィールドが決まります。特徴タイプと結果フィールドの対応は以下のようになります。(なお、特徴タイプを複数指定した場合も、対応する複数のフィールドに結果が設定されます。)

(追記:2020/10/27)
OCR関連のレスポンスデータ(fulTextAnnotationとtextAnnotatins)については、以下の記事を書きましたので参考にしてください。

(注意)
BatchAnnotateImageメソッドとは異なり、TEXT_DETECTIONとDOCUMENT_TEXT_DETECTIONの結果はfull_text_annotationのみで、text_annotationsは得られません。

特徴タイプ 結果フィールド
FACE_DETECTION face_annotations
LANDMARK_DETECTION landmark_annotations
LOGO_DETECTION logo_annotations
LABEL_DETECTION label_annotations
TEXT_DETECTION full_text_annotation
DOCUMENT_TEXT_DETECTION full_text_annotation
SAFE_SEARCH_DETECTION safe_search_annotation
IMAGE_PROPERTIES image_properties_annotation
CROP_HINTS crop_hints_annotation
WEB_DETECTION web_detection
PRODUCT_SEARCH product_search_results
OBJECT_LOCALIZATION localized_object_annotations

②errorフィールド(エラー情報)

ページレベルで発生したエラー情報は、errorフィールド(Status型)で得られます。(Status型については、『Vision APIのBatchAnnotateImagesメソッド(画像からの同期特徴抽出)を少し深堀りする/[4]Status型のエラー情報』を参照してください。)

AnnotateImageResponseのerrorフィールドのcode値が0の場合は成功で、それ以外はエラーということになります。

但し、BatchAnnotateImagesとは違って、BatchAnnotateFilesメソッドにおいては、AnnotateImageResponseにエラーが設定される具体的な例が、今のところ思いつきません。
明示的に指定したページが存在しない場合は、状況によって、メソッド全体のエラーとなるか、AnnotateImageResponseにエントリが無い(無視)か、のどちらかになります。

③contextフィールド(ImageAnnotationContext型)

どのページに対する特徴検出結果であるかを示すフィールド(ImageAnnotationContext型)です。ImageAnnotationContext型には2つのフィールドがあります。
  • uri:(未使用)BatchAnnotateFilesメソッドでは設定されません。
  • page_number:特徴検出したページ番号が設定されます。

リクエストのpagesフィールドと、このpage_number(必要ならtotal_pagesも)を組み合わせることで、要求したページと検出結果を関係付けることができます。


コメント

このブログの人気の投稿

VirtualBoxのスナップショット機能

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

オントロジーエディタ Protégé を使ってみる