使用 Tesseract.js 在 JavaScript 中进行 OCR

2025-06-07

使用 Tesseract.js 在 JavaScript 中进行 OCR

照片由Mark RasmusonUnsplash上拍摄。


在编写node-html-to-image模块时,我遇到了一个小问题。如何测试它是否真的有效?node-html-to-image这是一个 Node.js 模块,用于从 HTML 生成图像(png、jpeg)。如果您想了解更多信息,我写了一篇关于这个模块的小文章。我能想到的最简单的测试方法是,根据包含“Hello world!”的 HTML 字符串创建一个图像。然后,我可以使用OCR检查图像是否真的包含这个字符串

什么是 OCR?

OCR 代表光学字符识别。这项技术允许您从图像中提取文本。文本可以是手写文本,也可以是印刷文本。OCR 涉及许多复杂的步骤才能真正从图像中获取文本,但这并不是本文的目的。您可以阅读维基百科文章了解更多信息。

我们将重点介绍如何将其与最流行的开源 OCR 引擎Tesseract结合使用。作为一个库,它可供 C/C++ 开发人员使用。幸运的是,它有一个 JavaScript 移植版本。

安装

Tesseract.js与node-tesseract-ocr不同,它不需要您在计算机上安装任何东西。这也意味着它无法离线工作。node-tesseract-ocr它只是一个包装器,tesseract因此您需要在计算机上安装。同时,您tesseract可以随时随地下载语言和核心脚本。tesseract-langTesseract.js

您唯一需要做的就是Tesseract.js使用您最喜欢的包管理器安装 npm 包:

# With yarn
yarn add tesseract.js
# With npm
npm install tesseract.js
Enter fullscreen mode Exit fullscreen mode

如何使用

这是我们将尝试从中提取文本的图像。

包含 Hello world 的图片

让我们一步一步地进行。

首先我们需要导入该createWorker函数。

const { createWorker } = require('tesseract.js')
Enter fullscreen mode Exit fullscreen mode

我们调用它来创建一个新的 tesseract worker,它是 Node.js 中的子进程和浏览器中的 Web Worker(是的,Tesseract.js 也可以在浏览器中工作)。

const worker = createWorker()
Enter fullscreen mode Exit fullscreen mode

一个 Worker 实例有几个方法。我们首先需要调用的是load函数。它加载核心脚本,并为 Tesseract Worker 的后续工作做好准备。

// ...

async function getTextFromImage() {
  await worker.load()
}
Enter fullscreen mode Exit fullscreen mode

然后,我们需要加载图像中文本的语言。我们可以使用loadLanguages方法来实现。我将下载一个包含该语言训练日期的文件。在我们的示例中,该文件名为eng.traineddata。我们可以使用字符加载多种语言+(例如:eng+fr)。

// ...

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
}
Enter fullscreen mode Exit fullscreen mode

是时候让我们的 Worker 准备好执行 OCR 任务了。我们使用Initialize方法来实现。它接受我们想要使用的语言作为参数。它可以是我们之前加载的语言的子集。

// ...

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
  await worker.initialize('eng')
}
Enter fullscreen mode Exit fullscreen mode

让我们开始 OCR 吧!我们的 Worker 有一个识别方法,它接受一张图片作为参数。图片可以是 URL、文件系统路径或缓冲区。它返回一个带有 data 属性的对象,该属性也是一个带有 text 属性的对象,其中包含最终结果。

// ...

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
  await worker.initialize('eng')

  const { data: { text } } = await worker.recognize('./hello-world.png');
}
Enter fullscreen mode Exit fullscreen mode

最后一步,我们需要使用方法terminate清理我们的工作进程。

// ...

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
  await worker.initialize('eng')

  const { data: { text } } = await worker.recognize('./hello-world.png');

  await worker.terminate()

  return text
}
Enter fullscreen mode Exit fullscreen mode

让我们测试一下!我们调用我们的函数并将结果打印到输出。

getTextFromImage()
  .then(console.log)
Enter fullscreen mode Exit fullscreen mode

当您调用脚本时,您应该会得到以下结果。

~ ❯ node tesseract.js                                                                                                                                                   ⏎
HELLO WORLD!
Enter fullscreen mode Exit fullscreen mode

很好,但是它没有找到我们图像中的所有文本......

Tesseract 默认以SINGLE_BLOCK模式工作。每个 Worker 实例都包含一个setParameters 函数,用于更改 Tesseract 的默认行为。在本例中,我们想要更改tessedit_pageseg_mode参数值。在此之前,我们需要导入 PSM 枚举(这是页面分段模式的缩写)。

const { createWorker } = require('tesseract.js')
const PSM = require('tesseract.js/src/constants/PSM.js')

// ...
Enter fullscreen mode Exit fullscreen mode

最后,我们调用setParameters方法并传入所需的模式。在本例中,我们将使用AUTO模式并让引擎查找所有行。

// ...

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
  await worker.initialize('eng')
  await worker.setParameters({
    tessedit_pageseg_mode: PSM.AUTO,
  })

  const { data: { text } } = await worker.recognize('./hello-world.png');

  await worker.terminate()

  return text
}

// ...
Enter fullscreen mode Exit fullscreen mode

通过调用你应该会得到不同的结果。

~ ❯ node tesseract.js                                                                                                                                                   ⏎
HELLO WORLD!

made with € by node-html-to-image
Enter fullscreen mode Exit fullscreen mode

如你所见,它找到了整个文本。虽然识别表情符号似乎有些困难,但结果还是相当令人印象深刻。

最终代码如下:

const { createWorker } = require('tesseract.js')
const PSM = require('tesseract.js/src/constants/PSM.js')

async function getTextFromImage() {
  await worker.load()
  await worker.loadLanguage('eng')
  await worker.initialize('eng')
  await worker.setParameters({
    tessedit_pageseg_mode: PSM.AUTO,
  })

  const { data: { text } } = await worker.recognize('./hello-world.png');

  await worker.terminate()

  return text
}

getTextFromImage()
  .then(console.log)
Enter fullscreen mode Exit fullscreen mode

Tesseract.js 文档中还有更多示例,其中包含以下额外功能:

  • 进步
  • 多语言
  • 白名单字符
  • 还有更多...

如果你好奇我是如何测试node-html-to-image 的,可以在这里找到源代码。

您已设置好🙌希望它能对您有所帮助!

节日快乐🎉


欢迎提供反馈或想法🙏如果您有任何问题,请发推文给我@YvonnickFrin

文章来源:https://dev.to/yvonnickfrin/ocr-in-javascript-with-tesseract-hnl
PREV
拯救地球,清理你的邮箱
NEXT
DevTips:使用早期返回来避免嵌套条件