陸自のイラク日報をOCRしてJSON化する(暫定版/Google Cloud Vision API)


スポンサーリンク

すでに検索サイトも作った方がいますし、ブログ記事化した方もいますが、マイペースでいきましょう。

スクライド風にに言うと「俺がスロウリィ!?」ですが気分が乗らなかったのはしょうがない。

スクライド 5.1ch DVD-BOX (期間限定生産)

スクライド 5.1ch DVD-BOX (期間限定生産)

やりたいこと

陸上自衛隊のイラク日報のデータは紙で配布されたのか画像をPDF化したしろもろなので検索できないし、テキスト読み上げ処理とも相性が悪い。

OCRするに際して大義名分は一般市民側にあると考えて良いでしょう。

やることとしては、

  1. PDFを1ページずつ画像化する(または内部の画像データの抽出)
  2. 画像データをGoogle Cloud Vision APIでOCR、JSONデータを取得
  3. JSONデータを扱いやすく
  4. DBにぶち込むほか、加工する

ということ。とりあえずこの記事は「2. 」まで。

PDFの画像化、または画像データの抽出

PDFの画像化はコマンドでやるか、あるいはPythonのライブラリで適当にやるか。コマンドでやるならmutoolsかな。

a244.hateblo.jp

GhostScript系のコマンドでもいいだろうけど。

PDF内部の画像データを抜き取るのもあり。陸自の日報と半径内が、下記のブログ記事はPDFminerを使っている。

blog.mudatobunka.org

他の選択肢はPopplerあるいはそのラッパーライブラリを探して使うか。

プログラム作成

前提

環境など。

  • Python 3.x (3.6.5)
  • macOS 10.13.4
  • (PyCharm CE 2017.3.4)

PyCharmでコードを書いて、環境変数(後述)をセットして実行。PyCharmで実行する必然性はないけど。

準備

pdf2imageというPython用のライブラリがあるのでこれを使う。内部でPopplerを呼び出すらしい。

github.com

$ pip3 install  pdf2image

環境によってはPopplerもインストールする。Linux系の場合はおそらくpoppler-utilsが必要。

$ brew install poppler

参考ページ:PythonでPDFを画像に変換する | ぷろぐら×でざいん

Google Cloud Vision APIの呼び出し

pypi.org

Google提供のPython用のライブラリgoogle-cloud-visionを使う方向で。エラー処理周りとBASE64エンコードする必要が無いのがメリット。直接APIを叩いたほうがシンプルな気もする。

大前提として、事前にGoogle Cloud Platformのユーザー登録とプロジェクトの作成が必要(手順は省略)。

ただ、直接JSONが欲しい場合オーバースペック。シェルスクリプトでcurlあたりを使ってリクエスト投げてもいいかも。

何よりレスポンスとして返ってくるAnnotateImageResponseオブジェクトから直接JSONデータを取得できない……。

一手間必要になるが、シリアライズ済みのデータを取得できる。

How to serialize to json or dict that response from vision api? · Issue #3485 · GoogleCloudPlatform/google-cloud-python

まず、Google Vision API用のライブラリをインストールする。

$ pip3 install --upgrade google-cloud-vision

Google Developer Console からサービスアカウントを有効化する(詳細略)。キーの記載されたJSONファイルを適当な場所に保存して、環境変数の値にファイルの場所をセットする。

$ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/keyfile.json"

このライブラリ、ドキュメントの整合性がおかしいような気がする。len()でエラーになるし、retryというオプション引数もintではなくRetryクラスのオブジェクトを渡さないといけないし。その点、ライブラリを使わずに直接POST APIを呼び出すほうがいいかもしれない。

以下参考。

qiita.com

作成したプログラム(Python スクリプト)

陸自イラク日報PDFのOCRスクリプト

PDFファイルごとに画像データ化してGoogle Cloud Vision APIを呼び出すので遅いです。

並列処理化するか、先にPDFを一気に画像化するか、前述のようにPDFminer.sixでPDF内部の画像データを抽出しておいて、その後で一気にAPIを呼び出したほうが早かっただろうと思います。

地味にPDFの画像化に1ファイルあたり十数秒ぐらいかかっていたので。更にいうと、画像をPNGフォーマットで処理している部分もJPEGにしたほうがデータ送信時間が短くなる分、高速化するはず。

生成したデータ

まあ同じデータをもとにOCRするなら結果は一緒なので個別にやる必要はないでしょう。

ノイズ除去も何もせずにデータを送りつけただけなので結果に不備があるかもしれませんがご了承のほどを。

陸上自衛隊 イラク日報データ(OCR)ダウンロード

展開すると数GBになるので注意。日本語部分はユニコードエスケープされているのでそのままでは扱いにくいです。悪しからず。

なお、元データが自衛隊作成の文書であり、著作権者は自衛隊および防衛省となるはずですが、行政文書ということなので著作権による保護対象とはならないという認識です。そもそも著作物ではない。

したがって、このJSONデータについてはパブリックドメイン相当となります。(と、信じております)。

ただ、日報の一部で「面白い」と話題になっている部分に関しては創作性が認められる可能性は有り得そうな気もします。

その時は素直にゴメンササイする方向で。

需要があるのか不明ですが、自己責任でご利用下さい。

データの利用方法

JSON形式でかつユニコードエスケープされているので、Pythonで読み込む場合は以下のように。

file = open("json/<ディレクトリ名>/対象ファイル.json")

data = json.load(file)

# テキスト認識結果
result = data['textAnnotations']

description = data['textAnnotations'][0]['description']

# ページ構造付き
pages = data['fullTextAnnotation']

Pythonで読み込めば日本語もちゃんと扱われる。 JSONのキーに関してはGoogle Cloud Vision APIのドキュメントを参照。

APIの利用料金

全部で7,876ページなのでその回数分OCR用のAPIを呼び出している。途中で失敗してやり直した文も含めてトータル8,000回ぐらい。

最初の1,000回は無料で、それ以降の呼び出し分が1,000リクエストにつき$1.5。請求は$11.48なので想定の範囲内。

ソースネクストのOCRソフトよりは安い。文字の認識位置のデータを活用しないとあまり有り難みがないですが。

気が向いたら透明テキスト付きPDFの作成にトライするということで。

とりあえずここまで。

参考資料:陸自イラク日報ファイル別ページ数一覧

別解

やり方はいろいろあるはず。MicrosoftのOCR APIという手もあるし。

その1

Google Cloud Vision APIの、PDF/TIFF Document Text Detection API(ただしベータ版)を使うこともできる(試してない)。このAPIの場合、 Google Storage 上の PDFかTIFFファイルのURLを指定すると出力先に指定したGoogle Storage上に結果を出力する模様。

PDF/TIFF Document Text Detection  |  Cloud Vision API Documentation  |  Google Cloud

その2

Google Drive に画像データをぶち込むと勝手にOCRしてテキスト化してくれるんじゃなかったけ?

まとめ

前置き部分は削っても良かったか。一部のファイルしか見ていないので適切にOCRできているのかチェックする必要がある……。

黒塗り部分の処理など、改善の余地多数あり。

Web APIの呼び出しだけでなくスクレイピング系の処理にもPythonのretryパッケージ(モジュール)は便利なので積極的に活用していきたい。

gistよりgithubにプロジェクト一式アップロードした方がいいのかな。さすがにPDFとかJSONそのままだと数GBのもあるのでスクリプト部分だけか。

www.mod.go.jp

参考URL

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

PDF構造解説

PDF構造解説

広告