🔍

PaddleOCRで日本語を読む

2020/11/08に公開

PaddleOCRについて

https://github.com/PaddlePaddle/PaddleOCR
Deep Learningを使ったOCRです。Baiduが開発しているようで、軽量(lightweight)を売りにしています。

論文はこちらで確認できます。
https://arxiv.org/abs/2009.09941v3

2020年の9月ごろに耳にしまして、簡単に触れるような手引きやDockerイメージ等が充実していることもあり、試してみることにしました。

日本語にも対応しています。先に申しますと日本語のOCRに少し苦戦したので、このように記事として残しておきます。

導入

GitHubにある説明の通りです。リンクからご参照ください。本記事ではDockerを使い、かつ手っ取り早くCPUで動かすことにします。

sudo docker run --name ppocr -v $PWD:/paddle --network=host -it hub.baidubce.com/paddlepaddle/paddle:latest-gpu-cuda9.0-cudnn7-dev /bin/bash

動かす (中国語)

これも本家手引きの通りです。モデルファイルが既に用意されているので、取得してくるのみです。リンクからご参照ください。

モデルは3種類あります。一覧がこちらにあります。

  • テキスト検出 Text Detection Model
  • テキスト認識 Text Recognition Model
  • テキストの向き(角度)の判別 Text Angle Classification Model

売りの"lightweight"とはモデルの小ささのことだと私は解したのですが、事実モバイル向けモデルですと数MB程度で、アプリに組み込むのも現実的なサイズに思えます。処理速度も軽く、CPUでもすぐ終わります。

画像はいくつかPaddleOCRリポジトリに含まれているので、それを投げて試すことができます。まずは手引き通り中国語で実施します。画像はこれです: https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/imgs/11.jpg

$ cd /home/PaddleOCR
$ python3 tools/infer/predict_system.py \
  --image_dir="./doc/imgs/11.jpg" \
  --det_model_dir=./inference/ch_ppocr_server_v1.1_det_infer/  \
  --rec_model_dir=./inference/ch_ppocr_server_v1.1_rec_infer/ \
  --cls_model_dir=./inference/ch_ppocr_mobile_v1.1_cls_infer/ \
  --use_angle_cls=True \
  --use_space_char=True \
  --use_gpu=False

結果はこのようになりました。

grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
dt_boxes num : 16, elapse : 0.3450467586517334
cls num  : 16, elapse : 0.08440923690795898
rec_res num  : 16, elapse : 5.007258176803589
Predict time of ./doc/imgs/11.jpg: 5.463s
纯臻营养护发素, 0.997
产品信息/参数, 1.000
(45元/每公斤,100公斤起订), 0.957
每瓶22元,1000瓶起订), 0.997
【品牌】:代加工方式/OEMODM, 0.998
【品名】:纯臻营养护发素, 0.997
【产品编号】:YM-X-3011, 0.985
ODMOEM, 1.000
【净含量】:220ml, 0.999
【适用人群】:适合所有肤质, 0.984
【主要成分】:鲸蜡硬脂醇、燕麦β-葡聚, 0.966
糖、椰油酰胺丙基甜菜碱、泛醒, 0.955
(成品包材), 0.999
【主要功能】:可紧致头发磷层,从而达到, 0.997
即时持久改善头发光泽的效果,给干燥的头, 0.992
发足够的滋养, 1.000
The visualized image saved in ./inference_results/11.jpg

最後の行にあるように、OCR結果を画像でも生成してくれています。確認のため、ホスト側にコピーしました。

$ docker cp ppocr:/home/PaddleOCR/inference_results/11.jpg ./

Visualized_11.jpg

動かす(日本語)

ようやく本題です。モデル一覧のページには中国語以外にも英語 フランス語 ドイツ語 韓国語 日本語 向けのモデルが用意されています(2020/11/08時点) [1]

では日本語で試してみましょう。日本語版が用意されているのはText Recognition Model (テキスト認識モデル) のみのようです。Text Detection と Text Angle Classification のモデルは中国語と同じものを使います。

画像はこれです japan_2.jpg [2]: https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/imgs/japan_2.jpg

中国語と同様のパラメータで実行

--rec_model_dir のみ日本語モデルに変更しており、ほかは同じです。

$ python3 tools/infer/predict_system.py \
--image_dir="./doc/imgs/japan_2.jpg" \
--det_model_dir=./inference/ch_ppocr_mobile_v1.1_det_infer/  \
--rec_model_dir=./inference/japan_ppocr_mobile_v1.1_rec_infer/ \
--cls_model_dir=./inference/ch_ppocr_mobile_v1.1_cls_infer/ \
--use_angle_cls=True \
--use_space_char=True \
--use_gpu=False

さてこれを実行すると、まるで日本語ではない結果が返ってきます。

grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
dt_boxes num : 54, elapse : 0.3517613410949707
cls num  : 54, elapse : 0.3236730098724365
rec_res num  : 54, elapse : 0.5352718830108643
Predict time of ./doc/imgs/japan_2.jpg: 1.268s
墙锦墙锦, 1.000
浈俺步, 0.953
盒泅杜盒格联迤步示唇, 0.982
罡蛰侗, 0.781
璀轰璀轰, 0.999
侗诲已蜓侗, 1.000
迤和唇扫唇, 0.890
甬断枇效, 0.993
截青步多骸, 0.848
瞬和帘和, 0.652
饯府迤步多骸, 0.955
盒泅格时, 0.929
(以下略)

最初は文字化けかと思ったのですが、そうではありません。

パラメータの修正

結論から言えば、使われる文字セットの辞書ファイル を適切に指定する必要があります。既定では中国語のままになっています。文字の認識結果は簡単に言えばインデックス(整数)で表現されていて、中国語文字セットに対してインデックスで引いた文字になってしまっています。

文字セットの定義は、実装としては以下の箇所付近で読み込んでいます。これを見ると character_dict_path を指定すればよいのがわかります。かつ、この分岐に入るには character_type を指定しなければならないのもわかります。
https://github.com/PaddlePaddle/PaddleOCR/blob/develop/ppocr/utils/character.py#L41

文字セットは以下のファイルを使えばよいようです。韓国語などほかの言語向けのファイルも隣にあります。
https://github.com/PaddlePaddle/PaddleOCR/blob/develop/ppocr/utils/dict/japan_dict.txt

以上の知見から、末尾に2つのパラメータを追加して再実行します。

コマンドライン引数としては、char_dict_path ではなく rec_char_dict_path のように頭にrec_を付けなければならないのも若干はまりポイントでした。

$ python3 tools/infer/predict_system.py \
--image_dir="./doc/imgs/japan_2.jpg" \
--det_model_dir=./inference/ch_ppocr_mobile_v1.1_det_infer/  \
--rec_model_dir=./inference/japan_ppocr_mobile_v1.1_rec_infer/ \
--cls_model_dir=./inference/ch_ppocr_mobile_v1.1_cls_infer/ \
--use_angle_cls=True \
--use_space_char=True \
--use_gpu=False \
--rec_char_dict_path=./ppocr/utils/dict/japan_dict.txt \
--rec_char_type=japan
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
dt_boxes num : 54, elapse : 0.31853246688842773
cls num  : 54, elapse : 0.3145565986633301
rec_res num  : 54, elapse : 0.9496450424194336
Predict time of ./doc/imgs/japan_2.jpg: 1.646s
もちもち, 0.999
大然の, 0.993
とろっと一後味のよい, 0.985
濃度な, 0.670
サクサク, 0.996
なめらかな, 0.999
味わい深い, 0.913
焼きたて, 0.998
迷みのある, 0.879
さわゃわ, 0.670
うま味のある, 0.921
とろ一り, 0.932
(以下略)

Result_japan_2

所々検出漏れや誤認識がありますが、まずまずですね。

現段階ではこの程度までしか試していないので、これからさらに触ってみたいと思います。

備考:Windowsのコマンドプロンプトでうまく表示されない場合

中国語のOCRの際、以下のように処理が芳しくないように見えて混乱するかもしれません。
Windows_Console_MSGothic

コンソールのフォントを変えると表示できるので、早合点しないようにしましょう。上はMS ゴシックの場合の表示です。これをNSimSunに変えてみたのが以下の状態です。
Windows_Console_NSimSun

脚注
  1. サポート予定の言語: https://github.com/PaddlePaddle/PaddleOCR/issues/1048 ↩︎

  2. なお japan_1.jpg は大人の事情的に怪しい... https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/imgs/japan_1.jpg ↩︎

Discussion