財務省の公開した交渉記録PDFをいじる その1(目次のPDF編)
自分でモロに忘れそうなので備忘録として。
一時ファイルがじわじわと増殖するのでもっとスマートに行きたいところです。
作戦というか方針
まずは目次のPDFファイルから。
- 目次のPDFから交渉記録(応接記録)を機械可読(Computer Readable)な形式に変換
- マスク無しのPDFを画像化、再度PDFに変換して過去記事で紹介したAPIでOCR
- 目次のページ番号から必要なページを割り出して、OCR結果を分割、どうにして添付資料のページを除去
- どうにかしてMarkdown化
- 静的ページジェネレーターでWebページ化
この記事では「1. 」の部分。
問題は黒塗り部分。特定の操作で外せるのはいいけど、外してからOCRして明らかにやばい部分だけ伏せ字にする?
とりあえずやっていきます。
データの入手
財務省のWebサイトから、といいたいところですがそこはやはりWebアーカイブから黒塗りの外せる方を。
- 20180523p-1.pdf
- 20180523p-2.pdf
- 20180523p-3.pdf
- 20180523p-4.pdf
目次のOCR処理
目次のデータは素直に財務省のページから。
20180523p-0.pdf
というファイルです。
目次ファイル
一応、目次のPDFファイルについてもGoogle Cloud Vision OCRでOCRしてみました。残念ながら罫線が邪魔なのか、OCR結果がいまいち。通し番号の列が認識できていない。また、右端のページ番号も認識に失敗している。
水平方向の行を列ごとに細切れにされて出力されて扱いにくい。
Web APIでいくならMicrosoftのAPIの法が良いかも。画像を切り出してTesseractでOCRしてみます。
このファイル、不思議なことに各ページが横に長い短冊状の画像が縦に37個結合したPDFになっていて理解不能。 何これ一体?
ファイルサイズを小さくしたかったの?
何はともあれ、表の罫線があるとGoogleのOCR API、Tesseract両者とも結果がイマイチであるという点を考慮し、画像をぶった切ってTesseractでOCRする方向で。
本気で行くなら罫線と文字は接触していないので、ハフ変換で直線検出してやればいいのかな。
ちなみに"OpenCV line remove"でググると結構ヒットする。
罫線(水平線)の除去についてはLeptonicaによるサンプルがあります。
Removing dark lines from a light pencil drawing — Leptonica Documentation v1.68 documentation
画像の切り出し
まず目次のPDFから各ページを画像に変換。
$ mutool draw -o "index_page_%d.png" -r 300 pdf_masked/20180523p-0.pdf
-o
で出力ファイルを指定。%d
はページ番号が入ります。
GUIでやってもいいですが、表紙を除いた合計8ページから日付の列とページ番号の列を切り出せばよいのでコマンドで。
300dpiで画像化した場合、3ページ目以降は表の上端までの距離が概ね150ピクセル、表の見出しを含めると250ピクセルぐらい。
ものすごくざっくり欲しい列の位置を図で示しておく*1。
カラープロファイルを指定しないと下記のエラーが出るので、+profile "icc"
オプションを追加。-noise
オプションでノイズ除去。
convert: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `output2_1.png' @ warning/png.c/MagickPNGWarningHandler/1744.
参考:ImageMagick で PNG の形式を変換 - awm-Tech
左側の日付の列を切り出す。
$ convert masked/index_page_2.png +profile "icc" -noise 4 -crop "480x2980+500+410" output2_1.png
同じように右側の列。
$ convert masked/index_page_2.png +profile "icc" -noise 4 -crop "180x2980+2000+410" output2_2.png
-crop
オプションの引数は、切り抜くサイズ(横、縦)とx座標のオフセット、y座標のオフセット。
理想を言えば罫線を除去したいところだがまあ妥協。
3ページ目以降。
$ convert masked/index_page_3.png +profile "icc" -noise 4 -crop "480x3100+500+280" output3_1.png $ convert masked/index_page_3.png +profile "icc" -noise 4 -crop "180x3100+2000+280" output3_2.png
もう少し範囲を絞って縦の罫線をきっちり除去すべきだったか。
- 作者: クーガー株式会社,石井敦
- 出版社/メーカー: インプレス
- 発売日: 2008/11/28
- メディア: 大型本
- 購入: 4人 クリック: 89回
- この商品を含むブログ (8件) を見る
ImageMagickの日本語の本、あったのか(絶版)。
Tesseract 4.x
ビルドに必要なライブラリのインストール。
$ brew install --only-dependencies tesseract
最新版をソースからビルドしようかと一瞬だけ思いましたが、地味に面倒なので中途半端ですがHomebrew経由で最新版を。要するに4.x系でやりたかったというだけです。
Tesseract本体(開発版)。
$ brew install tesseract --HEAD
学習用のツールはインストールせず。
現状のHomebrewパッケージの場合、--HEAD
オプションを付けると全言語の言語別データをダウンロードする。その際、ダウンロードされるのは以下のリポジトリのデータとなるので注意。
現状、tessdata
は無印(3.0x用のデータを含む)、tessdata_fast
、tessdata_best
の3系統。
なお、Tesseract tessdata downloaderという補助ツールも提供されている。
4.x系向けのデータはeng
とかjpn
のデータと、script(書字系?)別のデータ(EnglishとかJapaneseとか)で2種類ある。
- tesseract-ocr/tessdata_fast: Fast integer versions of trained models
- tessdata_fast/script at master · tesseract-ocr/tessdata_fast
現状、Japanese.traineddata
などscript
フォルダ直下のデータはそのままでは読み込まれないので、tessdata
フォルダにコピーするかシンボリックリンクを作成する必要がるので注意。
今回の画像データで試した範囲ではjpn..traineddata
で十分かな。Japanese.traineddata
では半角数字の前後で余計な空白が入る。
目次のOCR
$ tesseract output2_1.png ocr_text -l jpn
引数は、
tesseract 画像ファイル 出力ファイルの接頭辞 オプション
出力ファイル名にstdout
を指定すると標準出力(つまりコンソール画面)に結果を出力する。
認識結果の例
$ tesseract output2_1.png stdout -l jpn --psm 6 Warning. Invalid resolution 0 dpi. Using 70 instead. 平成25年6月28日 平成25年7月8日 平成25年7月25日 平成25年8月1日 平成25年8月13日 平成25年8月21日 平成25年9月2日 平成25年9月12日 平成25年10月4日 平成25年10月24日 平成25年10月27日 平成25年10月30日 平成25年11月4日 平成25年11月19日 平成26年12月16日 平成25年12月26日 平成25年12月27日 平成26年1月9日 平成26年1月27日 平成26年1月28日 平成26年1月31日 平成26年2月3日 平成26年2月13日 平成26年3月4日 平成26年3月6日 平成26年3月2日 平成26年4月15日
大変結構。
$ tesseract output2_2.png stdout -l jpn --psm 6 --oem 3 Warning. Invalid resolution 0 dpi. Using 70 instead. ] 18 19 19 22 24 26 27 35 36 42 44 46 47 50 53 55 56 63 64 73 75 77 78 81 84 87
数字の"1"の認識ミスは許容範囲内。
--psm (page segmentation mode)
の値によっては最初の”1"を取りこぼすか、余計な空行が入ったりする。古いバージョンのTesseractのほうが数字の認識に関しては優秀だろうと思う。面倒なので試していない。
やはり面倒なのでスクリプトで一括。
#! /usr/local/bin/bash convert masked/index_page_2.png +profile "icc" -noise 4 -crop "480x2980+500+410" cropped_2_1.png convert masked/index_page_2.png +profile "icc" -noise 4 -crop "180x2980+2000+410" cropped_2_2.png for i in `seq 3 9` ; do convert masked/index_page_${i}.png +profile "icc" -noise 4 -crop "480x3100+500+280" cropped_${i}_1.png convert masked/index_page_${i}.png +profile "icc" -noise 4 -crop "180x3100+2000+280" cropped_${i}_2.png done for j in `seq 2 9`; do echo "first ${j}" tesseract cropped_${j}_1.png ocr_text_${j}_1 -l jpn --psm 6 echo "2nd ${j}" tesseract cropped_${j}_2.png ocr_text_${j}_2 -l jpn --psm 6 done
認識ミスは以下の通り。
- 1ページ目 数字の"1"の認識ミス
- 3ページ目 「平成26年6月17晶」。末尾の「日」を認識できず。
- 4ページ目 末尾の「日」の認識ミス。余計な文字「|」
- 5ページ目 末尾に余計な文字「409 .」
- 6ページ目 余計な文字「征」「 .」。末尾の「日」の認識ミス。
- 7ページ目 余計な文字「|」
- 8ページ目。なぜか"810"が脱落。
あとは「日」が「昌」になったり「目」になっている箇所がいくつか。画像を拡大する処理が必要だったかな。
まあ手作業で修正できる範囲です。
末尾に^L
(Form Feed: \f
)がくっついているので後で除去する。
OCR結果のテキストファイルの結合
結合するファイル同士の行数が同じであるという前提で、paste
コマンドを使う。
#! /usr/local/bin/bash for j in `seq 2 9`; do echo "target ${j}" paste ocr_text_${j}_1.txt ocr_text_${j}_2.txt >> ocr_result_${j}.tsv done
前述の邪魔な^L
を除去する。
$ cat $(ls *.tsv) | tr -d '\f' | sed '/^[[:blank:]]*$/d' > page_list.tsv
参考:Linux パターン別ファイルの空行削除(除外)方法 | 俺的備忘録 〜なんかいろいろ〜
完成品:財務省の公開した国有地の取引に関する交渉記録の目次PDFから抜き出した日付とページ番号の対応表(2018年5月)
※ 不備があったので更新しています。
まとめ
とりあえず目次データをTSV化するところまで。
Tesseractのドキュメント構造解析処理がアレなのはともく、GoogleのAPIも罫線入りの表が苦手だとはさすがに意外。
Cloud Vision APIの方は"TEXT_DETECTION"の方を試すのもありかもしれないですがそれはまた別の機会に。
次は本文データ(OCR済み)に挑みます。
続きます。
詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識
- 作者: Gary Bradski,Adrian Kaehler,松田晃一,小沼千絵,永田雅人,花形理
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/05/26
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: 上田隆一
- 出版社/メーカー: 技術評論社
- 発売日: 2015/05/15
- メディア: Kindle版
- この商品を含むブログを見る
*1:いかにもやっつけ仕事
Tesseract OCR 3.05 のインストールと新機能
2月16日付でオープンソースのOCRエンジンである Tesseract OCR の3.05がリリースされています。
2月中に記事にしようと思いつつ結局3月になってしまいました。
Ubuntu 17.04 の Feature Freeze に間に合わせたいという要望が出た結果、唐突にリリースされたようです*1。
実際のところ、Ubuntu 17.04 に採用されるのかどうかは不明です。
変更点
ざっくりいうと一番のメインはTSV出力。あとは諸々のバグ修正。HTML形式の出力*2についても改善しているようです。あとはバグ対応など。
以下、リリースノートからのざっくり訳。
- hOCR 出力 における改善(微調整)
- 新しい出力オプションとしてTSVを追加
- バージョン 3.04.00における
AnalyseLayout()
メソッドのABI非互換を修正 - text2image tool : すべてのOpenType リガチャが有効に(この機能にはPango 1.38以降が必要)
- Training tools :
assert
関数をtprintf()
とexit(1)
に置き換え - Cygwin 環境における互換性問題を修正
- マルチページのTIFFファイル処理の改善
- 埋め込みpdfフォントについての改善 (pdf.ttf)
- コマンドラインからOCRエンジンモード指定するオプションを追加(
--oem
オプションの追加)) tesseract
コマンドの、オプション指定形式を ‘-psm’ から ‘–psm’ (ハイフン2つ)に変更- 新しいC APIの追加と古いAPIの削除( for orientation and script detection )
- ビルドに必要なautoconf のバージョンを 2.59 に変更
- 不要なコードの削除
- 多数のコンパイラの警告に対処
- メモリリークおよびリソースリーク*3を修正
- ‘Cube’ OCR エンジンのバグ修正
- openCL 関連のバグを修正
- CMake によるビルドに対応
- Windows環境向けに CPPAN supportを追加
オプションの指定方法ですが、従来と同じく-psm
でもエラーにはなりません。将来的には--psm
のようにハイフン2つに移行するはず。
また、--psm
オプション*4に指定できる値が追加されています(詳細はtesseract -h
で確認)。
text2image
コマンドのmac環境におけるバグは修正されたかと思いきや、4系からのバックポートの余波でリグレッションしているので要注意*5。
各種ラッパーの対応状況
すんなり対応したのはJava/Android 系ぐらいで全然進んでいないようです。TSV出力を使わないのであれば、tesseract
コマンドを呼び出すタイプのライブラリは普通に動くと思います。
新機能
新機能であるTSV出力を試してみます。認識結果をタブ区切りテキストとして出力する機能という認識です。普通の文書よりは表とか本の目次のような画像データ向き。
$ tesseract -v tesseract 3.05.00 leptonica-1.74.1 libjpeg 8d : libpng 1.6.28 : libtiff 4.0.7 : zlib 1.2.8
手頃な画像が見つからないので適当な画像で試します。
電子書籍版の『[改訂第7版]LaTeX2ε美文書作成入門』のp.225の表の一部を切り抜いたもの(実際は幅640pxに拡大)。
実際にtesseract
コマンドで試すには、コマンドラインの末尾にtsv
を追加して実行。
$ tesseract -l eng resize_table.tiff stdout tsv 2> /dev/null level page_num block_num par_num line_num word_num left top width height conf text 1 1 0 0 0 0 0 0 640 146 -1 2 1 1 0 0 0 55 11 30 119 -1 3 1 1 1 0 0 55 11 30 119 -1 4 1 1 1 1 0 55 11 30 16 -1 5 1 1 1 1 1 55 11 30 16 79 pbk 4 1 1 1 2 0 55 45 30 16 -1 5 1 1 1 2 1 55 45 30 16 79 pbk 4 1 1 1 3 0 55 79 30 17 -1 5 1 1 1 3 1 55 79 30 17 78 phk 4 1 1 1 4 0 55 113 30 17 -1 5 1 1 1 4 1 55 113 30 17 79 pbk 2 1 2 0 0 0 220 45 18 12 -1 3 1 2 1 0 0 220 45 18 12 -1 4 1 2 1 1 0 220 45 18 12 -1 5 1 2 1 1 1 220 45 18 12 66 it 2 1 3 0 0 0 220 113 18 12 -1 3 1 3 1 0 0 220 113 18 12 -1 4 1 3 1 1 0 220 113 18 12 -1 5 1 3 1 1 1 220 113 18 12 79 it 2 1 4 0 0 0 303 8 209 118 -1 3 1 4 1 0 0 303 8 209 118 -1 4 1 4 1 1 0 303 8 147 20 -1 5 1 4 1 1 1 303 8 97 15 78 Bookman— 5 1 4 1 1 2 402 8 48 20 74 Light 4 1 4 1 2 0 303 43 186 18 -1 5 1 4 1 2 1 303 43 186 18 75 Bookman—Lighfltalic 4 1 4 1 3 0 303 76 155 15 -1 5 1 4 1 3 1 303 76 155 15 67 Baum-Dem! 4 1 4 1 4 0 303 110 209 16 -1 5 1 4 1 4 1 303 110 209 16 72 Boahmul-Dzmfltaflc
ちょっと認識ミスト取りこぼしが発生してますが、一列目の一行目のセルから順に出力されています(最後の列が認識したテキスト)。 拡大倍率としきい値処理をちゃんとやればちゃんと認識してくれるはずですが、とりあえず確かこんな感じだったはず。
それぞれの列ですが、level
とpar_num
というのはよくわかりませんが、ヘッダのconf
は確からしさ、あとはそのまま。
TSV出力させるために必要なのはtessedit_create_tsv
というパラメータなので、さらに挙動をコントロールすることも可能です。
上記のコマンドラインで指定しているtsv
の実態は、tessdata/configs
ディレクトリ配下にあるtsv
という設定ファイルです。
$ cat /usr/local/share/tessdata/configs/tsv tessedit_create_tsv 1 tessedit_pageseg_mode 1
ある程度複雑なレイアウトの画像からテキストを認識する場合に有効だと思います。
各種OS向けパッケージ
Linux
Arch Linux はすでにパッケージが提供されています。
githubのリリースページで配布されているアーカイブは以前と異なり、configure
スクリプトが含まれないので./autogen.sh
を実行する必要がある点に注意。もしくはcmake
を使うことも可能。
Ubuntu 17.04 に採用されるのかと思いきや、17.04 Beta 1 の時点では3.04系のままのようです。
Arch Linux
記憶違いでなければ新バージョンリリースの翌日だか翌々日にはパッケージが提供されていたはず。
$ sudo paceman -S tesseract $ sudo paceman -S tesseract-data-{eng,jpn}
他の言語についてはpacman -Ss tesseract-data
で検索してインストール。なお、向き判定のosd.traineddata
ファイルは(Arch Linux のパッケージの場合)、本体と一緒に/usr/share/tessdata
にインストールされる。
Ubuntu 16.04
バイナリパッケージは提供されていないのでソースからインストール。 Leptonica についてはバージョン 1.74系が必要です。
まずは必要なライブラリを一式インストールする。
sudo apt install autoconf automake libtool sudo apt install autoconf-archive sudo apt install pkg-config sudo apt install libpng12-dev sudo apt install libjpeg8-dev sudo apt install libtiff5-dev sudo apt install zlib1g-dev sudo apt install libleptonica-dev
学習用のツールが必要なら下記もインストールしておく。
sudo apt install libicu-dev sudo apt install libpango1.0-dev sudo apt install libcairo2-dev
せっかくなのでcmake
を使いたいところだが、CMakeLists.txt
というファイルにinstall
ターゲット用の記述がないのでmake install
できない……。
Leptonica のインストール
Ubuntu 17.04用のパッケージをビルドし直すのもありかもしれないが、上書きしてほしくはないのでソースコードからビルドする。
Releases · DanBloomberg/leptonica · GitHub
$ tar zxf leptonica-1.74.1.tar.gz $ cd leptonica-1.74.1/
ソースアーカイブを展開すると、`autobuild`というスクリプトがあるのでまずこいつを実行。
$ ./autobuild $ ./configure $ make -j2 $ sudo make install $ sudo ldconfig
/usr/local
配下にインストールされるはず。
Tesseract のインストール
$ tar zxf tesseract-3.05.00.tar.gz $ cd tesseract-3.05.00.tar.gz
以前は不要だったような気がするが、./autogen.sh
を実行してconfigure
スクリプトを生成。
$ ./autogen.sh $ LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure --with-training-tools $ make $ sudo make install $ sudo ldconfig
学習用のツールが不要な場合はconfigure
スクリプトの、--with-training-tools
は必要ない。
$ tesseract --version tesseract 3.05.00 leptonica-1.74.1 libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.2.54 : libtiff 4.0.6 : zlib 1.2.8
macOS
Homebrew はプルリク投げてみた結果、コメントを削除してマージされた。MacPports は3.04のまま。
以下はHomebrew の場合。
$ brew update $ brew install tesseract --with-training-tools
既存の学習済みの言語データしか使わないのであれば--with-training-tools
は不要。
途中でglib
がらみでエラーになる場合は、表示されるメッセージの通りにする。
Error: You must `brew link glib` before tesseract can be installed
以下のようにbrew link
コマンドを実行してから上記のコマンドを再度実行する。
$ brew link glib
標準では英語とテキストの方向判別データしかダウンロードされないので、/usr/local/share/tessdata
配下にそれぞれの言語別のデータファイルを(3.04用)ダウンロードしてコピーする(後述)。
このパッケージではtesstrain.sh
関連ファイルはインストールされないので必要であればソースアーカイブから適当な場所にコピーする。
バグ対策
mac環境固有のバグ対策。
text2image
を実行する、あるいはtesstrain.sh
を使う場合は、環境変数PANGOCAIRO_BACKEND
に値としてfc
をセットする。
export
コマンドでもいいし、コマンドの先頭にPANGOCAIRO_BACKEND=fc
を付加していい。
参考:
$ PANGOCAIRO_BACKEND=fc ./training/tesstrain.sh --lang jpn --langdata_dir ../github_tesseract/langdata/ --training_text ../github_tesseract/langdata/jpn/jpn.training_text --fonts_dir /Library/Fonts/
それぞれのファイルのパスは環境に応じて修正。
なお、mac環境ではtesstrain.sh
をエディタで編集してmktemp
をgmktemp
に置き換える必要あり。
Windows
公式ページからリンクされているのは今のところアルファ版であるバージョン4.0になっています。
ドイツの大学の方がビルドしたWindows 向けの開発版バイナリが以下より入手できるようです(3.05devと4.0dev)。ご利用は自己責任で。
“training tool"に関してはビルドした張本人がWindowsバイナリを使用していないようなので他の環境で。
Cygwin 版の方がトータルで見るとまともかもしれません。
それぞれの言語別のデータファイル
パッケージ管理ツール経由で取得できる場合はそちらから入手。Homebrew の場合は全部まとめてダウンロードするか、英語と向き判別用のデータだけの2択…。
[2017/03/11 追記]
公式ページに各バージョン(3.03rcを除く)向けのダウンロード用のリンクが記載されたページがあるので必要ならそこからダウンロード。
Data Files · tesseract-ocr/tesseract Wiki · GitHub
[追記ここまで]
GitHub - tesseract-ocr/tessdata at 3.04.00
リポジトリにある最新版は4.00用のファイルなので、3.04.00
タグのツリーから取得する。
あるいは、言語コードが明らかな場合はwget
でURL直打ち。
$ wget https://github.com/tesseract-ocr/tessdata/raw/3.04.00/jpn.traineddata
jpn
の部分を必要な言語に置き換えれば他の言語も取得できます。
ソースからビルドした場合は、/usr/local/share/tessdata
にコピー。それ以外の場合はおそらく/usr/share/tessdata
*6。
もしくは、環境変数 TESSDATA_PREFIX
にtessdata
ディレクトリの一つ上の階層のディレクトリを指定する。
まとめ
もう少しまともな検証用の画像を用意してみたいと思いますがひとまずここまで。
認識精度については3.04系と比較して特に改善していない印象です。バージョン4系に期待しましょうとしか。
何はともあれiOS向けのラッパーの安定板が新規リリースされて欲しいと思う今日この頃です。
それではまた。
開発版のTesseract 4.0 alpha をためしてみる その2
前回に引き続き、開発版のTesseract 4.0alpha ネタです。大した内容はありません。
やったこと
前回の続きとして、新しいjpn.trainneddata
ファイルをバラして内容を確認してみます。
ファイルが混ざると面倒なので作業ディレクトリを2つ作ります。
$ mkdir 4.0a $ mkdir 3.04
まず新しい方のjpn.traineddata
。パスは Homebrew で開発版をインストールした場合した関係で、/usr/local/Cellar/tesseract/
配下の'HEAD-'で始まるディレクトリ(フォルダ)になります。
$ combine_tessdata -u /usr/local/Cellar/tesseract/HEAD-23e420a_2/share/tessdata/jpn.traineddata 4.0a/jpn. Wrote 4.0a/jpn.config Wrote 4.0a/jpn.unicharset Wrote 4.0a/jpn.unicharambigs Wrote 4.0a/jpn.inttemp Wrote 4.0a/jpn.pffmtable Wrote 4.0a/jpn.normproto Wrote 4.0a/jpn.punc-dawg Wrote 4.0a/jpn.word-dawg Wrote 4.0a/jpn.number-dawg Wrote 4.0a/jpn.freq-dawg Wrote 4.0a/jpn.shapetable Wrote 4.0a/jpn.params-model Wrote 4.0a/jpn.lstm Wrote 4.0a/jpn.lstm-punc-dawg Wrote 4.0a/jpn.lstm-word-dawg
以前と比較して、さりげなくファイルが増えています。
- jpn.lstm
- jpn.lstm-punc-dawg
- jpn.lstm-word-dawg
dawgというのはデータ構造の名称の方(directed acyclic word graph : DAWG)のことでで、要は辞書データです。新しいlstmエンジン用の記号(句読点、Punctuation)辞書(punc-dawg)と、単語辞書(word-dawg)かと思います。
DAWGに関する参考ページ
tesstrain.sh
および、tesstrain_utils.sh
の修正内容からすると、既存コマンドのいくつかが新しく生成するファイルをリネームしているようです。
いつの間にかlstmtraining
というコマンドが追加されていますが、このコマンドが直接呼び出されている箇所は見つけられず。
比較対象のバージョン3.04用のjpn.trainneddata
は以下の通り。
$ combine_tessdata -u ~/workspace/github_tesseract/tessdata/jpn.traineddata 3.04/jpn. Extracting tessdata components from /Users/atuyosi/workspace/github_tesseract/tessdata/jpn.traineddata Wrote 3.04/jpn.config Wrote 3.04/jpn.unicharset Wrote 3.04/jpn.unicharambigs Wrote 3.04/jpn.inttemp Wrote 3.04/jpn.pffmtable Wrote 3.04/jpn.normproto Wrote 3.04/jpn.punc-dawg Wrote 3.04/jpn.word-dawg Wrote 3.04/jpn.number-dawg Wrote 3.04/jpn.freq-dawg Wrote 3.04/jpn.shapetable Wrote 3.04/jpn.params-model
md5チェックサムを比較すると新しく増えたファイル以外は全く同一でした。langdataリポジトリにはまだ更新はないみたいなので妥当といえば妥当です。
ついでなのでjpn.lstm-word-dawg
を元のテキストに戻してみます。下記のコマンドでtemp.txt
にdawg形式に変換される前の状態に戻せるはず。
$ dawg2wordlist 4.0a/jpn.unicharset 4.0a/jpn.lstm-word-dawg temp.txt Loading word list from 4.0a/jpn.lstm-word-dawg Reading squished dawg Word list loaded.
中身を見ると理解不能な単語の羅列になっているようです。
$ wc -l temp.txt 110077 temp.txt
先頭だけ抜粋。正直、何これというのが感想。
$ head -n 10 temp.txt ワ ワマ ワマ想プ ワマ想プナク燻ーア ワマ想プナク燻ーア信 ワマ想プナク燻ーアな ワマ想プKク燻ーア ワマ想プケク燻ーア ワマ想プれマ ワマ想想|ナ
単語辞書をニューラルネットワークで自動生成したのでしょうかね? それともn-gram データから文字列生成したとか?
[2016/12/04 追記]
上記の件はバグかも。あるいは新しいエンジンは単語辞書を必要としないのか。
jpn.unicharset
というファイルじゃなくて、専用のファイルがいるのか云々というのがIssueの内容。
まあ要調査ということで。
追記
OCRエンジンの再学習(トレーニング)について、公式Wiki に情報が記載されています*1。
ざっくりいうと、以下のような感じ。
- 学習プロセスの基本的な流れは同じだが、細部で変化している
- 以前より遥かに時間がかかる
- 完全に再学習させなくても良くなった
- どこまで再学習させるかによって、いくつかの方法を選べる
- これまでとは違い、非常に時間のかかるプロセスが存在するので完全に再学習プロセスを自動化できない
完全に再学習させない場合については以前より便利になると考えて良さそう。例えば書体の追加だけ、とか。
ざっと見たところ、変更点は以下。
- 従来の
.tr
ファイルに変わり、.lstmf
というファイルを修正する .box
ファイル(学習用の画像の、文字の位置と幅・高さ情報を記録したファイル)の書式の簡略化(行についての情報だけいいと書いてある)- これまでと異なり、同一画像内に複数のフォントが混在していても問題ない
- クラスタ化ステップ(mftraining、cntraining, shapeclustering)に
lstmtraining
が使用される(と、書いてある) - たとえ新しいOCRエンジンしか使わないとしても、
combine_tessdata
コマンドは従来式のOCRエンジン用のファイルを要求する*2
新しいjpn.traineddata
ファイルが追加されたファイルを除いて以前とほとんど同じなのは、結局、追加されたファイル以外は従来式のOCRエンジン用ということで良さそう。
上記のWikiを見る限りjpn.lstm-number-dawg
ファイルが存在してもおかしくないはずだけど、そもそも生成元のファイルが空だったような気がするので当然か。
まとめ
ひとまずファイルが増えているということまでは確認しました。
それとlstmtraining
という思わせぶりなコマンドが追加されているようです。
以上です。
開発版のTesseract 4.0 alphaをためしてみる(macOS)
この記事は開発中のアルファ版を対象にしてます。その点には十分注意してください。要するに自己責任でどうぞって話です*1。
微妙に出遅れている感じがありますが……。
11月中旬ごろからメイン開発者のRay Smith氏によるバージョン 4.x のコードがgithubにコミットされています。
2、3日前からで各言語のXXX.traineddata
ファイルもアップロードされており*2ひとまず試せる状態。
まだ全ての言語が出揃っていませんが、英語などの主要言語はアップロードされているようです。
日本語用の言語別のデータもアップロードされています。
正式リリースがいつになるのかは不透明ですが、バージョン4.x の最大の特徴は今流行りのニューラルネットワーク技術の採用とのことです。 要するに深層学習とか強化学習とか言ってるアレ。
Long short-term memory(LSTM)による新認識エンジン*3。
参考:4.0 with LSTM · tesseract-ocr/tesseract Wiki · GitHub
Ray Smithの講演資料:docs/das_tutorial2016 at master · tesseract-ocr/docs · GitHub
そもそもLSTM自体の仕組みがよくわかっていないので、OCR処理のどの部分にどういう形で組み込まれているのかはよくわかりません。
もう一つの新機能はTSV出力。地味だけど表形式のデータを読み取る場合には便利なはず。一応3.05ブランチ*4で入った新機能。
ただし、3.05というバージョンは今のところリリースされていません。されるかどうかは不明です。
macOS へのインストール
横着ですがHomebrew でインストールします。ビルドツールとして今までのautoconf
とは別にcmake
も使えるようです。
依存ライブラリとしてOpenMPが必要になっています。そのため何も考えずに開発版をインストールしようとすると余裕で失敗します。
$ brew install tesseract --HEAD --with-training-tools <skip> lstm.cpp:22:10: fatal error: 'omp.h' file not found #include <omp.h> ^ 1 error generated. make[2]: *** [lstm.lo] Error 1 make[2]: *** Waiting for unfinished jobs.... <skip>
ヘッダファイルが見つからないというエラーですが、そもそもmacOS 付属のllvmはOpenMPに対応していないようです。
対処法は、ビルド用のコンパイラとしてgcc
をインストールするか、llvm
の最新版をインストールするか、です*5。
Homebrew で使用するコンパイラを切り替える最も簡単な方法として、--cc
オプションにコンパイラのパッケージ名を指定する方法を利用します。
パッケージ名としてllvm
を指定しても受け付けてくれないのでgcc6
をインストールしました。本来であれば、brew edit tesseract
するか、横着せずにgit clone
してビルドする方が望ましいはずですが、面倒なので……。
$ brew install homebrew/versions/gcc6
非常に時間がかかります。泣きたくなります。バージョン番号なしのgcc
パッケージの場合、brew
コマンド側がパッケージ名として認識しないので苦肉の策です。
依存ライブラリだけHomebrewでインストールして、コンパイラは環境変数(CC
とかCXX
)で切り替える方が短時間で済んだような気もします。
さて本命。
$ brew install tesseract --HEAD --with-training-tools --cc=gcc-6
ビルドにさほど時間はかからないはずですが、--HEAD
を指定すると各言語用のデータを全部ダウンロードする*6のでそれなりに時間がかかります。
バージョンの確認
お約束。
$ tesseract -v tesseract 4.00.00alpha leptonica-1.73 libjpeg 8d : libpng 1.6.26 : libtiff 4.0.7 : zlib 1.2.8
やたらゼロの数が多い。
オプションを眺めてみる。
$ tesseract -h Usage: tesseract --help | --help-psm | --help-oem | --version tesseract --list-langs [--tessdata-dir PATH] tesseract --print-parameters [options...] [configfile...] tesseract imagename|stdin outputbase|stdout [options...] [configfile...] OCR options: --tessdata-dir PATH Specify the location of tessdata path. --user-words PATH Specify the location of user words file. --user-patterns PATH Specify the location of user patterns file. -l LANG[+LANG] Specify language(s) used for OCR. -c VAR=VALUE Set value for config variables. Multiple -c arguments are allowed. -psm NUM Specify page segmentation mode. -oem NUM Specify OCR Engine mode. NOTE: These options must occur before any configfile. Page segmentation modes: 0 Orientation and script detection (OSD) only. 1 Automatic page segmentation with OSD. 2 Automatic page segmentation, but no OSD, or OCR. 3 Fully automatic page segmentation, but no OSD. (Default) 4 Assume a single column of text of variable sizes. 5 Assume a single uniform block of vertically aligned text. 6 Assume a single uniform block of text. 7 Treat the image as a single text line. 8 Treat the image as a single word. 9 Treat the image as a single word in a circle. 10 Treat the image as a single character. 11 Sparse text. Find as much text as possible in no particular order. 12 Sparse text with OSD. 13 Raw line. Treat the image as a single text line, bypassing hacks that are Tesseract-specific. OCR Engine modes: 0 Original Tesseract only. 1 Cube only. 2 Tesseract + cube. 3 Default, based on what is available. 4 Neural nets (LSTM) only. Single options: -h, --help Show this help message. --help-psm Show page segmentation modes. --help-oem Show OCR Engine modes. -v, --version Show version information. --list-langs List available languages for tesseract engine. --print-parameters Print tesseract parameters to stdout.
Page segmentation mode(psm)として11、12、13が追加されています。11と12は以前から存在したみたいです(ドキュメント未記載の隠しオプション扱い)。Sparse text と言われてもピンと来ませんが、文字(文章)がページ内に散らばっているイメージだと思います*7。
特筆すべきは-oem
オプションの方。
$ tesseract --help-oem OCR Engine modes: 0 Original Tesseract only. 1 Cube only. 2 Tesseract + cube. 3 Default, based on what is available. 4 Neural nets (LSTM) only.
ただし、Cubeエンジンは日本語非対応です。Cubeエンジンは将来廃止するという話だったはずですが、どうなるのかはわかりません。
お試し
まだアルファ版なので旧バージョンとの比較は先送りにします。
画像は過去記事から流用。
その1
その2
従来の認識エンジン
$ tesseract -oem 0 -psm 6 -l jpn image.jpg default_output Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
最後の引数は出力ファイルの接頭辞です。この記事を書いている最中に思い出しましたが、ファイル名の接頭辞を指定する代わりにstdout
を指定すると標準出力に結果を出力してくれます……。
なお、設定を切り替えたい場合はコマンドライン引数の最後に指定できます(ドキュメント参照)。
$ cat default_output.txt こ れは 日本語の文章です。 随 ヽろ はに ほへ と
まあ、平常運転です。サボらずに画像を拡大すべきです。-psm
は6ではなくて7
の方がベターかも。
その2
$ tesseract -oem 0 -psm 6 -l jpn image2.jpg default_output2 Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
$ cat default_output2.txt オープンソースの光学文字認識ライブラリを試してみます。 ) Tesseractー〇CR は600gーeの資金援助宣受けてゝ開発されてしヽるりししヽです。 英数字の認識率は97%とか。漢字や平仮名はどっでしよつか。
画像を拡大すればもっと良くなったはず。
新しい認識エンジン
$ tesseract -oem 4 -psm 6 -l jpn image.jpg lstm_output Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file
警告メッセージから見ると、一時ファイルに書き出して読み込んでる?
結果その1
$cat lstm_output.txt これ は 日本 語 の 文章 で す 。 いろは に ほ へ と
結果その2
$ tesseract -oem 4 -psm 6 -l jpn image2.jpg lstm_output2 Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file
認識対象の行数が増えると警告メッセージの行数も増えるの?
$ cat lstm_output2.txt オープン ソ ー ス の 光 学 文 字 認 識 ラ イブ ラ リ を 試し て み ま す 。 。 _ TesseractLOCR は Google の 賄 金 援 助 を 受 け て 開発 され て いる ら し いで す 。 英 数 字 の 認 識 率 は 9700 と か 。 漆 字 や 平仮名 は どう で しょ うか 。
文字間のスペースが気になりますが、許容範囲でしょう。2行目は格段に良くなっているように見えます。3行目は"%"と”漢”を ミスってます。
いままでイマイチだった日本語中の英単語の認識率が改善しているかも。
警告メッセージが気になりますが、認識率自体は改善しそうです。
せっかくなので画像を拡大してみます。
$ convert -geometry 120% image.jpg image2_large.jpg $ tesseract -oem 4 -psm 6 -l jpn image2_large.jpg lstm_output2 Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file Warning in pixWriteMemPng: work-around: writing to a temp file Warning in pixReadMemPng: work-around: writing to a temp file
さて、結果はどうか。
$ cat lstm_output3.txt オ ー プ ブ プ ブン ソース の 光 学 文字 認識 ラ イ ブラ リ を 試し て み ます 。 。 __ TesseracrOCR は Google の 賞 金 援 助 を 受 け て 開発 され て いる らし い です 。 英 数字 の 認識 率 は 979%% と か 。 漢 字 や 平仮名 は ど う でしょ うか 。
1行目と3行目が不思議な出力になっています……。Google 翻訳も謎の文字列の繰り返しを出力するケースがあるので同じようなもの?
他にも試したいことはありますが、ひとまずここまで。
追記
tesseract
コマンドのオプション形式が変化するようです。
当面は 従来と同じ形式も使用できるようですが、今後は-psm
(ハイフンは1つ)から--psm
(ハイフンは2つ)になるようです。
一般的なGNUのコマンドと形式を合わせましょう、という変更です。影響の大きい変更はメジャーバージョンアップの時にやった方がいいよねとかなんとか。
まとめ
新しいOCRエンジンはこれまでよりは期待できるのではないでしょうか。
Google group のやり取りを読む限りでは従来の認識エンジンをどうするか、とか、メジャー番号が上がるついでに互換性のない変更を入れようとか色々と議論がされいます。
バージョン 4.0の前に3.05 をリリースするとかしないとか。
個人的にはTSVファイル出力機能だけでいいので3.05がリリースされる方がいいと思っています。
githubのwikiにはSSE命令がどうのこうのという記述があるのでiOS用のライブラリへの移植は時間がかかりそうな雰囲気。
かなり適当なエントリになってますが以上です。
Tesseractの各言語のラッパーいろいろ(随時更新)
TesseractというのはGoogleが開発を支援しているオープンソースのOCRエンジンです。
Tesseract本体のインストールについては公式のWikiを参照。もしくはググって下さい。
TesseractのC/C++APIを使用するタイプと、tesseract
コマンドを呼び出すタイプの2系統があります。
Web APIなどの形式で使う場合、tesseract
コマンドを呼び出すタイプはリクエストの度にプロセスを生成することになるので好ましくないかと。
- Python 3
- pyocr
- pytesseract
- tesserocr
- Go
- gosseract:
- go-tesseract
- Ruby
- Java
- Tess4J
- Swift(iOS)
- Windows
- Android
- tess-two
- APIとして完成しているもの
- OpenOCR
- 番外編(Tesseract-OCRとは別)