EasyOCR 是 JaidedAI 推出的即装即用 Python OCR 库:pip install easyocr,两行代码,就能把图片里的文字提取成字符串。它采用 Apache-2.0 许可,支持 80+ 种语言,底层是一个由两个 PyTorch 模型组成的流水线——先由 CRAFT 检测器找出它认为是文本的区域并画框,再由识别器读取每个框里的字符。预训练权重会在你第一次调用时自动下载。从形态上看,它是 Tesseract 和 PaddleOCR 的自托管替代方案,而不是按页面计费的云 OCR API。
基础 API 非常短:Reader(['en']),然后 readtext()。但部署成本并不小——在这个环境里,PyTorch 本体大约占 2 GB,实测一个全新进程的峰值常驻内存接近 1 GB。我渲染了 36 张英文 PNG 测试样本,在 CPU 上运行 easyocr 1.7.2,并逐字符对照生成的真值计算得分。尺寸和方向是导致字符错误率(CER)断崖式上升的主要因素;仪表盘测试还暴露了短 token 检测和美元符号识别的问题。
其中最明显的失败,正好发生在大家最常推荐的那个参数上。rotation_info 在社区里一直被当作处理旋转图片的“万能解法”,所以我给同一句话做了三个正交旋转版本。结果在 270° 时,它确实做到了宣传中的效果,把字符错误率从 0.83 降到了 0.10。到了 180°,它只算部分生效:从 0.85 降到 0.67,但有一整个短语被漏掉了。到了 90°,情况反而更糟,0.81 上升到 0.92,识别器甚至开始返回镜像文本。还是同一个参数、同一组角度,却出现三种不同结果——所以把它打开,并不等于“旋转问题已解决”。同样的 36 个样本还暴露出一个清晰的字号临界点、一个系统性的美元符号误读,以及一个我原先判断完全错误的结论。
两个模型,套在一件大衣里
EasyOCR 不是单一模型,而是两个模型串起来的流水线。你得先知道是哪一段出了问题,排查才有方向。
第一段是 CRAFT,也就是检测器。它的职责只有一个:判断图像里哪里有文本,并把框返回出来。它不会识别任何字符。第二段是 CRNN 识别器——先做 ResNet 特征提取,再经过 BiLSTM,最后用 CTC 贪心解码——负责读取每个框中的字符。两段都运行在 PyTorch 上。在 CPU 模式下,识别器默认会进行动态 int8 量化,所以它比原始参数量看起来更快、更轻。

实际影响很直接:EasyOCR 有两种完全不同的失败模式,对应的修复方式也不一样。如果检测器根本没画出框,那你怎么调识别器都没用——字符压根没进入流水线。如果框是有的,但字符串错了,那就是识别阶段的问题,预处理可能还能救回来。我读过的几乎所有“EasyOCR 漏掉了我的文字”的讨论,往往都把这两类问题混为一谈。
截至 2026 年 7 月 27 日查看的项目状态:29,825 个星标、528 个开放 issue、Apache-2.0 许可,当前版本是 v1.7.2(2024 年 9 月发布),master 分支的最后一次推送是在 2025 年 12 月。这些日期并不能证明架构稳定,也不能证明维护健康。在决定采用前,请务必确认它与你的 Python/PyTorch 环境兼容,维护者近期是否有响应,以及与你输入类型相关的 issue 是否已有处理。
OCR 经常会被和 CAPTCHA 破解混在一起,但这不是本文的使用场景。这里没有测试任何 bot-detection 挑战,也不鼓励绕过它们。本文讨论的工作,是从你有权限读取的图片和截图中识别文字。
我测了什么,以及这些数字没覆盖什么
测试集是我自己渲染的 36 张 PNG:35 张单行图片,覆盖七种字体、八种字号、七个对比度等级、七个倾斜角、三种正交旋转,以及三种背景;外加一张合成的仪表盘截图,包含 19 个单独标注的元素。每张图都来自同一个固定字符串(Sphinx of black quartz, judge my vow. 1234567890——48 个字符,包含大小写、数字和标点),并且在生成标签的同一过程中写入 ground truth,因此图像和标签不会发生漂移。
准确率使用的是 字符错误率(CER):字符级 Levenshtein 距离除以真值长度。CER 为 0 表示完全正确;CER 为 0.10 表示大约每 10 个字符错 1 个。我在标题里报告大小写敏感的 CER,同时附上忽略大小写后的结果,因为问题大多其实出在大小写上。
但边界比数字更重要:
- 仅英文。 使用的是
english_g2识别器。EasyOCR 宣称支持 80+ 语言,而我只测试了一种。这并不代表非拉丁文字;那些领域真正有参考价值的是公开的学术 OCR 对比。 - 仅合成文本。 是渲染出来的文字,不是照片。没有相机噪声、JPEG 压缩、光照或透视变化。
- 不含手写体。 项目本身也明确表示尚不支持手写识别。
- 仅 CPU。 macOS arm64,
gpu=False。这台机器虽然有 MPS,但 EasyOCR 在非 CUDA 环境下只会走 CPU。GPU 性能没有测,因此本文不会给出任何 GPU 数字。 - 单机单版本。 easyocr 1.7.2、torch 2.13.0、Python 3.12。
所以:这些是受控的单变量曲线,准确展示“什么时候会开始崩”,而且是在干净的、渲染出来的拉丁文字上得出的。它们不是现实世界语料库的总评分,也不能替代那种评分。
相关证据是可直接查看的,而不是被锁在 notebook 里。样本生成器和精确字符串在 tests/build_fixtures.py 和 tests/fixtures/ground_truth.json 中;识别、耗时和资源采集逻辑在 tests/run_easyocr.py;tests/metrics.py 则根据原始输出计算文中展示的错误率。最终的识别记录和汇总指标保存在 artifacts/raw/。重新跑一遍这条链路,有助于核对这台机器和这个版本的表现。但它仍然无法回答 EasyOCR 在你的手机照片、语言、版式或预处理流水线中的表现,因此生产环境验收应加入与你真实场景相近的输入,而不是把这些样本当成认证套件。
这里有一个值得提醒的测试陷阱,因为它差点让我得出错误的标题结论。我的第一次指标统计得到的是黑底 Arial 的 CER 0.375,这对最简单的输入来说糟糕得离谱。问题不在 EasyOCR,而在我的评估逻辑:检测器把同一行拆成了单词框和数字框,而我用“先按 y、再按 x 排序再拼接”的朴素方法时,把数字排到了前面。改成按行感知分组(先按垂直重叠把框归为一行,再从左到右读取)之后,干净字体的 CER 回到了大约 0.04–0.10。要做自己的 OCR 评估,这个坑你也很可能会踩。
安装:包很小,依赖却不小

pip install easyocr
就这么简单,但它几乎没有把真实成本说完。这个包本身很轻量,真正带来的负担是 PyTorch,大约 2 GB。然后你第一次调用 readtext() 时,EasyOCR 会静默把权重下载到 ~/.EasyOCR/model/ —— 总计 93.7 MiB,其中 CRAFT 检测器是 79.30 MiB(craft_mlt_25k.pth),英文识别器是 14.44 MiB(english_g2.pth)。
教程里通常不会特别说明这一点,所以:第一次运行需要联网,而且下载期间会停顿;任何容器化部署要么把这些权重预先打进镜像,要么在冷启动时承受下载开销。一旦缓存完成,后续就可以离线运行了。
冷启动的 Reader() 初始化——模型从磁盘加载进内存,再加上 int8 量化步骤——在多次运行中耗时 1.3–1.7 秒。之后只需要:
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
就能用了。两行代码,不用额外配置,也不用自己去找 checkpoint。这个阶段里,名字里的 “easy” 确实名副其实——真正的摩擦都来自依赖体量,不在 API 本身。
干净文本的下限:字符几乎全对,但大小写会漂
七种系统字体,黑字白底,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。另一个常见错误是标点:句尾句号在几种字体里会被识别成 : 或 _。Georgia 在你不再在乎大小写之后,读得完全正确。
这很值得知道。如果你的下游步骤是模糊匹配、关键词搜索,或者把文本送进语言模型,大小写变化几乎没什么损失。但如果你的下游要和数据库键做精确字符串比较,那影响就很大了。比较之前先统一大小写,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,CER 从 0.04 直接跳到 0.77,这不是渐进式退化,而是一个过滤器严格按文档工作后的结果。也就是说,低于大约 10 px 的文本,默认 EasyOCR 几乎等同于看不见。
最佳区间是 12–28 px,其中 16 px 时整段 CER 为 0。到了 40 px 以上,CER 又开始轻微回升——不是字符丢了,而是 vow → VOW 的大小写翻转重新出现了。大字号并不更难读,只是它不再享受到 16 px 时那种刚刚好的字距优势。
如果你要从截图中抽文字:先检查渲染字高,再决定要不要怪模型。 在 HiDPI 显示器上以 1× 方式截取的仪表盘,或者以 72 DPI 栅格化的 PDF 页面,正文文本经常会低于 10 px。改成 2× 截图或先放大再 OCR,通常就能避开“EasyOCR 漏掉半页内容”这一类报错。如果实在做不到,再考虑调低 min_size——但要做好噪声上升的准备,因为这个过滤器本来就是用来压掉垃圾检测的。
旋转:只有 10° 容忍度,而且修复并不对称
先看倾斜。小角度、Arial 32 px、默认设置 vs 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 | 是 |
同一个参数,同一组角度,却出现了三种结果。
在 270° 时,rotation_info 确实做到了 issue 讨论 里承诺的效果:CER 从 0.83 降到 0.10,已经是很实用的读法了。在 180° 时,只能算部分生效——CER 降到 0.67,但短语 my vow. 被整段丢掉。在 90° 时,它反而从 0.81 恶化到 0.92,原始输出也说明了原因:识别器返回的是镜像字符串。VOW 变成了 MOA,quartz 变成了 zuuenb。在镜子里读这些词,它们是对的;但放在数据管道里,这就只是个无用的花活。
我没有把这归因于拼接顺序错误,而是直接看了原始预测,因为我最初也怀疑是“拼接时把顺序弄乱了”。但事实不是拼接问题——这就是 EasyOCR 真正返回的内容。
其机制只是一个假设,不是测量结果;我并没有做旋转约定的专门实验。Pillow 渲染正角度时是逆时针,因此只有 270° 的渲染图恰好和识别器能处理的重试方向对上,而 90° 那张图最佳得分的重试则落到了翻转方向。不管具体机制是什么,实际结论都不会变:
这个样本说明,不能假设 rotation_info 在不同方向上表现对称。你应该验证自己输入里真实会出现哪些旋转;如果可以,先在上游做方向标准化,这是一种值得尝试的缓解手段,但不是这三个样本所证明的“必需前提”。
我判断错的一点
我原本以为,低对比度会是 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 |
CER 一直都没有离开“干净”区间,哪怕 Weber 对比度降到 0.14——也就是白底上的灰 220,已经浅到我得眯着眼睛确认文字确实存在。而“增强对比度”这一列和默认列在每一步都一模一样,因为默认流程本来就已经成功了。
背景也说明了同样的事情。全程黑字:
| 背景 | CER |
|---|---|
| 纯浅蓝色面板 | 0.083 |
| 垂直渐变 | 0.021 |
| 高斯噪声(μ200,σ22) | 0.000 |
在这一组样本里,最噪的那个反而是完美识别。
不过这个范围很窄:这里说的是纯色、无噪声的低对比度图,不是带传感器噪声和 JPEG 压缩的拍照收据。在这组样本中,几何和短 token 才是主要故障来源;我测试过的颜色和合成噪声变化并没有把它弄坏。
一个真实场景:从仪表盘截图里提取数字
这其实才是 Python OCR 最常见的使用方式。有人发来一张内部仪表盘截图,或者你在一个图表很多的分析页面上跑 Python scraping pipeline,页面上的数字只以像素渲染存在,而你想把它们变成数据。
我渲染了一个“Sales Dashboard”窗口——深色标题栏、标题和圆形头像徽章、三个 KPI 面板、三个按钮、一个 2×3 表格——并把 19 个文本元素 全部用精确字符串和像素框标注出来,然后通过框重叠把 EasyOCR 的输出与之匹配。
检测召回率:16/19。 漏掉的三个是:
- 单字母徽章 “A”
- 表格单元格 “Q1”
- 表格单元格 “Q2”
而 “Q3” 被检测到了。同样的字体、同样的字号、同一列——检测器保住了一个两个字符的 token,却丢掉了另外两个。对外观非常相似的单元格,检测表现并不一致。由于这几次运行的输出都是确定性的,这并不能说明它有随机“掷硬币”行为。一个类似的截图质量问题在 #460 中有记录。
对那 16 个成功检测到的元素来说,文本几乎都完全正确:平均 CER 0.027,其中 13/16 是完全一致的。标题、标签、按钮("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(正确) |
四个美元符号里,有三个被识别成了大写 S。从视觉上说,这也不是完全离谱——但这意味着你提取出的每一个货币字段都只差一个字符就会变成垃圾,而朴素的 float() 会全部报错。
如果你的截图流程里包含短标签或货币字段,请验证像放大、加边距裁剪、限定字段预期、符号感知后处理这类缓解方案。本文没有对这些方案做基准测试,而且用正则把开头的 S 替换掉,可能会误伤合法值。只有在你的 schema 和校验规则足够安全时,再应用纠正。
运行成本是多少
同一台机器上的数字(macOS arm64、CPU、单机,在可能存在并发负载的情况下测得——请把它们看作趋势,而不是通用基准):
| 指标 | 数值 |
|---|---|
| 磁盘上的模型权重 | 93.7 MiB(79.30 检测器 + 14.44 识别器) |
| 全新 CPU 进程的峰值常驻内存 | 984.5 MiB |
冷启动 Reader() 初始化 | 1.3–1.7 秒 |
| 热路径延迟,单行干净 48 字符(p50) | 约 0.062 秒(p25–p75:0.059–0.067 秒,n=20) |
detail=0 与 detail=1 | 基本相同(中位数 0.062 vs 0.063 秒) |
最大的成本不是那 94 MB 权重,而是每个 worker 进程大约 1 GB 的常驻内存,再叠加约 2 GB 的 torch 依赖。这才是决定它能不能塞进容器里的关键数字,但很少有人会提它。
速度在容易场景下是可以接受的。CPU 上一行干净、单条、热状态下不到 0.1 秒,完全可用。但这确实是最容易的情况:一行、短文本、高对比度。社区里反复出现的 “EasyOCR 在 CPU 上要几十秒” 抱怨,通常对应的是大面积、多区域、整张画布级别的文档;我没有复现那种场景——那是不同工作负载,我这里只是引用它,而不是声称我已经验证过。
顺带澄清一个小误区:detail=0 并不会让 EasyOCR 更快。它只是把边界框和置信度从返回值里去掉而已,计算本身已经做完了。中位数只差 1 毫秒,完全在噪声范围内。
优缺点
优点
- 在干净的、渲染出来的拉丁文本上,字符召回几乎完美——大小写敏感 CER 平均 0.071,忽略大小写后 0.024,在 16 px 时可以达到整段 CER 为 0。
- API 真的是两行:
Reader(['en'])然后readtext(),无需复杂配置,也不用手动挑模型。 - 对比度的鲁棒性比传闻中更强:在干净文本上,Weber 对比度降到 0.14 也没有崩;噪声、渐变和有色背景也没有让它明显退化(高斯噪声样本甚至是完全正确的)。
- 对检测到的截图元素表现非常好:平均 CER 0.027,16 个里有 13 个完全正确,包括带逗号的数字。
- 结果确定性强。本文里每个准确率数字,在两次完全独立的进程运行中都字节级一致;变化的只有耗时。
- Apache-2.0、自托管、没有厂商使用费;成本主要体现在算力、内存、存储和队列管理上。
缺点
- 低于文档所写
min_size=10下限时会直接崩掉——8 px 时 CER 0.77。小 UI 字体默认根本看不见。 - 对倾斜的容忍度大约只到 10°,到 20° 就基本失效了。
rotation_info不是对称修复:270° 能救回来,180° 只能部分恢复,90° 反而更差,还会返回镜像文本。- 检测器会漏掉孤立的短 token——一个单字母徽章和两个两字符单元格都丢了,但第三个格式相同的单元格却保住了。
- 货币值上的
$会系统性被误读成S(4 个里有 3 个)。 - 每个进程约 1 GB 常驻内存,再加上约 2 GB 的 torch 依赖。
- 最新发布是 2024 年 9 月;这个项目更像是稳定,而不是持续快速演进。
谁该用,谁该避开
如果你的输入是干净、正向、以合理尺寸渲染出来的文本——比如截图、UI 捕获、栅格化 PDF,或者生成型报表——并且你需要一个没有厂商使用费的自托管 Python 流水线,那么可以评估 EasyOCR。这里的英文 CPU 结果只适用于这条使用路径;照片、手写体和其他文字脚本需要单独测试。
如果你的输入符合以下任一情况,就该直接放弃:照片——我的数字都是合成渲染文本,不能说明相机噪声、透视或光照问题;手写体——项目本身就没有支持;非拉丁脚本——EasyOCR 虽然支持 80+ 语言,但我只测了一个,学术公开对比才是该领域的参考;任意旋转输入——除非你先自己做方向纠正;内存紧张的部署——每个 worker 一整个 GB,很快就会累积起来。
在决定是否需要 OCR 之前,先检查 DOM 和网络响应。如果你想要的值已经以结构化文本存在,直接从源头抽取,可以避免 OCR 的检测和识别误差。OCR 只适合那些只有像素这一种可用表示形式的场景。
替代方案,以及我们的技术栈放在哪
EasyOCR 采用 Apache-2.0 许可,自托管,没有厂商使用费,但它确实有真实的算力和运维成本。PaddleOCR、Tesseract 以及视觉语言模型都没有跑过这套基准,因此这里不会给出一对一结论。
更有意思的比较,不是 OCR 和 OCR 之间,而是你到底该不该做 OCR。
我见过的大多数截图提取需求,本质上都是在绕开一个“难抓”的网页:JavaScript 渲染表格、登录后才能看到的仪表盘、或者会反爬的网站。截图再 OCR 看起来像最省事的路,但其实你丢掉了原本就存在的结构化文本,又要为一个更差版本的数据付出额外代价,尤其还要承受美元符号这类识别误差。
作者说明:Thunderbit 是我们用于网页提取的托管方案。本文没有用这些图像样本测试它。关键边界在于源数据的表示形式:如果网页里本来就有结构化数据,就该用 DOM/网络提取;只有当像素是唯一来源时,才评估 OCR。
同一测试平台上的相关阅读:开源爬虫完整对比、Crawl4AI 测评,以及更广泛的 AI 驱动提取,适用于那些不太愿意配合选择器的页面。
结论
要不要用 EasyOCR?如果你的图片是正向的、字高至少 12 像素,而且识别的是拉丁文字,那答案是:可以。它在这个范围内表现很好——干净文本平均 CER 0.071,统一大小写后 0.024,16 px 时整段完全正确,而且对对比度的鲁棒性比口碑里说的更强。API 确实只有两行,而且结果是确定性的;当你在调试一条流水线时,这一点比很多人愿意承认的都重要。
但超出这个范围,它会以一些具体、可学习的方式失效。低于 10 px 的文本会被 min_size 过滤器吞掉。超过 20° 的倾斜会让识别崩溃。rotation_info 只能修复一个正交方向,另一个只能半修,第三个还会因为镜像文本而更糟。单字母和两字符 token 会从检测器里掉出去,而旁边的邻居却能幸存。美元符号会变成字母 S。
这些失败来自两个阶段:几何侧是框漏检或方向错了,识别侧是美元符号混淆。把放大、方向标准化、加边距裁剪,以及基于 schema 的符号修复,都当成需要验证的候选方案,而不是默认安全的修复。
只是别像我差点做的那样,用一个坏掉的评估脚本,去相信一个你根本没弄懂的数字。自己渲染样本,精确掌握真值,找到你自己的临界点。
试试 Thunderbit 做网页数据提取 Get Started Free
常见问题
EasyOCR 的准确率足够用于生产环境中的截图文字提取吗?
在这套合成仪表盘上,成功匹配的元素平均 CER 为 0.027,其中 16 个里有 13 个完全正确。19 个元素里有 3 个没被检测到,4 个美元符号里有 3 个变成了 S。这是否可接受,以及放大或基于 schema 的修复是否有效,都必须在你的目标版式上单独测试。
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。如果你的源数据是 1× 截取的 HiDPI 截图,或者 72 DPI 的 PDF 栅格图,应该先放大再 OCR,而不是去降低 min_size,因为这个过滤器本来就是为了压掉垃圾检测的。
rotation_info 能修复 EasyOCR 的旋转图片吗?
不能可靠修复,而且不对称。把 rotation_info=[90,180,270] 用在同一句话的三个正交旋转版本上,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,而 torch 依赖本身还要再占大约 2 GB。冷启动的 Reader 初始化用了 1.3–1.7 秒;在这台机器上,一行干净文本的 p50 热延迟大约是 0.062 秒。detail=0 只是改变返回结构,没有改变实测运行时间。
EasyOCR 适合商业使用吗?现在还在维护吗? 它采用 Apache-2.0 许可,宽松且适合商业使用。截至 2026 年 7 月 27 日,仓库有 29,825 个星标和 528 个开放 issue,最新版本是 2024 年 9 月的 v1.7.2,master 分支最后一次推送是在 2025 年 12 月。更准确地说,它是稳定而不是被遗弃——架构近来变化不大,活跃度更多体现在 issue 讨论上。在你基于它开发前,请自己再确认一次当前的 license 和版本状态。


