每个人都给出的关于扫描文本的建议是使用最高分辨率并获得正确的照明。 我运行这个网站使用的引擎对一组故意损坏的图像来找出这些问题中的哪些,答案都不是。 同一句话完美地从原始大小的三分之一的图片中得出,完美地来自灰色背景中的灰色文本,完美地来自以质量 25 保存的 JPEG。 破坏它的是将页面倾斜了五度。 下面的每个数字都来自那次跑步,他们指向的清单与通常的清单不同。
TL;博士: Tesseract 读取清晰呈现的文本,直到出现两个特定的问题。 倾斜是第一个:0 到 3 度的偏斜给出了 0% 的字符错误率,5 度给出 2.9%,12 度给出 16.7%,20 度给出 32.4%。 大小是第二个,它是一个悬崖而不是一个斜坡:文本保持完美到大约 7 个像素的大写高度,然后在 5.8 像素处折叠到 85.3% 的错误。 低对比度、模糊和重型 JPEG 压缩几乎没有注册。 在你做任何其他事情之前把图片拉直。 那个 图像到文本转换器 在浏览器中运行引擎,因此图片永远不会上传。
这些数字是如何产生的?
通过渲染一个已知的句子,一次以一种方式损坏图像,回读它,并计算修复结果所需的编辑。
度量是字符错误率:图像所说的内容与引擎返回的内容之间的Levenshtein距离除以真值的长度。 50 个字符的行上的 2% 错误率是一个错误的字符。 文本是三行混合散文、发票编号、日期、货币金额、电子邮件地址和电话号码,因为在实践中重要的错误发生在第二种内容中而不是第一种内容中。
一个警告属于顶部而不是埋在顶部。 这些是渲染的图像,而不是照片。 每个变量都隔离了一个变量,这是将失败归因于原因的唯一方法,但页面的真实照片同时出现了几个:折叠处的轻微倾斜、不均匀的光线、在一个边缘的运动模糊以及在保存之前使所有内容都锐化的相机。 因此,以下阈值是最佳情况。 一张正好在两个轴上的照片会比任何一个数字所暗示的要糟糕。
引擎是通过 tesseract.js 是 Tesseract 4's LSTM 模型,这正是该工具运行的,因此这些不是来自不同系统的数字。
多少偏斜太过分了?
三到五度之间,比你注意到的要少。
| 轮转 | 字符错误率 | 报告的信心 |
|---|---|---|
| 0度 | 0.0% | 95 |
| 1 度 | 0.0% | 95 |
| 2 度 | 0.0% | 95 |
| 3 度 | 0.0% | 94 |
| 5 度 | 2.9% | 91 |
| 8 度 | 7.8% | 82 |
| 12度 | 16.7% | 70 |
| 20度 | 32.4% | 66 |
三度没有发生任何事情,然后它从架子上掉下来。 原因在于引擎的工作方式:它找到文本行,然后将每行切成字符。 一条倾斜的线穿过几排像素,因此切片穿过一些字母的顶部和其他字母的底部,并要求模型对片段进行分类。
在 5 度时,误差很小且昂贵。 “过时”作为“日期”和“总”作为“总”返回。 两者都是一个人可以直接阅读的单词中的一个字母,并且都坐在发票号码和一个人将要复制的货币金额旁边,而不检查。
手持一页的手机通常会用五度以上的时间。 这是在运行任何东西之前都值得修复的唯一问题,并且修复是免费的:旋转图片直到线条水平。
在 OCR 失败之前,文本有多小?
比您预期的要小,直到它完全停止工作。
| 图像宽度 | 大写字母高度 | 误差率 | 信心 |
|---|---|---|---|
| 1600 像素 | ~29 像素 | 0.0% | 95 |
| 800像素 | ~14 像素 | 0.0% | 95 |
| 533 像素 | ~10 像素 | 0.0% | 92 |
| 400 像素 | ~7个像素 | 0.0% | 84 |
| 320 像素 | ~6 人机 | 85.3% | 41 |
| 240 像素 | ~4个像素 | 100.0% | 0 |
同样的三行在原始大小的四分之一处完美地读出,每个大写字母大约有七个像素高。 再往下一步,输出无法使用,然后空置。
那是一个悬崖,而不是一个渐变,它改变了建议。 “使用你拥有的最高分辨率”是没有错的,但它描述了大多数图片没有的问题。 网页的截图,标志的照片,打印的字母的电话图片:所有这些都远远超过七个像素的字母高度。 他们更经常拥有的是倾斜。
悬崖确实咬的地方是远处的作物。 节日照片背景中的文字,街对面的标志,屏幕分辨率的整页扫描中的一条小字体。 如果您在 100% 变焦时难以阅读这些字母,则发动机也靠近其地板。
低对比度会破坏阅读吗?
不,这是最与我预期相矛盾的结果。
#8a8a8a 的灰色文本在#BDBDBD 的灰色背景上以 0.0% 的错误率和 95 的置信度进行回读,与白色的黑白相同。 整个图像的三像素高斯模糊给出了 0.6%。 以质量 25 保存并缩放到一半尺寸的 JPEG 得出 0.0%。
原因是引擎不读你的灰色。 它首先将图像二元化,将所有图像都变成黑白,并从图片中选择了一个阈值,并且统一的低对比度完好无损地保存下来。 无法生存的是在页面上不同的对比度,这是阴影或手机闪光产生的:一个阈值不能适合图像的两半。
因此,照明建议的有用版本比通常的要窄。 甚至照明也很重要。 明亮的灯光没有。 一张昏暗、均匀亮的页面照片击败了一张明亮的照片,中间有一个阴影。
为什么两列布局会被混淆?
因为阅读顺序是布局判断,引擎仅从几何形状中进行。
我并排渲染了两个文本块,每行三行,在共享基线上。 结果交错了:
LEFT ONE RIGHT ONE LEFT TWO RIGHT TWO LEFT THREE RIGHT THREE
每一个字都是正确的。 订单无用。 引擎发现六行文本位于三个垂直位置,并读取每一行,这是一张表格的正确行为,而对两列散文进行错误的行列。
真正的报纸页面或学术 PDF 经常存在,因为列之间的阴沟很宽且足够一致,可以检测到页面分割步骤。 一个布局的屏幕截图和两个松散的块并排,这是这种工具的常见情况,通常不会。
可靠的解决方案是裁剪。 运行一列,复制结果,然后运行另一列。 这听起来很费力,大约需要十五秒,这比重建一段句子被洗牌的段落还要少。
能读字吗?
不可靠,边界是关于字母是否触动而不是它们看起来是否非正式。
如果不提供照片,我无法测试真实的笔迹,这将具有混合变量,因此我测试了三种降低规律性的字体作为替身:
| 字体 | 误差率 | 信心 |
|---|---|---|
| 漫画 sans MS | 0.0% | 95 |
| 画笔脚本 mt | 5.9% | 67 |
| 斯内尔 圆形手 | 20.6% | 55 |
Comic Sans 是非正式的,对引擎来说是完全清晰的,因为它的字母是宽度一致的独立形状。 Snell Roundhand 是一个连接的脚本,五分之一的角色回来了。
这是真正的区别。 Tesseract 的模型经过印刷类型的训练,并希望将一条线切割成离散的字形。 连接书写没有干净的切割点,因此在识别获得机会之前分割失败。 真正的笔迹比 Snell 圆手要差,不是更好,因为它也不同字母。
如果您需要手写阅读,这是错误的工具,其他所有 tesseract 前端也是如此。 该工作需要一个受过笔迹训练的模型。
哪些角色出错了?
看起来像数字的字母,方向是一致的。
我渲染了通常的嫌疑人的一行,并读回了它:
truth: O0 l1I 5S 8B 2Z rn/m
read: 00 111 5S 8B 2Z rn/m
资本 O 变成零。 小写 l 和大写字母 i 都变成了数字 1。 两人最担心的是,5对S和8对B,正确地回来了,RN对M对阵M。
模式是一个带有数字字形字形的孤立字母被读作数字。 在运行散文中,这很少重要,因为它周围的语言模型将结果拉回单词。 在参考代码、序列号或许可证中,没有周围的词可以提供帮助,这正是这种工具的使用方式。
校对任何混合字母和数字的字符串,没有空格。 这是发动机确信错误的一类输出。
信心分数告诉你什么?
大致页面的去向,而不是您关心的数字是否正确。
该工具显示引擎的平均单词置信度为高、中或低,高为 85 及以上。 针对测量的错误率,该映射在边缘是广泛明智和乐观的:
| 函 | 信心 | 标签 | 真实错误率 |
|---|---|---|---|
| 潔 | 95 | 峣 | 0.0% |
| 5 度偏斜 | 91 | 峣 | 2.9% |
| 12度偏斜 | 70 | 方法 | 16.7% |
| 320像素宽 | 41 | 忧愁 | 85.3% |
| 连接脚本 | 55 | 忧愁 | 20.6% |
低分是一个可靠的警告:所有得分低于 60 分的东西都被真正破坏了。 高分是比看起来更弱的证据。 5 度的案例得分 91,接口称之为高,同时在发票行中悄悄地破坏一个单词。
将其用作烟雾报警器而不是保证。 低意味着不要费心读取输出。 高意味着整个页面进展顺利,这与每个角色的正确性不同。
每种语言下载多少钱?
0.67 到 2.82 兆字节之间,一次,然后缓存。
引擎需要每种语言的训练有素的数据文件。 因为该工具仅运行 LSTM 模型,因此它会拉出整数化的最佳质量集,这比 OCR 写入的文件要小得多。 从 CDN 中测量的库默认为:
| 语言 | 下载 | 语言 | 下载 |
|---|---|---|---|
| 英语 | 2.82 MB | 印地语 | 1.32 MB |
| 俄国人 | 2.56 MB | 孟加拉人 | 1.31 兆 |
| 西班牙人 | 2.00 MB | 朝鲜人 | 1.50 MB |
| 日本 | 1.94 兆 | 德国人 | 1.27 兆 |
| 中文(简体) | 1.64 MB | 葡萄牙人 | 1.33 兆 |
| 阿拉伯人的 | 1.58 MB | 意大利人 | 1.58 MB |
| 法国风味 | 0.67 兆 |
十三人合起来大约 21 MB,这还不到一张现代手机上的照片。 中文或日语必须是巨大的普遍假设在这里不成立:简体中文为1.64 MB,比英语小,因为文件存储的是模型而不是字形库。
为什么第一次跑步比第二次慢?
因为第一个是下载和启动引擎,第二个只是阅读。
第一次运行一种语言是获取 tesseract 的 WebAssembly 构建,获取该语言的数据文件,并初始化一个工作者。 之后,工作人员在页面中保持活跃状态,数据文件由浏览器缓存,因此同一语言中的第二张图像立即开始。 切换语言会重新初始化工作人员,但不会重新下载已经获取的任何内容。
识别本身很快。 在这台机器上,读取三行测试图像的清洁版本需要 186 毫秒,损坏的版本需要 70 到 125 毫秒,所有这些都在已经运行的工人身上。 对于一整页的文本,需要一两秒而不是十分之一,但您注意到的第一次运行等待是设置,而不是阅读。
一旦一种语言被缓存,该工具根本没有网络,这是一种真正的离线功能,而不是营销线。
在运行 OCR 之前,您应该对图像执行什么操作?
三件事,按这个顺序,第一件事比其他两个更重要。
- 把它拉直。 旋转直到文本行水平。 三度是免费的,五个不是。
- 裁剪到文本。 这解决了列问题,删除了分割器必须拒绝的背景,并使文本在框架中的份额更大。
- 别管其他一切。 不磨,不提高对比,不要用手转换成黑白。 无论如何,发动机是二值化的,磨锐过滤器在字母边缘周围增加了响铃,以前不存在的字母边缘环绕。
值得添加而不是删除的东西是分辨率,但前提是您靠近地板。 从 7 像素的资本高度到 14 像素的高度,测量值没有任何变化。 从 6 到 7 改变了一切。
OCR 什么时候是错误的工具?
当图片不是文本时,当文本是手写的,当您想要的东西是可搜索的文档而不是字符块时。
OCR 为您提供没有结构的单词:没有标题、没有表格单元格、您可以信任的段落边界、复杂布局中的阅读顺序。 获取截图中的引用或完全正确的照片中的地址。 要将扫描的报告转换为可编辑的内容,这是几个步骤中的第一个。
如果您想要的是对图片的描述而不是打印中的文字,那是完全不同的模型和不同的工具。 如果源是生成的而不是扫描的 PDF,则文本已在文件中:直接拉出它会保留布局并且不会丢失任何图像识别无法匹配的内容。
为什么会在浏览器中运行?
因为人们通过 OCR 发送的图片是他们最不想上传的。
收据、银行信件、处方、护照、身份证、合同照片、私人谈话的截图。 通常的替代方案是获取您的图像的站点,在您一无所知的服务器上处理它,并保留它保留的任何内容。
引擎是在页面中运行的 WebAssembly,在一个工作人员中。 图像被解码到制表符内存中,在那里读取,文本出现。 没有上传,没有队列,也没有存储的副本,并且在第一次运行之后整个事情离线工作。 成本是一次性语言下载,非常大的图像受限制选项卡的内容限制。
这个网站还没有做的两件事,它们属于同一条管道:拉直照片页面并将其裁剪成文本。 两者都必须发生在您已经拥有的任何查看器中,这是上述工作流程中的一个尴尬接缝。 后面的内容包括:如果源是几页的照片, 图像组合指南 处理结果重新组合在一起。



