初投稿です。
目標
スマホのブラウザとカメラで動く日本語OCRアプリケーションを作る。
経緯
会社で社内便(複数)の郵送を頼まれる事がある。その際、宛名読む→宛名から郵便受け番号への変換→宛名の郵便受けまで行って投函→宛名読む→...を繰り返す必要があり効率化したい。
↓
配達の前にPCで宛名を一括で打ち込み、郵便受けの番号リストを作成すれば良いがタイピングが面倒。
スマホのカメラで動くOCRなら便利そうだが、Google Cloud Vision APIの社内利用はセキュリティの問題もあって(多分)無理。
↓
tesseract.jsなら入力情報を外部に送信しなくて良いので安全なのでは!?
AndroidとかiOSのアプリは作れないけどhtmlなら何とかなりそう!?
↓
今ここ
↓
社員情報のAPIを使用した最短ルートの提案など...
作成物
作成物のデモ
処理速度の関係でiPhone 7以降を推奨します。
デモ動画
@null pic.twitter.com/pDajJpD5vc
— 石のことなら (@a_ab_abc) 2017年10月7日
仕組み
JavaScriptのnavigator.mediaDevices.getUserMedia()
メソッドを利用してカメラの映像を取り込む。
↓
取り込んだ映像をhtmlのcanvas
タグを利用して切り出す。
↓
映像を2値化してディスプレイする(ユーザーに機械の気持ちを理解してもらい、機械が読みやすい写真を撮ってもらうため)。
↓
シャッター押す。
↓
canvas
タグで(2値化されていない)静止画を生成。
↓
Tesseract.recognize()
でOCRする。
コード
やっていないこと
- tesseract.jsはOCR時に様々なオプションを指定でき、何か精度を高められそうだが今回は何もしていない。
-
canvas
タグで画像を描画する際、カメラから得られた画像を半分のサイズに圧縮しているが、圧縮しないほうが認識精度が良いかもしれない。 - vue.jsを使ってみたかったが使っていない。
注意点
- tesseract.jsでは2回目以降のOCR時に以前使用した推論データのキャッシュが使えるため、推論データのダウンロードが不要で高速。アプリ起動時に
準備中🐹
と出るのは、日本語の推論データをダウンロードするために一度OCRを走らせているから。 -
canvas
以外にカメラの映像を写す必要が無いので、カメラ映像の実体である<video id="player" controls autoplay playsinline></video>
を隠蔽したかったが、cssで隠蔽するとiPhoneのカメラが起動できなくなる(iPhone 7, iOS11, Safari)。そのため#player
のwidth
を0.5にして目立たなくさせた。 -
navigator.mediaDevices.getUserMedia()
はhttps環境でないと使えないらしい。私はwindows使用者なのでHyper-Vで作成した仮想UbuntuにApache2を入れてローカルにhttps環境を作成しました。
まとめ
あの横山三国志全文検索システムでも使用されたGoogle Cloud Vision APIと比較すると、tessaractの日本語の読み取り精度は明らかに劣るので文章の意味を読み解くのとかにはいまいち使えなさそうですが、社員名の検索であれば文字列の一部が引っかかればかなり絞りこめるのでこの方向で開発を進めていけそうです。
英語の認識精度は高いんですけどね。