読者です 読者をやめる 読者になる 読者になる

今更だけどGoogle Cloud Vision APIでOCR (その2)

OCR GCP Ruby IT プログラミング

引き続いてGoogle Cloud Vision API で遊んでみる。

a244.hateblo.jp

前置き

前回はざっくり対応漢字の確認をしたのでそれ以外の観点で。

  • 絵文字
  • 文字サイズ
  • 傍点
  • 数式(英数字だけでも)

検証

前提条件としてGoogle Cloud Platform のユーザー登録とAPIと課金の有効化は完了しているものとする。画像はMacのPagesで適当に入力し、スクリーショットを作成。

検証用のスクリプト

前回のやつを一部修正。BatchAnnotateImagesRequest.newの引数に与えるオブジェクトをそれぞれのコンストラクタで生成してから引数に与えるように修正。

#! /usr/bin/env ruby

require 'json'
require 'google/apis/vision_v1'

Vision = Google::Apis::VisionV1
vision = Vision::VisionService.new
#vision.key = "API KEY"
vision.key = ENV['GOOGLE_PRIVATE_KEY']

filename = ARGV[0]

features_list = Google::Apis::VisionV1::Feature.new({max_results: 3, type: "TEXT_DETECTION"})
context = Vision::ImageContext.new({language_hints: ["Japanese"], lant_long_rect: nil})

request = Vision::BatchAnnotateImagesRequest.new(  { requests:  [ features: [ features_list ], image: Vision::Image.new({content: File.read(filename) , image_context: context } ) ] }) 

result = vision.annotate_image(request) do |result, err |


  unless err  then

    result.responses.each do | res |
      puts res.text_annotations[0].description

#      res.text_annotations.each do | ta |
#        puts ta.description
#      end

    end

#    print JSON.pretty_generate(result.to_h)
  else
    puts err
  end

end

必要に応じて32行目をコメントアウトする。

使い方は前回と同じく環境変数をセットして引数に対象画像ファイル名を指定する。trial.rbという名前にしているので、下記のように実行。

$ export GOOGLE_PRIVATE_KEY="APIキー"
$ ruby trial.rb 画像ファイル名

検証その1

まずは絵文字と文字サイズから。

検証画像

本来はちゃんと解像度を固定するところだけどPagesのスクリンーンキャプチャ画像で代用。

f:id:atuyosi:20160906234743p:plain

744 x 566ピクセル

結果

絵文字
文字サイズ(6pt-18pt)
2,完璧主義、憂鬱、誹謗中傷、薔薇。
3,完璧主義、憂鬱、誹謗中傷、薔薇。
4,完璧主義、憂鬱、誹謗中傷、薔薇。
5·完璧主義、憂鬱、誹謗中傷、薔薇。
6,完璧主義、憂鬱、誹謗中傷、薔薇。
7,完璧主義、憂鬱、誹謗中傷、薔薇。
*元

末尾のゴミはご愛嬌として*1

絵文字は全滅。6ptの文字列は全く認識されてない。文字の大きさは一定サイズより小さいと認識されないらしい。人間から見て読みづらいサイズは認識しないのか、文字がありそうな領域の検出時点で弾かれているのか。

絵文字を文字とみなすかと言われると微妙なので妥当といえば妥当。

検証その2

画像

f:id:atuyosi:20160907155530p:plain

739 x 751ピクセル。 壁の字の羅列箇所は、2、8、12番目の文字だけ完璧の「璧」になっている。逆に意図的に完璧の璧を(かべ)にしている。

丸囲み数字とはあまり言わないのかも。Wikipediaでは丸数字、丸付き数字と書いてある。

結果

丸囲み文字
-NEC特殊文字
闢] ㍾ ㍽ ㍻キロ芋ン脊/ラトン7-Myy?"-ドルトンth龍す
,似たような漢字の中に紛れ込ませると?
壁璧壁壁壁壁璧璧壁壁壁璧壁壁壁壁壁(10pt)
壁璧壁壁壁壁辟璧壁壁壁璧壁壁壁壁壁(12pt)
壁璧壁壁壁壁壁璧壁壁壁璧壁壁壁壁壁(14pt)
完璧の璧を壁に変えてみると?
完璧な人間はいない。(10pt)
完璧な人間はいない(1 4pt)
,下線
我輩は猫である名前はまだない。
傍点
我輩は猫である。名前はまだない。
·その他
吾輩は猫である。 はまだない。
Cehぶうまんばん
漢字にルビを振る。重複するデータを削除する。順風満帆。

中黒(・)の認識が不安定なのと、一部存在しないはずの文字が出ている。 なぜか「漢字(かんじ)」と「重複(じゅうふく)」のルビは無視されて、不完全ながら「順風満帆(じゅんぷうまんぱん)」の方は認識されている。

認識結果をエディタに貼り付けて検索をかけると、「璧」と「(かべ)」の識別に失敗しているのは10ptのケースと「完」の文字の直後。

f:id:atuyosi:20160907162951p:plain

完璧の「璧」を(かべ)に置き換えたものは補正されている。これは前回の叱咤激励と同じ。 意図的に「(かべ)」の文字にしているので(通常は誤字だけど)意図した文字ではない。

ちょっとサンプルが足りないですが、ざっくりまとめると以下のようになる。

  • 丸囲みの数字は全滅というか無視されている
  • "㍾ ㍽ ㍻" はきっちり認識しているけど、「㌔」が二文字で認識されている以外の単位系の特殊文字は全滅
  • 傍点は無視しているようで対象の文字は認識できている
  • アンダーラインは句点(。)の認識に失敗している
  • 黒背景に白抜きの文字は認識できない
  • 熟語の場合は認識結果に補正がかかる
  • 文字に振り仮名がふってあったとしても認識できるが、振り仮名自体は完全には認識できない

比較的フォーマルな文書ではNEC特殊文字は使われないだろうからいいとして丸囲み数字*2は きっちり認識してほしいところ。

特に Tesseract に対する優位点を整理すると、

  • (文字サイズが小さい場合に)圧倒的な認識率
  • 傍点、下線、ルビによる影響を受けにくい
  • 認識可能な漢字の対応範囲が広い

一応補足しておくと、画像を拡大してやれば Tesseract の方も認識率は改善するはず*3 。ただ Tesseract は傍点、ルビの類は苦手なようなので前処理で除去してしまうか、ルビは独立した行としないとつらい。

個人の主観であって定量データではないです。労力の割に得るものなさそうなので。

検証その3(数式)

まあダメ元でやるだけやってみました。全然ダメです。

LaTeXでと言いたいところだけど面倒なのでPages+MathTypeで逃げる。30日間の評価期間が終了しても"MathType Lite"として数式エディタ機能は使えるとのこと。

画像

f:id:atuyosi:20160907193818p:plain

マクスウェル方程式積分系と組み合わせの計算式あたりで妥協。 581 x 314ピクセル

結果

B.dA-0
OB
Vx E
at
E.dA
through
n!
DE
dA

英数字はもう少し認識するかと思いましたが微妙な感じ。括弧はいけるかと思いましたが分数はダメだった模様です。

まとめ

Google Vision APIOCR機能について、①、②のような数字と黒背景かつ白抜きの文字を認識できないことがわかったのは大きな収穫。他の条件(アンダーラインや振り仮名)は画像自体を拡大してやればなんとかなりそう。

認識対象文字をコントロールできないのは難点だけど、それでも Tesseract と比べれば圧倒的な認識率。

傍点などの文字に対する装飾の情報は普通にロストするのでそこは頭に入れておく必要がある。


絵文字と数式は無茶振りとして、天下のGoogleAPIにも不完全な部分があるということでした。

それではまた。

*1:背景色は白色なんで二値化でおかしくはならないはず

*2:これもNEC特殊文字の一部ではある

*3:というか拡大しないとひどい結果を返してくるときがある。