EasyOCR は、JaidedAI が提供する Python 向けのすぐ使える OCR ライブラリです。pip install easyocr で入れられて、たった2行のコードで画像の中に埋め込まれた文字を文字列として取り出せます。Apache-2.0 ライセンスで、80以上の言語に対応。中では2つの PyTorch モデルをつないだパイプラインとして動いていて、まず CRAFT の検出器がテキストっぽい領域を四角く囲み、そのあと認識器が各 बॉक्स 内の文字を読み取ります。学習済み重みは、初回実行時に自動でダウンロードされます。立ち位置としては、ページ単位のクラウド OCR API ではなく、Tesseract や PaddleOCR の代わりになるセルフホスト型ツールです。
基本 API はかなり短くて、Reader(['en']) を作って readtext() を呼ぶだけです。ただ、導入は軽くても、実運用で必要になる容量はやや大きめです。この環境では PyTorch 本体だけで約 2 GB、さらに新規プロセスのピーク常駐メモリは実測で約 1 GB に達しました。私は英語の PNG 形式フィクスチャ 36枚を描画し、easyocr 1.7.2 を CPU 上で動かして、生成した正解データと1文字ずつ突き合わせて評価しました。結果として、文字サイズと向きが CER をかなり悪くし、ダッシュボード系のサンプルでは短いトークンの取りこぼしやドル記号の誤認識も確認できました。
特に印象に残った失敗は、誰もが勧めるあのパラメータに関するものです。rotation_info は回転画像への定番対策として issue tracker でよく挙がるため、同じ文を3方向に回転させた画像で試しました。270°では期待どおりに効いて、文字エラー率を 0.83 から 0.10 まで下げました。180°では半分だけ効いて、0.85 から 0.67 に改善したものの、一部のフレーズは消えました。90°では逆効果で、0.81 から 0.92 に悪化し、認識結果が鏡写しのような文字列になりました。同じパラメータ、同じ角度一覧でも結果は3通り――つまり、オンにしただけで「回転をちゃんと処理できる」とは言えません。同じ36枚のフィクスチャからは、はっきりした文字サイズの断崖、体系的なドル記号の誤読、そして私自身の予測の外し方も見つかりました。
コートの下に2つのモデル
EasyOCR は1つのモデルではありません。2段構成のパイプラインで動いていて、どの段で落ちたかを切り分けるとデバッグの仕方も変わります。
第1段は CRAFT、つまり 検出器 です。役割は位置特定だけで、画像のどこにテキストがあるかを判断してボックスを返すことに専念します。文字を読むことはしません。第2段は CRNN ベースの 認識器 で、ResNet による特徴抽出のあと、BiLSTM、CTC の greedy decoding を通じて各ボックス内の文字を読み取ります。どちらも PyTorch 上で動きます。CPU では認識器がデフォルトで int8 に動的量子化されるので、見た目のパラメータ数より軽く、速くなっています。

実務上の意味ははっきりしています。EasyOCR にはまったく別物の2種類の失敗モードがあり、それぞれに別の対処が必要です。検出器がボックスを1つも作らなければ、認識器をいくらいじっても意味がありません。文字は最初からパイプラインに入っていないからです。逆にボックスはあるのに文字列が間違うなら、それは認識の問題で、前処理で救える可能性があります。私が読んだ「EasyOCR がテキストを見逃した」という投稿の大半は、この2つをごっちゃにしています。
プロジェクトの現状を 2026年7月27日 時点で見ると、スター数 29,825、オープン issue 528件、Apache-2.0、v1.7.2 は 2024年9月公開、master への最後の push は 2025年12月でした。ただし、この手の日時だけでアーキテクチャの安定性や保守状況は判断できません。採用前には、Python/PyTorch の組み合わせとの互換性、メンテナの最近の応答状況、そして自分の入力に関係する issue を確認してください。
OCR は CAPTCHA の突破と結びつけられがちですが、ここで扱う用途はそこではありません。ボット検知チャレンジの回避を試したわけでもなく、それを勧める意図もありません。対象は、閲覧権限のある画像やスクリーンショットから文字を読むことです。
何を測ったのか、そしてこの数字が示さないもの
テストセットは 自分で描画した PNG 36枚 です。内訳は、7種類のフォント、8種類のサイズ、7種類のコントラスト、7種類の傾き、3方向の回転、3種類の背景をまたぐ単一行画像 35枚と、19個のラベル付き要素を含む synthetic なダッシュボードスクリーンショット 1枚です。すべての画像は、正解ラベルを書き出すのと同じ処理で、固定文字列 (Sphinx of black quartz, judge my vow. 1234567890 — 48文字、大小文字、数字、句読点を含む) から生成しました。そのため、画像とラベルが途中でずれることはありません。
精度指標は character error rate (CER) です。文字列レーベンシュタイン距離を正解長で割った値で、CER 0 は完全一致、CER 0.10 は10文字に1文字ほどの誤りを意味します。見出しでは大文字小文字を区別した CER を示し、あわせて大小文字を無視した値も載せています。実際には、誤差の大半がケース違いに由来していたからです。
ただし、数字以上に大事なのは境界条件です。
- 英語のみ。
english_g2認識器を使いました。EasyOCR は80以上の言語をうたっていますが、私が試したのは1言語だけです。非ラテン文字については何も言えません。しかも、公開されている学術比較はまさにその領域が中心です。 - synthetic のみ。 写真ではなく、描画した文字です。カメラノイズ、JPEG 圧縮、照明、遠近歪みはありません。
- 手書きなし。 プロジェクト自身が、手書きは未対応と明記しています。
- CPU のみ。 macOS arm64、
gpu=False。この機械では MPS も使えましたが、EasyOCR は CUDA 以外では CPU を使います。GPU 性能は測っていないので、GPU の数値はここにはありません。 - 1台の機械、1つの版。 easyocr 1.7.2、torch 2.13.0、Python 3.12。
つまり、これはクリーンに描画したラテン文字上で、どこで精度が崩れるかを1変数ずつ見た制御実験です。実世界のコーパススコアではなく、その代替にもなりません。
証拠はノートブックの中だけに閉じ込めていません。フィクスチャ生成器と正確な文字列は tests/build_fixtures.py と tests/fixtures/ground_truth.json にあり、認識・計測・リソース取得は tests/run_easyocr.py に実装されています。さらに tests/metrics.py が、生の出力からレポート用の誤り率を計算します。結果の認識ログと集計値は artifacts/raw/ に保存されています。この一連を再実行すれば、この機械と版での挙動確認には役立ちます。ただし、あなたのスマホ写真、言語、レイアウト、前処理パイプラインでどうなるかは依然として分かりません。実運用で採用するなら、このフィクスチャを認証用スイートとみなすのではなく、代表的な入力を追加して検証すべきです。
なお、1つだけハーネスの落とし穴を共有しておきます。これが危うく誤った見出し値を生むところでした。最初の計測では、クリーンな黒字 Arial に対して CER 0.375 と出ました。最も簡単な入力としてはかなりひどい値です。でも問題は EasyOCR ではありませんでした。検出器が1行を単語ボックスと数字ボックスに分けていたのに、私の単純な「y で並べてから x でつなぐ」処理が数字を先頭に置いてしまっていたのです。縦方向の重なりでボックスをまとめ、左から順に読む行認識型の grouping に直したところ、クリーンなフォントはおおむね 0.04〜0.10 に収まりました。自分で OCR 評価を作るなら、同じ罠が待っています。
セットアップ:インストールは軽いが、依存は重い

pip install easyocr
これで終わりです。とはいえ、実情をあまり隠していません。パッケージ自体は小さいのに、引き込まれるのは 約2 GB の PyTorch です。そして初めて readtext() を呼ぶと、EasyOCR は重みを ~/.EasyOCR/model/ に静かにダウンロードします。合計は 93.7 MiB で、内訳は CRAFT 検出器が 79.30 MiB (craft_mlt_25k.pth)、英語認識器が 14.44 MiB (english_g2.pth) です。
チュートリアルではこの点にあまり触れません。つまり、初回実行にはネット接続が必要で、ダウンロード中はいったん止まります。コンテナ運用では、これらの重みをイメージに焼き込むか、コールドスタート時に毎回ダウンロードを受け入れる必要があります。キャッシュされれば、その後はオフラインで動きます。
コールド状態での Reader() 初期化――モデルをディスクから RAM に載せ、int8 量子化を行うまで――には、複数回の実行で 1.3〜1.7秒 かかりました。そのあとに使うのは次の形です。
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
これで動きます。2行、設定なし、チェックポイント選びも不要。「easy」という名前はこの段階ではちゃんと似合っています。重さがあるのは API ではなく、依存関係のほうです。
クリーンテキストの下限:文字はほぼ完璧、ただし大文字小文字は不完全
7種類のシステムフォント、白地に黒、32 px、毎回同じ文字列です。
| フォント | CER(大小文字を区別) | CER(大小文字を無視) |
|---|---|---|
| Georgia | 0.0625 | 0.0000 |
| Times | 0.0417 | 0.0417 |
| Comic Sans | 0.0417 | 0.0208 |
| Arial | 0.0833 | 0.0208 |
| Verdana | 0.0833 | 0.0208 |
| Impact | 0.0833 | 0.0208 |
| Courier | 0.1042 | 0.0417 |
| 平均 | 0.0714 | 0.0238 |
平均 CER は 0.071、大小文字を正規化すると 0.024 まで下がります。この差が重要な発見です。EasyOCR はクリーンなラテン文字で文字そのものを見失っているのではなく、形は合っていても ケース を取り違えているのです。
具体的には、vow という小文字が7フォント中6つで VOW になりました(Comic Sans だけは Vow)。Impact ではさらに of が Of になります。繰り返し起きたもう1つの誤りは句読点で、文末のピリオドが複数のフォントで : や _ に化けました。Georgia は、大小文字を気にしなければ 完全一致 です。
このタイプのエラーはかなり実用的です。後段があいまい一致やキーワード検索、あるいは LLM への入力なら、ケースの違いはほぼ問題になりません。一方、データベースキーとの完全一致が必要なら致命的です。比較前に大小文字を正規化すれば、EasyOCR の見かけ上の誤差の半分は消えます。
Courier が最悪(0.1042)なのも納得できます。等幅フォントは文字間隔が不自然に広く、典型的な文字間隔で学習した CTC デコーダには少しやっかいです。
サイズの断崖は、ドキュメントどおりの場所にある

readtext() には min_size=10 という既定パラメータがあり、10ピクセル未満の検出ボックスを捨てます。多くの人はここを読み飛ばしますが、スクリーンショットや PDF 抽出をやる人にとっては、API の中でかなり重要な数値です。レンダリングした文字高さを変えると、挙動はこうなります。
| 描画サイズ(px) | CER | 起きたこと |
|---|---|---|
| 8 | 0.7708 | 崩壊 — ボックスが min_size フィルタに落ち、断片だけが残る |
| 10 | 0.1458 | 劣化 — 下限ちょうどで検出器が行を3つのボックスに分割 |
| 12 | 0.0417 | 回復 |
| 16 | 0.0000 | 完全一致 |
| 20 | 0.0208 | 良好 |
| 28 | 0.0208 | 良好 |
| 40 | 0.0625 | 良好(再びケース変換が出る) |
| 64 | 0.0625 | 良好(ケース変換) |
12 px から 8 px への 0.04 → 0.77 の跳ね上がりは、じわじわ悪くなる話ではありません。これはドキュメントどおりのフィルタが効いた結果で、10 px 前後を下回る文字はデフォルトの EasyOCR ではほぼ見えなくなる、ということです。
最も良い帯域は 12〜28 px で、16 px では CER 0 まで到達します。40 px を超えると CER は少し戻りますが、文字が読めなくなるからではなく、vow → VOW のケース変換が再登場するからです。大きい文字が読みにくいのではなく、16 px のときにうまく働いた間隔条件が外れているだけです。
スクリーンショットから文字を抜く人への実務アドバイスは1つです。モデルを責める前に、まず描画後の文字高さを確認してください。 HiDPI ディスプレイで1倍のまま取ったダッシュボードや、72 DPI でラスター化した PDF は、本文が 10 px 未満に落ちることが珍しくありません。2倍で取得するか OCR 前に拡大すれば、「EasyOCR がページの半分を無視した」という不具合報告の大半は避けられます。どちらも無理なら min_size を下げる選択肢はありますが、そのフィルタは不要な検出を抑えるためのものなので、ノイズ増加は覚悟してください。
回転:10°までは耐えるが、対称な修正ではない
まずは傾きです。小角度、Arial 32 px、デフォルト設定と rotation_info=[90,180,270] を比較します。
| 傾き角度 | CER(デフォルト) | CER(rotation_info あり) |
|---|---|---|
| 0° | 0.0833 | 0.0833 |
| 5° | 0.0417 | 0.0417 |
| 10° | 0.0208 | 0.0833 |
| 15° | 0.2917 | 0.3750 |
| 20° | 0.7500 | 0.7708 |
| 30° | 0.8958 | 0.8750 |
| 45° | 0.8958 | 0.8750 |
デフォルトの EasyOCR は、10°程度 の傾きならほとんど崩れません(CER ≤ 0.083)。15°で揺れ始め、20° でほぼ壊れます。rotation_info は傾きには効きません。中身を見れば納得できます。列挙した角度でしか再試行しないので、15° の傾きは 90/180/270 のどれにも当てはまらないからです。10° ではむしろ少し悪化しました(0.021 → 0.083)。間違った角度の再試行が、信頼度の票を奪ってしまうためです。
では、直交回転はどうかというと、ここから少し変です。
| 回転 | CER(デフォルト) | CER(rotation_info あり) | 回復したか |
|---|---|---|---|
| 90° | 0.8125 | 0.9167 | いいえ — 悪化 |
| 180° | 0.8542 | 0.6667 | 部分的に |
| 270° | 0.8333 | 0.1042 | はい |
同じパラメータ、同じ角度一覧、結果は3通りです。
270° では、rotation_info は issue thread の説明どおりに動いて、CER は 0.83 から 0.10 に下がり、実用的な読み取りになりました。180° では半分だけ効いて、CER は 0.67 に改善するものの、my vow. というフレーズは丸ごと失われました。90° では逆向きに悪化し、0.81 から 0.92 へ。生の出力を見ると理由は明らかで、認識器が 鏡写し の文字列を返しているのです。VOW は MOA になります。quartz は zuuenb になります。鏡に映せば正しいので見た目はおもしろいですが、データ処理としては使えません。
私は集計値ではなく生の予測結果で確認しました。最初は「結合順で壊れたのでは」と疑ったからです。でも、これは join の問題ではなく、実際に EasyOCR が返した結果でした。
仕組みについては仮説であって計測結果ではありません。回転規約の実験はしていないからです。Pillow は正の角度を反時計回りに描画するので、270° の画像だけが、認識器がうまく扱える再試行向きにたまたま一致したのでしょう。90° のケースでは、最も高得点の再試行が反転向きに落ちた、と見ることもできます。どちらにせよ、運用上の結論は同じです。
このフィクスチャは、rotation_info が向きによって対称に働くとは限らないことを示しています。自分の入力で想定される回転は必ず検証してください。事前の向き正規化は有力な対策候補ですが、3つの描画例だけで必須と断定できるものではありません。
予測を外した点
私は、低コントラストこそ EasyOCR の弱点だろうと予想していました。薄いグレーの文字を白地に置いたものは OCR 失敗の典型で、これを救うための既知のルートもあります。contrast_ths=0.1 と adjust_contrast=0.5 で、低コントラストのボックスをコントラスト増強した再実行に回し、より自信の高い結果を採用する仕組みです。
でも、その救済ルートは一度も動きませんでした。必要なかったからです。
| 前景グレー | Weber コントラスト | CER(デフォルト) | CER(adjust_contrast=1.0) |
|---|---|---|---|
| 0(黒) | 1.000 | 0.0833 | 0.0833 |
| 64 | 0.749 | 0.0833 | 0.0833 |
| 110 | 0.569 | 0.0833 | 0.0833 |
| 150 | 0.412 | 0.1042 | 0.1042 |
| 180 | 0.294 | 0.0625 | 0.0625 |
| 200 | 0.216 | 0.0417 | 0.0417 |
| 220 | 0.137 | 0.0417 | 0.0417 |
Weber 0.14 まで下がっても CER はクリーン帯から外れません。つまり、白地に灰色 220 のような、よく見ないと読めないレベルでも普通に読めました。しかもコントラスト増強列は各段階でデフォルト列とまったく同じです。なぜなら、デフォルトの時点ですでに成功していたからです。
背景でも同じでした。黒文字のままです。
| 背景 | CER |
|---|---|
| 単色の薄い青のパネル | 0.083 |
| 縦方向グラデーション | 0.021 |
| ガウシアンノイズ(μ200、σ22) | 0.000 |
このセットで最もノイズが強いフィクスチャでも、完全一致でした。
ただし、対象範囲は狭いです。ここでの低コントラストは、単色でノイズのない描画であって、センサーノイズや JPEG 圧縮を含む実写のレシートではありません。このフィクスチャ群では、最も大きな失敗を生んだのは幾何と短いトークンであり、色や synthetic ノイズの変種はそうではありませんでした。
実例:ダッシュボードスクリーンショットから数値を取り出す
実際の Python OCR は、結局こういう用途で使われることが多いです。社内ダッシュボードのスクリーンショットが送られてきたり、Python scraping pipeline でグラフ中心の分析ページを処理していて、数値が描画ピクセルとしてしか存在しないときに、それをデータとして取り出したいわけです。
私は「Sales Dashboard」風のウィンドウ――タイトル付きのダークヘッダーと丸いアバターバッジ、3つの KPI パネル、3つのボタン、2×3 の表――を描画し、19個すべてのテキスト要素を正確な文字列とピクセル座標つきでラベル付けしました。そのうえで、ボックスの重なりを使って EasyOCR の出力と対応づけました。
検出再現率は 19中16。 見逃した3つは次のとおりです。
- 1文字のバッジ 「A」
- 表セル 「Q1」
- 表セル 「Q2」
一方で 「Q3」 は検出されました。フォントもサイズも列も同じです。検出器は見た目が似たセルの間で、一部だけ取りこぼしました。出力はこの実行では決定論的だったので、ランダムな「コイントス」挙動ではありません。関連するスクリーンショット品質の問題は #460 に記録されています。
検出できた16要素については、文字認識はかなり正確でした。平均 CER は 0.027、16中13が完全一致 です。タイトル、ラベル、ボタン("Save", "Cancel", "Export CSV")、列見出し、カンマ区切りの数値はすべて CER 0 で戻ってきました。1,284 も、カンマを含めて正しく読めました。
ただし、3つの不完全な読み取りはすべて同じ種類のエラーです。ドル表記です。
| 正解 | EasyOCR の読み取り |
|---|---|
$57,912 | S57,912 |
$18,330 | S18,330 |
$25,178 | S25,178 |
$12,004 | $12,004(正解) |
4件中3件のドル記号が大文字の S に化けました。見た目だけ見れば納得できなくもありませんが、抽出した通貨フィールドが1文字ずれて台無しになるということです。素朴な float() では全件エラーになります。
スクリーンショット処理に短いラベルや通貨が含まれるなら、拡大、余白付きクロップ、フィールド制約、記号を意識した後処理などの対策候補を必ず検証してください。ここではどれもベンチマークしていませんし、先頭の S を正規表現で置換するだけでは正当な値を壊す可能性があります。補正は、スキーマと検証ルールが安全性を保証できる場面だけに限定すべきです。
実行コスト
同じ機械での数値です(macOS arm64、CPU、単一ホスト、同時負荷の可能性がある条件で計測。絶対値ではなく傾向として見てください)。
| 指標 | 値 |
|---|---|
| ディスク上のモデル重み | 93.7 MiB(検出器 79.30 + 認識器 14.44) |
| 新規 CPU プロセスのピーク常駐メモリ | 984.5 MiB |
コールド状態の Reader() 初期化 | 1.3〜1.7 秒 |
| 1本のクリーンな48文字行に対するウォーム時遅延(p50) | 約0.062秒(p25〜p75: 0.059〜0.067秒、n=20) |
detail=0 と detail=1 | ほぼ同等(中央値 0.062 vs 0.063秒) |
主なコストは 94 MB の重みファイルではなく、約 2 GB の torch インストールに加えて、1プロセスあたり約1GBの常駐メモリ です。コンテナに収まるかどうかを決めるのはこの数字で、ここはあまり語られません。
速度は簡単なケースなら十分です。CPU 上で、クリーンな1行がウォーム時に 0.1 秒未満なら実用的といえます。ただしそれはあくまで簡単なケース――短く、コントラストの高い1行――の話です。「CPU で EasyOCR が数十秒かかる」 という不満は、大きな複数領域文書をフルキャンバスで処理した場合の話で、私は再現していません。条件が違うので、ここでは再現したとは言っていません。
ひとつ小さな神話を壊しておくと、detail=0 は EasyOCR を速くしません。返り値からボックス座標と信頼度を外すだけです。計算はもう終わっています。中央値の差は1ミリ秒程度で、ノイズの範囲です。
長所と短所
長所
- クリーンなラテン文字に対する文字再現性はかなり高い。大小文字区別ありで平均 CER 0.071、無視時 0.024、16 px では CER 0 を達成。
- 本当に2行の API。
Reader(['en'])のあとにreadtext()、設定不要、モデル選択不要。 - 俗説よりかなりコントラスト耐性が高い。クリーンテキストでは Weber 0.14 まで崩れず、ノイズ・グラデーション・色付き背景でも劣化しなかった(ガウシアンノイズのフィクスチャは完全一致)。
- 検出できたスクリーンショット要素ではかなり優秀。平均 CER 0.027、16中13が完全一致、カンマ区切りの数値も含む。
- 決定論的。このレポートの精度値は、完全に独立した2回のプロセス実行でバイト単位まで同一でした。変わったのは時間だけです。
- Apache-2.0 かつセルフホスト可能。ベンダー利用料はなく、かかるのは計算資源・メモリ・保存・キューイングだけです。
短所
min_size=10の下で急激に崩れる。8 px で CER 0.77。小さい UI 文字はデフォルトでは見えません。- 傾き耐性は約10°までで、20° で崩壊。
rotation_infoは対称な修正ではない。270° は回復、180° は部分的、90° は悪化して鏡写しの文字列を返す。- 検出器が短い単独トークンを落とす。1文字のバッジと2文字セル2つを落としつつ、同じ形式の別セルは残った。
- 通貨値で
$を体系的にSと誤読する(4件中3件)。 - プロセスあたり約1GBの常駐メモリに加えて、約2 GB の torch 依存。
- 最新リリースは 2024年9月。プロジェクトは活発に大きく変わるというより、安定寄りです。
誰に向いていて、誰は離れたほうがいいか
入力が、正立していて十分なサイズのクリーンな描画テキスト――スクリーンショット、UI キャプチャ、ラスター化 PDF、生成レポート――で、ベンダー利用料のないセルフホスト型 Python パイプラインが欲しいなら、EasyOCR を評価する価値があります。ここでの synthetic な英語・CPU 結果はその条件に対応します。写真、手書き、他スクリプトは別途テストが必要です。
次のどれかに当てはまるなら、見送るほうがいいでしょう。写真――今回の数値は synthetic に描画したテキストで、カメラノイズ、遠近、照明については何も言えません。手書き――プロジェクト自身が対応を主張していません。非ラテン文字――EasyOCR は80以上の言語をサポートしていますが、私が試したのは1言語だけで、比較の基準はここでは公開学術比較です。任意角度に回転した入力――自前で向き補正しない限り。メモリ制約が厳しい環境――ワーカー1つあたり1 GB はすぐ積み上がります。
OCR を選ぶ前に、DOM とネットワーク応答を確認してください。欲しい値がすでに構造化テキストとして存在するなら、そのソースを直接抜き出すほうが、OCR の検出・認識エラーを避けられます。OCR は、ピクセルしか残っていない場面で使うものです。
代替案と、私たちのスタックの位置づけ
EasyOCR は Apache-2.0 でセルフホスト可能。ベンダー利用料はありませんが、計算資源と運用コストは現実にかかります。PaddleOCR、Tesseract、vision-language model はこのベンチでは試していないので、直接比較の結論は出していません。
より大事な比較は OCR 同士ではなく、そもそも OCR をやるべきかどうかです。
私が見るスクリーンショット抽出の多くは、そもそもスクレイプしづらい Web ページへの回避策です。JavaScript 描画の表、ログイン背後のダッシュボード、抵抗の強いサイト――スクリーンショットを撮って OCR にかけるのは一番楽に見えますが、せっかくの構造化テキストを捨てて、より質の低い形に戻すためにドル記号税を払っているようなものです。
著者注: Thunderbit は、Web ページから抽出するための当社の管理型オプションです。今回の画像フィクスチャでは評価していません。重要な境界はソースの表現です。構造化された Web データがあるなら DOM/ネットワーク抽出を使い、ピクセルしかない場合に OCR を評価してください。
同じテストベンチからの関連読み物としては、オープンソーススクレイパーの総合比較、Crawl4AI レビュー、そしてセレクタに抵抗するページ向けの AI 駆動抽出 があります。
結論
EasyOCR を使うべきか。はい、画像が正立していて、文字の高さが少なくとも 12 ピクセルあり、ラテン文字を読んでいるなら、かなり優秀です。クリーンテキストで平均 CER 0.071、大小文字を正規化すれば 0.024、16 px では完全一致、しかも評判よりコントラスト耐性があります。API は本当に2行で、出力が決定論的である点も、パイプラインのデバッグでは思った以上に大事です。
ただし、その範囲を外れると、ちゃんと学習できるタイプの失敗をします。10 px 未満の文字は min_size フィルタに消えます。20° を超える傾きで読み取りは崩れます。rotation_info は1つの直交向きを救い、別の向きを半分だけ救い、3つ目は鏡文字で悪化させます。1文字や2文字のトークンは、隣が残っていても検出器から落ちます。ドル記号は S になります。
今回のフィクスチャの失敗は、幾何側のボックス取りこぼしや向きのズレと、認識側のドル記号混同の両方から起きました。拡大、向きの正規化、余白付きクロップ、スキーマを意識した記号修正は、必ず検証すべき候補として扱ってください。万能で安全な修正だと思い込まないことです。
ただし、壊れた評価ハーネスと、意味を理解していない数値で試すようなことはしないでください。私が危うくやりかけたように。自分でフィクスチャを描画し、正解を正確に把握し、自分の断崖を見つけてください。
Web データ抽出に Thunderbit を試す Get Started Free
よくある質問
EasyOCR は本番のスクリーンショット文字抽出に十分な精度がありますか?
synthetic なダッシュボードでは、対応づけできた要素の平均 CER は 0.027、16中13が完全一致でした。一方で19要素中3つは検出されず、4件中3件のドル記号が S になりました。これが許容できるか、また拡大やスキーマを意識した修正が効くかは、対象レイアウトで検証する必要があります。
EasyOCR が読める最小フォントサイズはどれくらいですか?
実用上は、描画後の文字高さでおよそ 12 ピクセルです。readtext() の min_size=10 は 10 px 未満のボックスを捨てるため、挙動は滑らかな減衰ではなく断崖になります。8 px で CER 0.77、10 px で 0.15、12 px で 0.04、16 px で 0 でした。私のスイープでは 12〜28 px がクリーン帯でした。HiDPI スクリーンショットを1倍で撮ったり、PDF を 72 DPI でラスター化しているなら、min_size を下げるより先に拡大してください。あのフィルタは不要な検出を抑えるためにあるからです。
rotation_info は EasyOCR で回転画像を直してくれますか?
安定してはいませんし、対称でもありません。rotation_info=[90,180,270] を同じ文の3つの直交回転画像に適用したところ、270° はきれいに回復(CER 0.83 → 0.10)、180° は部分的に改善(0.85 → 0.67、ただし一部フレーズは消失)、90° は 悪化(0.81 → 0.92)し、VOW → MOA のような鏡文字を返しました。さらに、小さな傾きには何の効果もありません。列挙した角度でしか再試行しないからです。EasyOCR を呼ぶ前に向きを補正するほうが安全です。
EasyOCR にはどれくらいのメモリとディスク容量が必要ですか?
重みファイルは 93.7 MiB で、初回利用時に ~/.EasyOCR/model/ にダウンロードされます。内訳は検出器 79.30 MiB と英語認識器 14.44 MiB です。実測した新規 CPU プロセスのピーク常駐メモリは 984.5 MiB で、そこに約 2 GB の torch インストールが上乗せされます。コールド状態の reader 初期化は 1.3〜1.7 秒でした。クリーンな1行なら、この機械では p50 で約 0.062 秒です。detail=0 は返り値の形を変えるだけで、実行時間は変わりません。
EasyOCR は商用利用無料ですか? まだ保守されていますか? Apache-2.0 ライセンスなので、商用利用にかなり使いやすいです。2026年7月27日時点では、リポジトリは 29,825スター、オープン issue 528件、最新リリースは 2024年9月の v1.7.2、master への最後の push は 2025年12月でした。放置というより安定状態と見るのが妥当です。アーキテクチャはしばらく大きく変わっておらず、活動は issue tracker 側に寄っています。使う前に、必ず現在の license とリリース状況を自分で確認してください。


