今更だけどGoogle Cloud Vision APIでOCR その1

今更だけどGoogle Cloud Vision API。そのうち試そうと思っているうちにGCPの仕様期間3ヶ月があっさりと終了……。

毎月最初の1000リクエストはコストゼロだそうなので試してみます。

Google Cloud Platform Japan 公式ブログ: ついに Google Cloud Vision API のベータ版リリース!

料金表(英語):Pricing  |  Google Cloud Vision API  |  Google Cloud Platform

前置き

日本語対応のOSSOCRエンジンとしてはTesseractNHocrが有名どころかと思います。 Tesseractは過去記事でもネタにしています。

今回はいわゆるWeb API であるGoogle Cloud Vision APIのText Detection (OCR) を試してみます。利用にあたっては、下記の作業が必要です。

詳細は下記の参考サイトを参照。

Cloud Vision APIの使い方まとめ (サンプルコード付き)

実験

まずは日本語の認識テスト。

テスト用スクリプト

APIエンドポイントにBASE64形式でエンコードした画像をJSONのパラメーター一式セットで送ればいいはずです。

幸いなことにGoogle API Clientというを使ったRubyのサンプルを公開されている方がいるのでこれを利用。

以下のサイトのコードを一部改変しています。

Ruby と Google Cloud Platform の Cloud Vision API で画像を解析して貰う - まっしろけっけ

まずはgemをインストール

$ gem install google-api-client

依存関係でGoogle Auth Library for Rubyというgem*1も入るようですが、面倒くさそうなので使っていません。Ruby のバージョンは2.3.1

$ ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

要点としては、以下の流れで処理を実行。

  1. Google::Apis::VisionV1::VisionService インスタンスを作る
  2. BatchAnnotateImagesRequestのオブジェクトを作ってリクエストを送る*2
  3. BatchAnnotateImagesResponseのオブジェクトが返ってくるのでAnnotateImageResponseクラスのインスタンスを取り出す

普通にエンドポイントのURLを叩いて出力のJSONをパースする方が直感的に思えます。 改変したスクリプトは以下のとおり。

#! /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]



request = Google::Apis::VisionV1::BatchAnnotateImagesRequest.new(
  requests: [
    {
      image:{
        content: File.read(filename)
      },
      features: [
        {
          type: "TEXT_DETECTION" ,
          maxResults: 1
        }
      ]
    }
  ]
) 

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

使い方は適当な名前で保存し、取得済みのAPIキーを環境変数にセットしておきます。 画像ファイルを引数に与えると標準出力に認識した文字列を表示するだけの簡単なスクリプトです。
冗長なので文節単位の認識結果、JSON出力はコメントアウトしています。

$ export GOOGLE_PRIVATE_KEY="APIキー"
$ ruby スクリプト名 画像ファイル

とりあえず試してみる。

例えば適当な画像*3

f:id:atuyosi:20160901014426p:plain

743 x 195ピクセル。Pagesで適当に入力して、Cmd+Shift+4スクリーンショットを撮ったもの。

お前に足りないものは…、それは!! 情熱思想理念頭脳気品優雅さ勤勉さ!!
そしてなによりもれ速さが足りない!!

2行目のォ!!の認識ミス以外は問題なく認識している。分かりきっていたことですが、優秀ですね。 JSONで出力を取り出してみると"お前"と"そして"で認識位置のX座標はちゃんと字下げの分だけずれています。

ちなみにtesseract-ocr に同じ画像を認識させると、以下の結果。tess305は出力ファイルの接頭辞で、-psm 6は単一の段落とみなすオプション。

$ tesseract -l jpn test1.png tess305 -psm 6
Tesseract Open Source OCR Engine v3.05.00dev with Leptonica
Warning in pixReadMemPng: work-around: writing to a temp file

$ cat tess305.txt
お前に足りなぃものは…、 それは!! 橿艶思腿餌鵬気品優謄さ動勉さ囁
そしてなによりもォ= 速さが足りない=

開発バージョン(3.05-dev)、公式配布のjpn.traineddataです。

これまでの経験上、画像サイズが小さいと結果がイマイチです、Tesseract。

というか、そんなことを知りたかったわけではなくて。

第二水準、第三水準の漢字は対応してるのか、を知りたいので、次が本命

第二水準および第三水準の漢字

Tesseractは公式配布のデータを使う限り、第二水準と第三水準の漢字は一部しか認識できない *4

果たして、Google Cloud Vision API のText Detection(OCR)機能はどこまで対応しているのか、をざっくり調査。

参考:Tesseract-ocr における漢字の対応(収録)状況 - Qiita

テスト画像

Tesseract OCRが対応していない文字を中心に第二水準および第三水準の漢字を適当にピックアップ。 もちろんTesseract OCRは学習させることで対応できますので念のため。

f:id:atuyosi:20160901031214p:plain

741x684ピクセル。同じくPagesで適当に入力して、Cmd+Shift+4スクリーンショットを撮ったもの。

結果

字形が似ている
叱U+53F1 U+20B9F 叱咤激励 叱咤激励
第二水準漢字
倅.伜.悴 せがれ
弐萬円虞美人草「朕は国家なり」
檳榔(ビンロウ)、刀劍亂舞
鳳凰鳳鳳凰圈、圍
坩堝(るつぼ)、妲己(だっき)、骨嵬(くがい)
第三水準漢字
鄧小平(とうしょうへい) 、任俠(にんきょう) 、王嚞(オウテツ)
吐噶喇列島(とかられっとう)
(口之島,中之島,平島,諏訪之瀬島·悪石島,小宝島,宝島)

中黒(・)を認識できていなかったりする点を除けばかなりの善戦ぶり。熟語になっている漢字はきっちり認識している。

𠮟(U+20B9F)は認識できていないようです。認識結果から消滅するか、叱(U+53F1)と認識されている。文字サイズを大きくして改善するかどうか。

囗(くにがまえ)シリーズ(囹、圀、囿、圄、圉、圈、圍)はさすがに無理みたいですね(7文字中2文字は認識)。そもそも熟語を想像できない漢字なので問題はないでしょう。
は苗字に使われているので認識できた方がいいかもしれないですが。


第四水準漢字を試していませんが、少なくともパナソニックOCRソフトは対応してないようなので対応不要ではないでしょうか。機会があればやってみるのもアリですが、中国語と認識されそうな気がします。

参考:仕様 | 日本語・英語活字カラーOCRソフト「読取革命Ver.15」 | パナソニック ソリューションテクノロジー株式会社 | Panasonic

まとめ

Google Cloud Vision APIの優秀さを確認。内部のOCRエンジンの素性は不明ですが、第二水準、第三水準の漢字もよく使われるものは認識するようです。

画像サイズにもよるとは思いますが、日本語に関してはTesseract-ocrより認識可能な文字が多い上に高性能。GoogleAPIは当然、オフラインでは使えない点と、 APIの呼び出し回数で課金される*5という点がネックです。

ちゃんとプログラムを書いて文字の認識位置を考慮してやれば電子書籍の自炊にはうってつけかと思います。


画像サイズを変えて変化を見たいですが今日はここまで。

ひょっとしたら続きます。それでは。

スクライド Blu-ray BOX

スクライド Blu-ray BOX

*1:名称はgoogleauth

*2:たとえ1画像でもAnnotateImageRequestの配列にしてやる必要がある

*3:元ネタはお察しください

*4:(おそらくGoogleの)日本語コーパスの出現頻度の高い漢字を学習させているようなのでこれは仕方ない。

*5:率直に言って1000リクエストで2.5ドルぐらいだったはずなので格安