tesseract+pytesseractのdockerコンテナ

# はじめに
スキャンした画像からデータを抽出してデータベースに…という需要はそこそこあると思います。そんなときに鉄板と噂なのが[tesseract](https://github.com/tesseract-ocr/tesseract)。ただ、このツール、どうもOSによってインストール方法がまちまち。ならだいたいの環境でインストールしてあるであろう（誇張）、dockerコンテナにしてしまえ！というのがことの始まりです。

ついでに画像処理に強そうなPythonも含めたのがポイント。あとはPythonでスクリプトを書くだけです。普段、Pythonを使わないので知らなかったんですが、PIL、すごく便利ですね〜

2018/10/11現在で、tesseract 3.04.01が動かせます。Pythonとの接続は[pytesseract](https://github.com/madmaze/pytesseract)を使いました。世の中には[PyOCR](https://gitlab.gnome.org/World/OpenPaperwork/pyocr)というのもあるそうです。

# 作り方

1. python3のlatestのDocker imageをベースに、
2. tesseractと依存ライブラリをaptでインストールして、
3. 必要なpythonライブラリをpipでインストール

ちなみにPythonのDocker imageが`Debian GNU/Linux 9 (stretch)`でしたので、それを参考にやり方を探しました。

```Dockerfile
# 1. python3のlatestのDocker imageをベースに、
FROM python:latest

# 2. tesseractと依存ライブラリをaptでインストールして、
RUN apt-get update
RUN apt-get -y install \
    tesseract-ocr \
    tesseract-ocr-jpn
RUN apt-get clean

# 3. 必要なpythonライブラリをpipでインストール
RUN pip install --upgrade pip; \
    pip install \
    pillow \
    pytesseract

ENTRYPOINT ["/usr/bin/tail", "-f", "/dev/null"]
```

## 困ったこと：画像が小さいとエラー

あまりに小さい画像だとエラーを吐く模様。Empty Page!!と言われます。PILのresize等で画像を拡大して読み取れば回避できました。当初、エラーの原因がわからず苦労しました。Leptonicaというパッケージに依存しているらしいので、それがないとダメ？と思ってビルド＆インストールしたりと大立ち回りの遠回り…

# 作ったもの

GitHubとDockerHubに上げました。DockerもPythonもとおりいっぺんな理解ですので、お手柔らかに…

## DockerHub
[cranpun/tesseractpython](https://hub.docker.com/r/cranpun/tesseractpython/)

## GitHub
[cranpun/tesseract-python-container
](https://github.com/cranpun/tesseract-python-container)

サンプルコードも放り込んだので試すには楽かもしれないです。Dockerさえ入っていればコマンド数発。

# （余談）動かしてみました

GitHubに放り込んだサンプルの動作結果です。git clone後、以下で試せます。

``` commandline
$ docker-compose build    # そこそこの時間がかかります。
$ docker-compose up -d
$ docker-compose exec tesseractpython python /opt/sample/sample.py
  # ↑これがサンプルのPythonスクリプトの実行。→解説1
$ docker-compose exec tesseractpython tesseract /opt/sample/textsample1.png stdout -l eng+jpn
  # ↑tesseractのコマンドもインストールしてあるので直接叩くこともできます。→解説2
$ docker-compose stop    # 遊び終わったらコンテナ停止
```

注意点として、一番上のフォルダを、コンテナ内の/optにマウントしてあるので、Pythonのコードやdocker-compose execでコマンド叩くときにはそれを踏まえてください（docker-compose.ymlのvolumesで指定した通りです）。

## 解説1

sampleフォルダ内のsample.pyの結果です。samle1.png〜sample4.pngを読み取ります。PythonのPILで1マスごとに（雑に）切り取って、tesseractの1文字モードで識別してみました。

読み取った画像と結果の一部をご紹介します。

### sample1.png

数字のみ
![sample1.png](https://qiita-image-store.s3.amazonaws.com/0/23715/dd729663-5245-0216-38d9-8cd3eaf70b03.png)

↓読み取り結果。まさかのパーフェクト。

```
1
2
3
4
5
6
7
8
9
```

### sample3.png
難しい漢字はどうでしょう？ ~~くずりゅうせ...~~

![sample3.png](https://qiita-image-store.s3.amazonaws.com/0/23715/975c2f7a-d511-199d-8642-83684aaa23e1.png)

↓読み取り結果。こちらも期待以上の精度。なぜか参が9になりました。

```
捌
壱
弐
漆
玖
9
陸
伍
肆
```

## 解説2

文章画像の読み取りです。textsample1.pngとtextsample2.png。tesseractコマンドを直接叩くやり方で試してみました。オプションは言語指定、`-l eng+jpn`のみです。

### textsample1.png

英文。MITライセンスの一部です。

---

![textsample1.png](https://qiita-image-store.s3.amazonaws.com/0/23715/e5d9eeba-aea2-0dab-02f2-56d8ea7ed483.png)

---

↓読み取り結果。文字として見るなら2割くらい...?英語だけとわかっているなら、言語はengだけのほうがまだマシな印象です。

```
MIT LItehse
C叩y‥g=t 川 2m …叩皿

陶叩m伽 】… hereby granted, free 〝T (Marge, m 洲 四巖伽 〝吐…"Mg z mW
ef thIs software 剛 mm…“ 血m爬"鮨UM 川es ぱ爬 Software"), to deal
m the Suftware mthnut rEstr】〔tm", md皿…g …伽吐 h爪n鹸m” the ug…
m use, mpy, m。d‥y, merge, nuhllsn, ulstnbute, sumtehse, and/Dr sell
mm“ 〝f the Software, and m 州耐 胸m肪 m w加爪 the Software LS



mrmshea m 伽 馴 皿m… m the faUumng m皿…M~:

鵬 above 〔叩y‥g吐 皿…E 伽 ms 州…m伽 皿…e 伽〝 膿 …‥皿皿 m 〕‥
mm“ gr mmm… 加川… “T the Suftware.

THE 50mm IS mvan "AS ーS", WーTH。UT WA剛W DF 鮒) KーND, EXPRESS 吹
IMPLIED, ーNCLU囁ーNG Bur NOT LIMITED m THE WARRANTIES NF NER〔H鮒T^飄ーLーTV,
FーmESS FOR A PARTIEULAR PURP囁SE MD N叩ーNFRーN5EME爪・ ーN N“ EVENT SHALL THE
剛T叩RS 吹 ⑳門肛酬T HOLDERS BE LIABLE FOR 畑〉 CLAIM, DAMAGES 吹 OTHER
LーABーLーTV' WHETHER ーN 鮒 A〔Tー叩 DF ⑳爪叫吼 mar DR DTHERWISE, ARISING mm,
伽T NF 脈 ーN camEmuN mm THE SOFTWARE 脈 THE USE 吹 OTHER DEALINGS IN THE
50mm.

```

### textsample2.png
日本語は読み取れるでしょうか？サンプルはこの記事の抜粋。最終稿前のキャプチャなので少し違う文章なのはご愛嬌。

---

![textsample2.png](https://qiita-image-store.s3.amazonaws.com/0/23715/24cf2bbc-13ab-ffff-17b9-05ad82e63030.png)

---


↓読み取り結果。先程よりちょっといいかも？読めなくもな…いや読めないですね。

```

スキヤ〉した画像か デ一タを油出してデ一タべ一ス〔〔…と髏`う扁要{暮そこそこ
ぁると思います〝 そんなとき【こ鉄板と噂なのが【eSSe陶C【。 ただ、 このツ一ル、 ど
うも。Sにょ つてイ)ス 卜一ルがいろいろ大変な槙様。 ならだいたいの人がイ〉

ス 卜一ルしてるでぁろう (誇張) 、 d0Cke「CG‥【竈…eバ〔してしまえ璽 というのが
ことの始まりです”

ついでに画像処理に強そ うなpyーh。nも含めたのがポイ ン 卜〝 ぁ と はPW加n署〈
'け です” 晋段ヽ PWh叩使わないんで知 らなかったんですが~ PL すご < 便利
ですね~



20ーg/ー0/ーー現在でヽ lesserac‘ 3.04.01iﬁg7mt ま す〝

```

## 所感
文章を読み取ろうと思うとそのままでは大変そうな印象です。もし使うなら、解説1のように切り出したり、画像を拡大したりシャープネスにしたり、オプションを調整したり等、工夫がいるという結果でした。tesseract本体もver4が開発中とのことで将来はより精度が上がるかもなー、と期待しております。


## 追記（2019/09/30）

@rapidliner00 さんからコメントをいただいた（ありがとうございます！）ので試したら、ものすごく精度が上がっておりました。詳しくは@rapidliner00 さんからコメントをご覧ください。

tesseract-ocr、現在はデフォルトだと4.0.0-2がインストールされるようですね。tesseract本体のバージョンも4.1までリリースされているようなので、今後ますます成長しそうな予感がします。

せっかくなのでDockerHubのイメージも更新しました。