今日も微速転進

ここではないどこかへ

OCRと画像の回転

メモっとかないと間違いなく忘れそうなので大したネタでもないけど。

iOSでカメラから取り込んだ画像は撮影時の本体の向きが考慮された状態になっていない(メタデータとして向きの情報が記録されている)。

つまり、 iOSで読み込んだ画像をそのままOCRエンジンであるTesseract-OCRに渡してもダメで、撮影時の向きと画像の向きを合わせてやる必要がある。

基本的にやることは下記リンク先の通り(特にコメント欄の方)。

qiita.com

iOSアプリでは常識の部類なんだろうけど知らないと普通にハマる。

リンク先の通りfixOrientation()メソッドをUIImageクラスのエクステンションとして定義して、下記のようにする。

        let tesseract = G8Tesseract(language: "jpn")
        
        tesseract.delegate = self
        
        tesseract.image = image.fixOrientation()
        tesseract.recognize()
        
        let ocred_text =  tesseract.recognizedText

また、画像サイズの大きさに上限があるようなので、自作のアプリの場合は長辺の長い方が2048ピクセル以下になるように拡大縮小しています。

とりあえず備忘録。

OCRアプリをリリースしました。

f:id:atuyosi:20160311210923j:plain:w320

タイトルの通りOCRアプリをリリースしました。iPhone 5s以降がターゲットで、日本語と英語をサポート。

OCRエンジンの調整とか含めて去年の11月末ぐらいからダラダラと。〆切が無いというのは恐ろしいですね。

なぜ今更OCRアプリか?

有り体に言えば「そこに山があるからだ」みたいな動機ですが、強いてあげるなら、

  • OCR機能を組み込んだ(別の)アプリを作りたい
  • 自分が失明しかけたから

というところでしょうか。 まあ何というか、失明しかけたってのは大きいです。安価なOCRソリューションは必要でしょう。

その辺は過去記事を参照(その一その二

一応の売りは数字専用モードと台形補正。JIS第一水準漢字をほぼカバー。

アプリ制作において苦労したところ

  • ネーミング
  • アイコン
  • スクリーンショット(iTunes app store用)
  • Xcode全般(慣れの問題)

アイコンは、まあ、妥協しました。はい。 正直に言ってデザインはまわりは外注したいですね。

スクリーンショットは下記のページで紹介されているツールのお世話になりました。いやほんと圧倒的感謝。

iOSアプリのスクリーンショットとテキストを用意するだけでAppStoreに申請する画像を作成できるSketch用フレームワーク「Sketch to AppStore」が公開。

統合開発環境自体、あまし好きじゃないので慣れるまでのフラストレーションは結構ありました。慣れてしまえはどうということはないかな。

あとはこれも引っかかりました。マジ焦った。

突然アプリをアップできなくなった - Missing iOS Distribution signing identity forエラーの対応 - スマホアプリの作り方

その他もろもろ

レビュー期間とか

3/7の深夜(1:59にapp storeのReviewに提出。
3/10の深夜2:17にレビュー開始。
3/11の10:08に審査をを通過。

手動でポチッとボタンをクリックしてリリース。”Ready for Sale.”の通知メールが来たのが3月11日16:18。

めでたしめでたし。

使用しているライブラリ

言語はもちろんSwift。 UIは最後の最後までグダグダで、最終的に最初の画面でモードとか読み取り対象言語を選んで画像を選ぶとOCR開始という形式に落ち着きました。 最後の最後でEurekaを採用。ややトリッキーな外観に。

OCRエンジン:
GitHub - gali8/Tesseract-OCR-iOS: Tesseract OCR iOS is a Framework for iOS7+, compiled also for armv7s and arm64.

入力フォーム:
GitHub - xmartlabs/Eureka: Elegant iOS form builder in Swift

進捗表示のプログレスバーを出す:
GitHub - jdg/MBProgressHUD: MBProgressHUD + Customizations

内部DB:
Realm: Create reactive mobile apps in a fraction of the time

広告:
Get Started  |  AdMob for iOS  |  Google Developers

仮想敵とか

スタンドアロン系だとClip○CRあたりが直接の競合アプリですかね。

“XCode Ghost"とか引っかかってるようなアプリはインストールすら嫌なんでまともに調べていませんが。

人力OCRの名刺アプリとかそういうのはどうしようもないので勘弁して下さい。

感想とか

スクリーンショット内の文字列が開発コードネームのままやんけ…orz。スクリーショット揃えるのに必死で気づいてないやん。

個人でモノ作るというのは実にフリーダムで、コンセプトを決めるのも自分自身で、妥協するのも自分。 100%自分の意見が通る、というのは非常に自分好みでいいと思っています。

当然というかやはりというか、問題は一気呵成にいかないと無限にずるずるいってしまうというところで、まあ一番の問題点はそこかと。 ただ画像を読み込んでOCRするという部分は一週間ぐらいでできていたにもかかわらずそのあとが数ヶ月かかっているので。

まさに最近読んだ某社のブログある通りかと。

短期決戦で決めろというのは重要だと思います。。さながら孫子の兵法、「兵は拙速を聞く」そのもの。

何はともあれ比較的まっとうなアプリをリリースしたという実績、これが一番欲しかった。

次のバージョンアップあたりでいわゆるAppExtentionに対応させて画像編集系のアプリから呼び出せるようにしたいというのが次の目標。 あと背景色とか文字色とか。透明テキスト付きのPDF生成とかも将来的にはなんとかしたい。

さて、いい加減本命の方を頑張りましょうか。

なんとか今月中にレビューに提出しましょうってことで。


……こちらからは以上です。

Xcode 7.0 + Swift2 でTesseract-OCR-iOSを使う(追記あり)

過去記事のXcode 7対応版です。

※実機で動かす場合の注意を末尾に追加。

a244.hateblo.jp

cocoapods で環境構築。前提はXcode 7.0.1、Swift 2。

新規プロジェクトを作ることを前提にします。

Podfile の作成

注意点としては、

  • 確実にXcodeを終了しておく
  • デフォルトでインストールされているrubyを使う

cocoapods 側はOS標準のrubyを使うことを推奨していたはずなので。

プロジェクトのルートフォルダへ移動し、Xcodeを終了させておく。

pod init

Podfileを編集する。2行目、4行目のコメントを外す。platformのiosバージョンはサポート対象に合わせて変更。 Tesseract-OCR-iOSの安定板(4.0.0)ではうまくビルドできないので、開発版を用いる。 逆に言うと、Swift 1.2とXcode 6.3の組み合わせなら安定板で良い。

# Uncomment this line to define a global platform for your project
 platform :ios,'8.0'
# Uncomment this line if you're using Swift
 use_frameworks!

target 'MyOCR' do
  pod 'TesseractOCRiOS', :git => 'https://github.com/gali8/Tesseract-OCR-iOS.git', :branch => 'master'
end

target 'MyOCRTests' do

end

target 'MyOCRUITests' do

end


みんな書いてるけど、BridgingHeaderはいらない。

import TesseractOCR

とすれば問題なく動作する。初回のコンパイルが通るまでは警告が出るかもしれないが、一回Frameworkのビルドが完了すれば出なくなる。

Xcode側の設定

Workspaceを開く

アプリ名.xcworkspaceというフォルダができているはずなので、openコマンドで開けばいい。

libz.tbdを組み込む

f:id:atuyosi:20151013000552j:plain

公式ドキュメントにはlibz.dylibを追加しろと書いてあるが、Xcode 7からdylibではなくtbdというファイルを介して読み込むようになった模様

なので素直にlibz.tbdを追加する。

  1. Project NavigatorからPods というプロジェクトを選択し、TesseractOCRiOSというターゲットをクリックする。
  2. 画面の下の方に"Linked Frameworks and Libraries"というカテゴリがあるので、下部の”+”アイコンをクリックする。
  3. ダイアログが表示されるので検索ボックスにlibzと入力して絞り込む。
  4. lib.tbdが表示されるはずなので、これを選択、”Add”をクリックする。

f:id:atuyosi:20151012234252p:plain

tessdataのインポート

必要な言語のlang.traineddataを用意する。 日本語の言語データについては冒頭で参照している過去のエントリも参考にしてください。

  1. 適当な場所にtessdataというフォルダを作り、Tesseract-ocrの言語データを展開しておく。
  2. Finderでtessdataのあるフォルダを表示しておく。
  3. FinderのウィンドウからtessdataフォルダをXcodeのプロジェクトの直下または対象アプリのターゲット直下にドラッグアンドドロップする。

    f:id:atuyosi:20151013001011j:plain

  4. ポップアップが表示されるので”Copy if needed”にチェックを入れ、"Folder References"を作る。

    f:id:atuyosi:20151012235204p:plain

  5. 最終的にこんな感じで青色のフォルダができていれOK。中身はjpn.traineddataとか各種言語データ。

    f:id:atuyosi:20151012234957p:plain

サンプルコード(他力本願で)

下記にちょうどいいサンプルがあるので参考にする。というか、コピペしてちょっと修正するだけでひとまず動くはず。他力本願ですいません。

qiita.com

必要な作業は

  • 文字の入った画像ファイルを用意する
  • ViewController.swiftを修正
    • import TesseractOCRの追加
    • printlnprint文にする
  • 上記サンプルだと一箇所警告が出るので気になる場合はvar tesseract =という箇所をlet tesseract = にすればいい。

デバッグログにOCR結果が出力されるはず。

[2015/10/15] 追記

実機の場合は、プロジェクトナビゲーターから[Build Settings] -> [Build Options] の"Enable Bitcode" を"No"にしないとリンカがエラーを吐きます。 Podsプロジェクト内のTesseractOCRiOSターゲット、並びにアプリ側の両方で設定する必要あり。

参考URL


P.S. 気分転換にブログテーマを変えてます。あしからず。

tesseract-ocr 3.04のインストール(macOS/OSX)※追記あり

今日もtesseract-ocrネタです。当面はブログのネタに困らないように思われます。

[2015/08/28 追記] tesseract-ocrRuby 用のラッパー(ruby-tesseract-ocr)はまだ3.04に対応していないようです。 Ruby経由でtesseract-ocrを使用している場合は、アップグレードしないほうが無難です。 もしくはGoogle Driveより3.03(rc)をダウンロードしてインストールするのが良いかと思います。下記と同じ要領でインストール可能。

Homebrewでも最新のtesseract-ocr 3.04 がインストールできるようになっています。 しかしながら、肝心のcombine_tessdataコマンドを始めとする言語データ(language data)を扱うコマンドがインストールされません。

そこで、MacOSX (Yosemite) にtesseract-ocrソースコードからインストールする手順をメモしておきます。

前提

MacOSX 10.10.5 (Yosemite)、Homebrew のセットアップは完了していることが前提です。

Homebrew ではインストールされないtesseract-ocr の付属コマンドは以下のとおり。

  • text2image
  • unicharset_extractor
  • set_unicharset_properties
  • shapeclustering
  • mftraining
  • cntraining
  • wordlist2dawg
  • dawg2wordlist
  • combine_tessdata

インストール

GitHub からソースコードをダウンロードします。"Source code (tar.gz)"をクリックします。

Releases · tesseract-ocr/tesseract · GitHub

準備

必要なライブラリをインストールします。3.03から新しく追加されたtext2imageコマンド*1の関係で、依存ライブラリが増えています。

$ brew install cairo pango
$ brew install leptonica
$ brew install icu4c

icu4c のインストール後に下記のメッセージが表示されますので、メモしておきます。

This formula is keg-only, which means it was not symlinked into /usr/local.

OS X provides libicucore.dylib (but nothing else).

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/icu4c/lib
    CPPFLAGS: -I/usr/local/opt/icu4c/include

理由は不明ですが、Homebrew経由でicu4cをインストールしても/usr/local/includeへのリンクが作成されないということのようです。 上記の環境変数をセットしてコンパイルするか、コンパイルする前に下記のコマンドを実行しておきます。

$ brew link icu4c --force

コンパイルしてインストール

tarアーカイブを展開。

$ tar zxf tar zxf tesseract-3.04.00.tar.gz
$ cd tesseract-3.04.00

あとは基本的にconfigure してmakeすればいいだけです。

$ ./configure LDFLAGS=-L/usr/local/opt/icu4c/lib CPPFLAGS=-I/usr/local/opt/icu4c/include

問題がなければ下記のようなメッセージが出力されるはず。特に後半のTraining tools...が出力されていない場合は何かライブラリが不足しています。

Configuration is done.
You can now build and install tesseract by running:

$ make
$ sudo make install

Training tools can be build and installed (after building of tesseract) with:

$ make training
$ sudo make training-install

素直に上記のコマンドを入力すればOKです。

$ make 
<skip>
$ sudo make install
<skip>
$ make training
<skip>
$ sudo make training-install

sudoコマンドはログインしているユーザのパスワード入力を要求するので念のため*2

アンインストールする際に必要なので、展開したソース一式はどこか適当な場所に残しておくことをおすすめします。(念のために記載しておくと、アンインストール手順は、上記のディレクトリで、sudo make uninstall とすれば一部コマンドを除いて削除されます*3。)

必要なコマンドが/usr/local 配下の各ディレクトリにインストールされます。

言語データ

tesseract-ocr/tessdata · GitHubから必要な言語データを取得します。 英語、日本語のOCRであれば以下の3つあれば十分かと。

  • eng.eng.traineddata
  • jpn.traineddata
  • osd.traineddata

git cloneすると遅いので、右側の「Download ZIP」で一括取得してごっそり放り込んでもいいかと思います。

言語データを展開して/usr/local/share/tessdata にコピーすれば完了です。

日本語の言語データ(jpn.traineddata)は若干問題があるようなので、下記を参考にjpn.unicharambigsというファイルを修正してください。

a244.hateblo.jp

動作確認

まずは利用可能な言語を確認します。

$ tesseract --list-langs
List of available languages (3):
eng
jpn
osd

また、3.03からパラメータの一覧を取得するオプションが追加されています。

$ tesseract --print-parameters

また、出力も従来からのテキスト、HTMLに加えてpdf形式が追加されています。

基本的な構文は、

$ tesseract <input image > <basename> <option> <config>

です。出力ファイルの拡張子は不要です。とりあえずOCRさせたいのであれば、

$ tesseract input.png output -l jpn

のように-l オプションで対象言語を3文字のアルファベットで指定します。出力はoutputo.txt。対応する画像フォーマットはLeptonicaという画像処理ライブラリのコンパイルオプション次第ですが、一般的なJPEGPNGTIFFBMP、PBMは問題無し。ただしGIFは不可。

例えば下記のようにすると、読み取った文字列がoutput.txt およびoutput.pdfに出力されます。output.pdfは画像+透明テキストというPDFファイルになります。

$ tesseract image.png output -l jpn pdf

同じ要領で、

$ tesseract image.png output -l jpn hocr

とするとHTML形式で出力されます。

他に有用なオプションは-psm--user-wordsでしょうか。前者はページ内のレイアウトのヒントを、後者は単語リストを指定できます。 主なオプションはtesseract -hで確認できます。

その他

ソースコードを展開したディレクトリのtrainng配下に新しいフォント、言語を学習させるための自動化スクリプトがあります。


それでは。

*1:指定されたフォントで学習用の画像とboxファイルを生成するコマンド

*2:想定している読者には完全に余計なお世話でしょうけど何となく

*3:冒頭に挙げたコマンドは削除されないので手で削除されたし

Tesseract-OCR-iOSと言語データ(jpn.traineddata)

[2015/08/25 20:37] タイトルを修正しました。
懲りずにtesseractネタです。まだまだ続きます。

今回はiOSアプリでtesseract-ocr を使うためのラッパーライブラリ、Tesseract-OCR-iOSについて。

github.com

導入(for Swift)

GitHubにあるテンプレートプロジェクトを使うのも一つの方法ですが、CocoaPodsを利用して導入します。

もう8月下旬ですが、Xcode 6.3、Tesseract-OCR-iOSは4.0*1を前提にしてます。

事前準備として対象言語の言語データをダウンロードしておく必要があります(後述)。

  1. Xcodeで新規プロジェクト作成
  2. Xcodeを終了する
  3. ターミナルで作成したプロジェクトの存在するディレクトリへ
  4. Podfileを作成する(下記参照)
  5. ターミナルでpod installを実行
  6. ”プロジェクト名".xcworkspace が作成されるので、Xcodeで開く
  7. 言語データ(language data)を"tessdata"フォルダごとXcodeのファイルナビゲータへドラッグ(Create Folder Reference)

Podfile はこんな感じで。use_frameworks!と入れておけばBridgingHeaderは不要です。

platform :ios, '8.0'
use_frameworks!

pod 'TesseractOCRiOS', '~> 4.0.0'

参考:Installation · gali8/Tesseract-OCR-iOS Wiki · GitHub

注意点

  • Xcode を確実に終了しておくこと
  • tessdata フォルダはsymbolic group ではなく、 Referenced Folderである必要がある

上記リンク先のようにフォルダのアイコンが青色になっていればOK。

f:id:atuyosi:20150825032132p:plain:w600

f:id:atuyosi:20150825032141p:plain

サンプルコードはにあります。

var tesseract:G8Tesseract = G8Tesseract(language:"eng+ita");

という箇所を、

var tesseract:G8Tesseract = G8Tesseract(language:"jpn");

にすれば日本語のOCRができるはず。

文字の方向を自動判別させたいなら、

tesseract.pageSegmentationMode = G8PageSegmentationMode.AutoOSD

のようにpageSegmentationMode を設定します。tesseract-ocr-3.01.osd.tar.gz

縦書き文書の読み取りを行わない場合は、以下のようにすれば段組の有無を含めてよきに計らってくれるようです。

tesseract.pageSegmentationMode = G8PageSegmentationMode.Auto

縦書き文書(段組なし)であれば、

tesseract.pageSegmentationMode = G8PageSegmentationMode.SingleBlockVertText

あとはXcodeの入力補完機能で確認してください。

言語データについて

現在のTesseract-OCR-iOS v4.0は本家tesseract-ocrの3.03がベースです(本家の最新バージョンは3.04.1)。本来ならバージョン3.03用に作成された言語別のデータを利用するのが望ましいですが、3.03用のデータはリリースされていないようなので、3.02用のデータを流用するか、3.04用のデータを修正して使用します。3.04用のデータを修正して使う方が日本語に関しては認識率は向上します。

なお、設定パラメータが増えている関係で、3.04向けのデータをそのまま使うとエラーで落ちます。

ver. 3.02 用のデータを使う

[2016/08/01 追記]

Google Codeのサービス終了及び移行期間の終了により、下記のリンク先からは入手できなくなっています。tesseract-ocr alternative downloadから該当ファイルを入手するか、後述の手順でGitHubで配布されているデータを改造してください。

Downloads - tesseract-ocr - An OCR Engine that was developed at HP Labs between 1985 and 1995... and now at Google. - Google Project Hosting

最低でもtesseract-ocr-3.02.eng.tar.gzという英語用のファイルが必要です。文字の方向を判別させたいなら tesseract-ocr-3.01.osd.tar.gzも追加で。

tesseract-ocr alternativeの方だと以下のファイルです。


Google Codeのサービス終了に関してはリンク先を参照。

ver. 3.04用のデータを使う(GitHubで配布されているファイル)

ケースバイケースかと思いますが、より日本語の認識精度を向上させたいのであれば、GitHub にあるtesseract-ocr 3.04用の言語データを一部改変するのが有効です。単語辞書の強化とparams-modelなるファイルが追加されているためか、スキャナで読み込んだ画像で試した範囲では改善しています。

tesseract-ocr/tessdata · GitHub

必要なのはjpn.traineddata のみです。GitHub で配布されているjpn.traineddataとそのまま使用すると下記のエラーでアプリが一発で落ちます。

read_params_file: parameter not found: allow_blob_division

設定項目が追加されていることが原因です。なので、jpn.traineddataファイルから一旦、jpn.configというファイルを抜き取り、修正して差し替えます。 この場合、tesseract-ocr 付属のcombine_tessdataが必要です。

カレントディレクトリの、tessdata配下にjpn.traineddataファイルが存在するものとします。環境に合わせてパスを修正してください。

$ combine_tessdata -e tessdata/jpn.traineddata jpn.config

エディタでjpn.config を開き、46行目をコメントアウトします。

# allow_blob_division        F

修正した設定ファイルで元のファイルを置き換えます。

$ combine_tessdata -o tessdata/jpn.traineddata jpn.config

これで上記のエラーは回避できるはず。

日本語に関しては、概ね3.04用の言語データの方が認識率が良いですが、jpn.unicharambigsというファイルに若干問題があります。少なくともアルファベットの"l"や数字の"1"を長音(ー)に変換してしまうようなので、サクッと修正します(過去のエントリにも書いていますが)。

まずはファイルを抜き取ります。

$ combine_tessdata -e tessdata/jpn.traineddata jpn.unicharambigs

20-26行目を修正。右端の"1"を”2”に修正するだけ。他にもきになるところがあれば修正。タブ区切りのフォーマットで、第1列と第3列はそれぞれ置換前、置換後の文字数です。第2列が置換前、第4列が置換後の文字に対応します。第5列の数字が"1"なら必ず置換し、"2"ならば単語辞書に存在するかをチェックして判断、です。第5列の値は"3"も同じような意味だと思いますが、違いは分かりません*2


jpn.unicharambigs 20-26行目

1    l   1   ー 2
1   | 1   ー 2
1   I   1   ー 2
1   1   1   ー 2
1   |   1   ー 2
1   O   1   。 2
1   °  1   。 2

修正前のオリジナルファイル:langdata/jpn.unicharambigs at master · tesseract-ocr/langdata · GitHub


[2015/08/27 追記]

jpn.unicharambigsの52行目も修正が必要です。アルファベットの小文字の"o"が句点に変換されていまいます。例えば"google"という文字列が、"g。。gle" に変換されてしまいます。これは良くないので、第5列の値を"1" から"2"に変更します。


jpn.unicharambigs 52行目

1   o   1   。  2

追記ここまで


書き戻します。

$ combine_tessdata -o tessdata/jpn.traineddata jpn.unicharambigs

jpn.traineddata のソース一式はtesseract-ocr/langdata · GitHubにあります。

下記のエントリに理解できた範囲で書いてます。

a244.hateblo.jp

今日はここまで。

*1:v3.4とは一部APIが変更されているようです

*2:ご存知でしたらコメント下さい

広告