OCR 能读什么、不能读什么:从截图和扫描件里拿到能用的文字

Tesseract 读干净的印刷体准确率 99%,读手写大约 0%。决定结果的是什么——分辨率、对比度、语言模型、版面——以及怎么把图片准备好,让文字读得对。

一句话

OCR——光学字符识别——把长得像字的像素变成真正的文字。对一张清晰的印刷体照片或截图,它接近完美;对手写、花体字,或一张糊掉的菜单照片,它接近没用。本站的引擎是 Tesseract,在浏览器里跑,带 12 个语言包;图片留在你的设备上。多数糟糕的结果来自图片而不是引擎,而且在按下按钮之前就能修好。

引擎怎么工作

Tesseract 1985 年诞生于惠普,2005 年开源,2006 年起由 Google 维护。第 4 版(2018 年)用 LSTM 神经网络取代了逐字符分类器,一次读一整行,所以它能应付粘连的字母和比例字体——老引擎做不到。流程是:找到页面上的文字区域,切成行,每行过一遍网络,再由语言模型——词典加字母序列统计——在相似形状之间裁决(l、1、I;0、O)。最后这一步就是为什么选对语言要紧:用英文模型读德文,会把 straße“纠正”成 strasse 或更糟。

在浏览器里,引擎编译成 WebAssembly(约 4 MB),每个语言包 0.7–3 MB,第一次用时下载并缓存。中文和日文的包最大,因为要认识几千个字。

什么决定结果

分辨率。 Tesseract 希望字高在 30 像素上下;低于 20 网络就开始猜。手机拍一页纸没问题;400 像素宽的缩略图不行。非要 OCR 一张小图,先放大两倍——不增加信息,但给找行的算法留出余地。

对比度和均匀度。 白底黑字,光线均匀。台灯下拍的一页纸中间亮、四角发灰;引擎用一个阈值二值化整张图,页面的一侧就消失了。在平光下拍,或者用扫描。

摆正。 引擎能纠正几度的倾斜。斜着拍的一页纸是个梯形,行会汇聚;OCR 之前先旋转并裁剪到文字块。裁剪同时去掉桌沿、你的拇指和另一页——每一样都会产生一行乱码。

版面。 单栏正文最容易。双栏通常能识别。表格、表单、环绕图片的文字、页边的图注,会以引擎自己选的顺序出来,数字列会丢掉对齐。要表格的话,OCR 你需要的那几格,而不是整页。

字体。 标准的书籍和屏幕字体:极好。压缩体、装饰体、手写体、描边字:差。训练数据没见过的字体是一个形状一个形状地读,语言模型的纠正只会让它更糟。

手写。 实际上不支持。Tesseract 是在印刷体上训练的;表单上的正楷大写也许能过,连笔不行。手写识别是另一个模型家族,不是这个工具做的事。

语言和混排

选文字实际使用的语言,能只选一种就只选一种。选三种语言等于把每个字符的候选集翻三倍,识别更慢、准确率更低。混排文本——一份带英文产品名的中文文档——才是两种语言一起选的场合(中文 + 英文):引擎逐词切换。可用的 12 种语言:英语、简体中文、繁体中文、日语、韩语、西班牙语、法语、德语、葡萄牙语、俄语、意大利语、越南语。

扫描的 PDF

扫描仪出来的 PDF 是每页一张图;文字不在里面,复制不了。用 200–300 dpi 把页面渲染成图片,再 OCR 这些图。用 72 dpi(屏幕分辨率)渲染,字高只有 10 像素,出来的是乱码。

“99%” 实际上意味着什么

一次好的 OCR 在一页干净的纸上大约每一百个字错一个。500 字一页就是三十来处错误,多数在数字、名字和标点里——恰恰是你顺着读读不出来的地方。文字去往任何要紧的地方之前,逐个数字对照原件核一遍;OCR 是草稿,不是誊本。

本文用到的工具