R&D チームの徳田(@dakuton)です。
最近は画像とテキストの狭間にいます。
今回記事のまとめ
簡単にまとめると以下のとおりです。
- いくつかの超解像(高解像度化)モデルがOpenCV extra modules(opencv_contrib)インストール + コード数行記述で導入可能
- 超解像に限らず、文字が一定サイズ以上になるような前処理 -> OCR解析 を実施すると、OCR精度改善につながることがある
- 超解像による見た目の滑らかさに比例して、OCR精度改善につながるわけではない
- 低計算コストな画像拡大から超解像に変更する恩恵は発生しにくい
- テスト条件を変えた場合、違った結果になる可能性あり(用いるOCRエンジン、画像の劣化条件、OpenCV未提供の後発モデル利用など)
実験内容
利用するOCRエンジンの実行条件は変えずに、前処理部分のみ変更した場合のOCR精度・速度変化を調べました。
前処理テストケース
下記3パターンについて、CPU(Intel Core i7 7700HQ)にて試しました。GPUは未検証です。
- 前処理なしの場合
- Bicubic補間による拡大(OpenCV)を前処理として用いた場合
- 超解像(OpenCV extra modules)を前処理として用いた場合
OCRエンジン
TesseractをPythonラッパーから使用しました。
- PyTesseract
- 日本語モデル(
jpn
) - 横書きモード(
--psm 6
)
テストデータ
下記画像を使用しました。(カジュアル面談応募ページの一部をスクリーンショット取得し縦横それぞれを1/2にリサイズしたもの、リサイズ後の画像サイズ: 830 × 407)
実験結果
前処理なしの場合
サンプルコード
import cv2 import pytesseract img = cv2.imread(img_file) result = pytesseract.image_to_string(img, lang="jpn", config="--psm 6")
OCR解析結果
カタカナなど密度の低い単語を除き、読めていない箇所がほとんどです。(縦横1/2にリサイズしなければもう少し読める部分はあるものの、レイアウト崩れが発生します)
オ プ テ ィ ム と は ? ? `maxWWg⑥ の ④OMD な 決 に な る ) こ と を 目 駐 し 、 ち ら ゅ る 思 細 *To カ マ ま # す る と と に R り 映 ん で u る る te。 圏 m シ ェ ア No①oMDM (vble Duce ManagenenD `OpdmalBc) な と ど の ラ イ セ ン ス Ri を ペ ー ス に 、 AlT・Robotcemg ク ラ ウ ド フ ラ ラ ッ ト フ ォ ー ム `OPnM coud oT 0⑤) 、 カ メ ラ W い で す く に RX る A 画 0MN サ ー ビ ス fOPTM A Carernu な ど を W し て u ま か ま た 、W⑤R で H 斧 g コ ロ ナ ウ イ ル ス IMMgPW よ る ワ ー ク ス タ イ ル の ま K に ち も せ て 、 テ レ ワ ー ク で も オ フ ィ ス マ m く MLEos 知 M を XN す る Opana Bz Tuevodu を ⑥ リ リ ー ス 、 で WWMM か ⑤③ ヶ ヨ で ロ ー ン テ し ま し た > そ ネ の ほ か ` た ぇ ず ゅ の に ち ち な い よ き な あ を B ち 、 柴 し み な が ⑤MPR す る 」 を ぽ B 啓 S に B で こ れ ⑤ の BH サ ー ビ ス と 、 mm・ 医 W 卸 R ロ ボ ッ ト ・④ ん 声 ・ 顆 ⑤ な ど W な 室 W の ト ッ プ ② 極 と の M 楊 で を 恐 の ま を に R 綱 ん u ま ⑨ た と え R 緯 a い て B ド ロ ー ン を 使 っ た ` ピ ン ポ イ ン ト 馬 商 R ・ 坪 B テ ク ノ ロ ジ ー」 の WW を MM@。 A・iT・Robolce を e っ で 業 し く 、 か っ と よ く 、 侵 げ る 風 絡 の %MERD 映 D と と に ょ り 、 拐 い ま の 浩 ・ 代 ⑧#R と S 思 宇 HMM を 希 W し て い ま か hmpsyAvuwccincojpaodeurzy haps/Agwxcpncojpnevedalzolal①③pomswsesss
解析時間(10回平均)
- 合計時間: 1892.427 ms
- リサイズにかかる時間: 0 ms
- OCRにかかる時間: 1892.427 ms
Bicubic補間による拡大(OpenCV)を前処理として用いた場合
サンプルコード
cv2.resize()
にて拡大(Bicubic補間にて4倍に拡大)後、OCR実行するサンプル
import cv2 import pytesseract img = cv2.imread(img_file) resized = cv2.resize(img, (img.shape[1]*scale, img.shape[0]*scale), interpolation=cv2.INTER_CUBIC) result = pytesseract.image_to_string(img, lang="jpn", config="--psm 6")
OCR解析結果
前処理なしより多少は読めるようになることがわかります。
なお、下記は今回のテストデータに限らず、Tesseract(日本語モデル)利用で発生する検出誤りとなります。
- 数字が丸付き数字になる
- かぎかっこの開始(「)が`になる
- l(エル)とI(アイ)の区別がつかない
オ プ テ ィ ム と は ? ? ` 第 四 次 産 業 革 命 の 中 心 的 な 企 業 に な る 」 こ と を 目 指 し 、 あ ら ゆ る 産 業 を IT の 力 で 変 革 す る こ と に 取 り 組 ん で い る 会 社 で す 。 国 内 シ ェ ア No.① の MDM (Mobile Device Management) `Optimal Biz」 な ど の ラ イ セ ン ス 収 益 を ベ ー ス に 、Al・loT・Robotics 活 用 ク ラ ウ ド プ ラ ッ ト フ ォ ー ム `OPTiM Cloud loT OS」 、 カ メ ラ に 繋 い で す ぐ に 徊 え る Al 画 像 鮮 析 サ ー ビ ス `OPTiM Al Camera」 な ど を 開 発 し て い ま す 。 ま た 、 直 近 で は 新 型 コ ロ ナ ウ イ ル ス 感 染 症 の 影 響 に よ る ワ ー ク ス タ イ ル の 変 化 に 合 わ せ て 、 テ レ ワ ー ク で も オ フ ィ ス で 働 く 以 上 の 生 産 性 実 現 を 支 攫 す る `Optimal Biz Telework」 を ⑥ 月 に リ リ ー ス 、 企 画 開 始 か ら 約 ③ ヶ 月 で ロ ー ン チ し ま し た 。 そ の ほ か 、 ` た え ず 身 の 丈 に 合 わ な い 大 き な 志 を 持 ち 、 楽 し み な が ら 描 戦 す る 」 を 経 営 理 念 に 掲 げ て 、 こ れ ら の 自 社 サ ー ビ ス と 、 農 業 ・ 医 療 ・ 建 設 ・ ロ ボ ッ ト ・ 小 売 ・ 銀 行 な ど 機 々 な 業 界 の ト ッ プ 企 業 と の 協 業 で 、 各 産 業 の 変 革 に 取 り 組 ん で い ま す 。 た と え ば 農 業 に お い て は 、 ド ロ ー ン を 使 っ た ` ピ ン ポ イ ン ト 農 薬 散 布 ・ 施 肥 テ ク ノ ロ ジ ー」 の 特 許 を 取 得 。Al・loT・Robotics を 使 っ て “ 楽 し く 、 か っ こ よ く 、 稼 げ る 農 業 “ の 実 現 に 取 り 組 む こ と に よ り 、 担 い 手 の 滅 少 ・ 後 継 者 不 足 と い う 産 業 課 題 を 解 滑 し て い ま す 。 https://www.optim.cojp/agriculture/ https://www.optim.cojp/newsdetail/②0①⑨①①①③-pressrelease
解析時間(10回平均)
- 合計時間: 5652.09 ms
- リサイズにかかる時間: 8.561 ms
- OCRにかかる時間: 5643.529 ms
超解像(OpenCV extra modules)を前処理として用いた場合
サンプルコード
LapSRN(x4)を用いた超解像リサイズ後、OCR実行するサンプル
import pathlib import urllib.request import cv2 from cv2 import dnn_superres # $ pip install opencv-contrib-python import pytesseract def load_sr_model(model_name, scale, url): model_path = pathlib.Path("models").joinpath("{}_{}.pb".format(model_name, scale)) if not model_path.exists(): model_path.parent.mkdir(exist_ok=True) urllib.request.urlretrieve(url, model_path) sr = dnn_superres.DnnSuperResImpl_create() sr.readModel(str(model_path)) sr.setModel(model_name, scale) return sr img = cv2.imread(img_file) sr = load_sr_model("lapsrn", 4, "https://github.com/fannymonori/TF-LapSRN/raw/master/export/LapSRN_x4.pb") img_sr = sr.upsample(img) result = pytesseract.image_to_string(img, lang="jpn", config="--psm 6")
OCR解析結果
画像の見た目としてはBicubic補間よりも超解像(LapSRN)のほうがなめらかに文字を表現できている(Mなどのギザギザが軽減されている)ように見えるものの、OCR(検出誤りの文字数カウント比較)としては改善効果なしとなりました。
- サンプルデータにおける前処理変更のTesseract検出差分(Bicubic補間 -> LapSRN)
- Optimal Biz」 -> Optimal Biz』 : 正解 -> 不正解
- Al画像鮮析サービ ス -> Al画像解析サービ ス : 不正解 -> 正解
- 実現を支攫する -> 実現を支援する : 不正解 -> 正解
- 大きな志を持ち、 -> 大きな志を狩ち、 : 正解 -> 不正解
- 楽しみながら描戦する -> 楽しみながら挽戦する : 不正解 -> 不正解
- すぐに徊える -> すぐに使える : 不正解 -> 正解
- 稼げる農業 -> 穂げる農業 : 正解 -> 不正解
- 産業課題を解滑 -> 産業課題を解消 : 正解 -> 不正解
- 2つめのURLドメイン: cojp -> cojjp : 不正解(.不足) -> 不正解
オ プ テ ィ ム と は ? ? ` 第 四 次 産 業 革 命 の 中 心 的 な 企 業 に な る 」 こ と を 目 指 し 、 あ ら ゆ る 産 業 を IT の 力 で 変 革 す る こ と に 取 り 組 ん で い る 会 社 で す 。 国 内 シ ェ ア No.① の MDM (Mobile Device Management) `Optimal Biz』 な ど の ラ イ セ ン ス 収 益 を ベ ー ス に 、Al ・loT ・Robotics 活 用 ク ラ ウ ド プ ラ ッ ト フ ォ ー ム `OPTiM Cloud loT OS」 、 カ メ ラ に 繋 い で す ぐ に 使 え る Al 画 像 解 析 サ ー ビ ス `OPTiM Al Camera」 な ど を 開 発 し て い ま す 。 ま た 、 直 近 で は 新 型 コ ロ ナ ウ イ ル ス 感 染 症 の 影 響 に よ る ワ ー ク ス タ イ ル の 変 化 に 合 わ せ て 、 テ レ ワ ー ク で も オ フ ィ ス で 働 く 以 上 の 生 産 性 実 現 を 支 援 す る `Optimal Biz Telework」 を ⑥ 月 に リ リ ー ス 、 企 画 開 始 か ら 約 ③ ヶ 月 で ロ ー ン チ し ま し た 。 そ の ほ か 、 ` た え ず 身 の 丈 に 合 わ な い 大 き な 志 を 狩 ち 、 楽 し み な が ら 挽 戦 す る 」 を 経 営 理 念 に 掲 げ て 、 こ れ ら の 自 社 サ ー ビ ス と 、 農 業 ・ 医 療 ・ 建 設 ・ ロ ボ ッ ト ・ 小 売 ・ 銀 行 な ど 機 々 な 業 界 の ト ッ プ 企 業 と の 協 業 で 、 各 産 業 の 変 革 に 取 り 組 ん で い ま す 。 た と え ば 農 業 に お い て は 、 ド ロ ー ン を 使 っ た ` ピ ン ポ イ ン ト 農 薬 散 布 ・ 施 肥 テ ク ノ ロ ジ ー」 の 特 許 を 取 得 。Al・loT・Robotics を 使 っ て “ 楽 し く 、 か っ こ よ く 、 穂 げ る 農 業 “ の 実 現 に 取 り 組 む こ と に よ り 、 狙 い 手 の 減 少 ・ 後 繁 者 不 足 と い う 産 業 課 題 を 解 消 し て い ま す 。 https://www.optim.cojp/agriculture/ https://www.optim.cojjp/newsdetail/②0①⑨①①①③-pressrelease
LapSRN以外のモデル(ESPCN, EDSR, FSRCNN)についても、「Bicubic補間と比較して改善した」といえる結果は得られませんでした。(各モデルが訓練時の入力などにBicubic補間を利用している、という依存があることを踏まえると、このような結果となることの違和感はないです)
解析時間(10回平均)
下記はLapSRN(x4、ダウンロード済み)での実行時間です。
- 合計時間: 15098.19 ms
- リサイズにかかる時間: 8545.71 ms
- モデル読み込み: 22.90 ms
- upsample: 8522.81 ms
- OCRにかかる時間: 6552.48 ms
- リサイズにかかる時間: 8545.71 ms
他の超解像モデルについても、Bicubic補間よりリサイズにかかる時間が0.2秒〜数分レベルで遅くなります。
- 手法ごとの時間比較(リサイズ処理部分のみ、10回実行平均)
- Bicubic補間(0.00856秒) <<< ESPCN(0.275秒) < FSRCNN(0.513秒) < LapSRN(8.546秒) <<< EDSR(121.702秒)
- 処理時間の優劣についてはBenchmarksにあるとおり
- リサイズ時間1秒以内に収めようとすると、評価指標(PSNRやSSIM)で見てもBicubic補間と大差ないレベル
おわりに
OCR精度改善の文脈でいえば、現時点でOpenCV extra modulesにて用意されている超解像モデルは意味なさそうという結果ではありましたが、さくっとインストールして試せるのはよいと思います。
狭い範囲でのテストのため、条件を変えれば有用なケースはあるかもしれません。
例えば、
- OCR解析エンジンを変更した場合は?
- Google Cloud Vision APIのテキスト検出では1024 x 768以上を推奨とあるように、画像の拡大・超解像が有効なケースはTesseract利用時に限らず存在します。
- GPUを用いた場合の速度は?
今回用いたテストデータが気になった方は、下記をご確認ください。