开源神器tesseract.js:前端OCR的终极选择!

发表时间: 2023-06-18 05:39

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

今天给大家带来的主题是 tesseract.js,即支持 100 多种语言的纯 Javascript OCR(Optical Character Recognition,即光符识别)工具。话不多说,直接进入正题。

1.什么是 Tesseract

Tesseract 最初是在 1985 年至 1994 年间在英国布里斯托尔惠普实验室和美国科罗拉多州格里利的惠普公司开发的,1996 年进行一些更改以移植到 Windows,并在 1998 年进行了一些 C++ 化。2005 年 Tesseract 由 HP 开源, 从 2006 年到 2018 年 11 月由谷歌开发。

Tesseract 的主要版本 5 是当前的稳定版本,从 2021 年 11 月 30 日的 5.0.0 版开始,最新的源代码可从 GitHub 上的主要分支获得。

Tesseract 软件包包含一个 OCR 引擎 libtesseract 和一个命令行程序 tesseract。

图片来自:https://www.klippa.com/en/blog/information/tesseract-ocr/

Tesseract 4 添加了一个新的基于神经网络 (LSTM) 的 OCR 引擎,该引擎专注于线条识别,但也仍然支持 Tesseract 3 的遗留 Tesseract OCR 引擎,该引擎通过识别字符模式来工作。 通过使用旧版 OCR 引擎模式 (--oem 0) 启用与 Tesseract 3 的兼容性。 它还需要支持旧引擎的训练数据文件,例如来自 tessdata 存储库的数据文件。

  • Tesseract 具有 unicode (UTF-8) 支持,可以“开箱即用”地识别 100 多种语言。
  • Tesseract 支持各种图像格式,包括 PNG、JPEG 和 TIFF。
  • Tesseract 支持多种输出格式:纯文本、hOCR (HTML)、PDF、仅不可见文本的 PDF、TSV 和 ALTO(最后一种 - 自版本 4.1.0 起)。

需要注意的是,在大多数情况下为了获得更好的 OCR 结果,开发者需要提高提供给 Tesseract 的图像质量,同时该项目不包括 GUI 应用程序。

目前 Tesseract 在 Github 上通过Apache-2.0 license开源,有超过51.5k的star、8.6k的fork、代码贡献者160+,是一个妥妥的优质开源项目

2.什么是Tesseract.js

Tesseract.js 是当下最流行的 Tesseract OCR 引擎的纯 Javascript 端口。

该库支持 100 多种语言、自动文本方向和脚本检测、用于阅读段落、单词和字符边界框的简单界面。 Tesseract.js 可以在浏览器中运行,也可以在带有 NodeJS 的服务器上运行。Tesseract.js 只是图片识别、及时视频识别等诸多优秀特性。

本质上,Tesseract.js 是包装了 Tesseract OCR 引擎的 webassembly 端口。它在浏览器中使用 webpack 或带有 CDN 的纯脚本标签,在服务器上使用 Node.js。安装后,使用起来也是非常简单:

import Tesseract from 'tesseract.js';Tesseract.recognize(  'https://tesseract.projectnaptha.com/img/eng_bw.png',  'eng',  { logger: m => console.log(m) }).then(({ data: { text } }) => {  console.log(text);})

或者使用 worker(推荐用于生产):

import { createWorker } from 'tesseract.js';const worker = await createWorker({  logger: m => console.log(m)});(async () => {  await worker.loadLanguage('eng');  await worker.initialize('eng');  const { data: { text } } = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');  console.log(text);  await worker.terminate();})();

也可以通过如下CDN引用Tesseract.js:

<!-- v4 --><script src='https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js'></script>

目前 Tesseract.js 在Github上通过Apache-2.0 license开源,有超过30.7k的star、2.1k的fork、10.2k的项目依赖量,代码贡献者70+,是一个妥妥的前端优质开源项目。

3.Tesseract.js三种模式

Tesseract.js 提供 3 种不同的文本识别方式,复杂程度各不相同。 这允许 Tesseract.js 为试验 Tesseract.js 的新用户提供易用性,同时为更有经验的用户提供精确控制和性能调节。


3.1 单函数模式

通过使用 Tesseract.recognize,开发者可以仅使用 1 个函数和 2 个参数(图像和语言)来识别文本,这使得新用户可以轻松地体验 Tesseract.js。

Tesseract.recognize(  'https://tesseract.projectnaptha.com/img/eng_bw.png',  'eng').then(({ data: { text } }) => {  console.log(text);})

在生产代码中通常应尽量避免使用此模式,每当运行 Tesseract.recognize 时都会创建一个新的 worker 并加载语言数据,比较低效。

3.2 使用worker

Tesseract.js 还支持手动创建和管理 worker(执行识别的对象)。

(async () => {    const worker = await Tesseract.createWorker();    await worker.loadLanguage('eng');    await worker.initialize('eng');    const { data: { text } } = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');    console.log(text);    await worker.terminate();})();

这种模式并不比编写的 Tesseract.recognize 示例更有效(在这两种情况下,都会创建和销毁一个 worker 来识别单个图像)。 然而,在实际应用程序的上下文中,将 创建工作程序和加载数据与运行识别作业分开,为开发人员提供了编写更高效代码所需的控制权:

  • Worker 可以提前准备,可以在首次加载页面时创建 worker 并加载语言数据,而不是等待用户上传图像来识别
  • Worker 可以重复用于多个识别工作,而不是创建一个新的 worker 并为每个识别的图像加载语言数据(如 Tesseract.recognize 所做的那样)

3.3 使用调度器 + Woker

Tesseract.js 支持调度程序,调度程序是一个包含多个 Worker 程序的对象用于并行执行作业。

const scheduler = Tesseract.createScheduler();//创建Worker并添加到调度程序const workerGen = async () => {  const worker = await Tesseract.createWorker();  await worker.loadLanguage('eng');  await worker.initialize('eng');  scheduler.addWorker(worker);}const workerN = 4;(async () => {  const resArr = Array(workerN);  for (let i=0; i<workerN; i++) {    resArr[i] = workerGen();  }  await Promise.all(resArr);  /** 添加几个识别任务 */  const results = await Promise.all(Array(10).fill(0).map(() => (    scheduler.addJob('recognize', 'https://tesseract.projectnaptha.com/img/eng_bw.png').then((x) => console.log(x.data.text))  )))  await scheduler.terminate();   // 终止所有Worker})();

虽然使用调度程序对于单个 Worker 的效率并不高,但它们允许快速并行执行大量作业。

使用调度程序时,请注意添加到同一调度程序的 Worker 应该都是同质的,即使用相同的语言配置相同的参数。 调度程序以非确定性方式将工作分配给 Worker,因此如果 Worker 不相同,则识别结果将取决于工作分配给哪个 Worker。

4.Tesseract.js 的三个主要版本

Tesseract.js v4 版本的主要变化包括:

  • 添加了旋转预处理选项(Rotation Preprocessing Pptions)(包括自动旋转)以显著提高准确性
  • 可以检索处理过的图像(旋转、灰度、二进制)、改进了对并行处理(调度程序)的支持
  • createWorker 支持异步的、getPDF 函数替换为 pdf 识别选项

Tesseract.js v3 的主要变化包括:

  • 显著更快的性能,识别示例图像时,浏览器的运行时间减少了 84%,Node.js 的运行时间减少了 96%
  • 升级到 Tesseract v5.1.0(使用 emscripten 3.1.18)
  • 为支持的设备添加了支持 SIMD 的构建
  • 添加 Node.js 版本 18支持
  • 删除 ASM.js 版本,任何其他旧版本的 Tesseract.js-core (<3.0.0)、Node.js 版本 10 和 12的支持

Tesseract.js v2 版本的主要变化包括:

  • 升级到 tesseract v4.1.1(上游使用 emscripten 1.39.10)
  • 同时支持多种语言,eg: eng+chi_tra for English and Traditional Chinese
  • 支持的图像格式:png、jpg、bmp、pbm
  • 支持 WebAssembly(当浏览器不支持时回退到 ASM.js)和 TypeScript

5.本文总结

本文主要和大家介绍 tesseract.js,即支持 100 多种语言的纯 Javascript OCR工具。相信通过本文的阅读,大家对 tesseract.js 会有一个初步的了解。

因为篇幅有限,关于 tesseract.js 的更多用法和特性文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏,您的支持是我不断创作的动力。

参考资料

https://github.com/tesseract-ocr/tesseract

https://github.com/naptha/tesseract.js

https://github.com/naptha/tesseract.js/blob/master/docs/intro.md

https://nanonets.com/blog/ocr-with-tesseract/

https://www.klippa.com/en/blog/information/tesseract-ocr/

封面图:来自