用React和Tesseract.js进行图像到文本的转换(OCR)

数据是每个软件应用程序的支柱,因为一个应用程序的主要目的是解决人类的问题。为了解决人类的问题,有必要掌握一些关于他们的信息。

这种信息被表示为数据,特别是通过计算。在网络上,数据大多以文本、图像、视频等形式收集。有时,图像包含基本的文本,这些文本要经过处理以达到某种目的。这些图像大多是手工处理的,因为没有办法以编程方式处理它们。

无法从图像中提取文本是我在上一家公司亲身经历的数据处理限制。我们需要处理扫描的礼品卡,但由于无法从图像中提取文本,我们不得不手动处理

公司内部有一个叫做 “运营 “的部门,负责手动确认礼品卡并将其计入用户的账户。虽然我们有一个网站,用户通过该网站与我们联系,但礼品卡的处理是在幕后手动进行的。

当时,我们的网站主要是用PHP(Laravel)做后台,JavaScript(jQuery和Vue)做前端。我们的技术栈足以与Tesseract.js一起工作,只要管理层认为这个问题是重要的。

我愿意解决这个问题,但从企业或管理层的角度来看,没有必要解决这个问题。离开公司后,我决定做一些研究,试图找到可能的解决方案。最终,我发现了OCR。

什么是OCR?

OCR是 “光学字符识别 “或 “光学字符阅读器 “的缩写。它被用来从图像中提取文本。

OCR的演变可以追溯到几项发明,但Optophone、”Gismo“、CCD平板扫描仪Newton MesssagePadTesseract是将字符识别提升到另一个有用水平的主要发明。

那么,为什么要使用OCR?嗯,光学字符识别解决了很多问题,其中一个问题引发了我写这篇文章。我意识到,从图像中提取文本的能力确保了很多可能性,例如。

  • 监管
    每个组织都需要出于某些原因监管用户的活动。监管可以用来保护用户的权利,确保他们免受威胁或诈骗。
    从图像中提取文本使一个组织能够处理图像上的文本信息以进行监管,特别是当图像是由一些用户提供的时候。
    例如,可以通过OCR实现类似Facebook对用于广告的图像的文本数量的监管。另外,在Twitter上隐藏敏感内容也是通过OCR实现的。
  • 可搜索性
    搜索是最常见的活动之一,尤其是在互联网上。搜索算法大多是基于对文本的操作。有了光学字符识别,就有可能识别图像上的字符,并利用它们向用户提供相关的图像结果。简而言之,现在借助于OCR,图像和视频都可以进行搜索。
  • 可访问性
    在图像上有文字一直是对可访问性的挑战,在图像上有少量文字是经验法则。有了OCR,屏幕阅读器可以访问图像上的文字,为其用户提供一些必要的经验。
  • 数据处理自动化数据的处理大多是自动化的规模。在图像上有文字是对数据处理的一个限制,因为这些文字不能被处理,除非手动。光学字符识别(OCR)使得以编程方式提取图像上的文本成为可能,从而确保数据处理的自动化,特别是当它与图像上的文本处理有关的时候。
  • 印刷品的数字化
    一切都在走向数字化,仍有许多文件需要数字化。支票、证书和其他实物文件现在可以通过使用光学字符识别来实现数字化。

发现以上所有的用途加深了我的兴趣,所以我决定进一步提出一个问题。

这个问题让我找到了Tesseract.js。

什么是Tesseract.js?

Tesseract.js是一个JavaScript库,它将原始的Tesseract 从C语言编译成JavaScript WebAssembly,从而使OCR可以在浏览器中使用。Tesseract.js引擎最初是用ASM.js编写的,后来被移植到WebAssembly中,但在WebAssembly不被支持的情况下,ASM.js仍然作为一个备份。

正如Tesseract.js的网站上所说,它支持100多种语言,自动检测文本方向和脚本,有一个简单的界面来阅读段落、单词和字符边界框。

Tesseract是一个用于各种操作系统的光学字符识别引擎。它是自由软件,在Apache许可证下发布。惠普公司在20世纪80年代将Tesseract开发为专有软件。它在2005年作为开放源码发布,自2006年以来,它的开发一直由谷歌赞助。

Tesseract的最新版本,即第4版,于2018年10月发布,它包含一个新的OCR引擎,使用基于长短时记忆(LSTM)的神经网络系统,它旨在产生更准确的结果。

了解Tesseract APIs

为了真正理解Tesseract是如何工作的,我们需要对它的一些API及其组成部分进行分解。根据Tesseract.js的文档,有两种方法来使用它。下面是第一种方法和它的分解。

  1. Tesseract.recognize(
  2. image,language,
  3. {
  4. logger: m => console.log(m)
  5. }
  6. )
  7. .catch (err => {
  8. console.error(err);
  9. })
  10. .then(result => {
  11. console.log(result);
  12. })
  13. }

recognize 方法将图像作为其第一个参数,语言(可以是多个)作为其第二个参数,{ logger: m => console.log(me) } 作为其最后一个参数。Tesseract支持的图像格式是jpg、png、bmp和pbm,它们只能作为元素(img、视频或canvas)、文件对象(<input> )、blob对象、图像的路径或URL和base64编码的图像提供。请阅读这里,了解更多关于Tesseract可以处理的所有图像格式的信息)。

语言是以字符串的形式提供的,如eng+ 符号可以用来串联几种语言,如eng+chi_tra 。语言参数用于确定在处理图像时要使用的训练有素的语言数据。

注意你可以这里找到所有可用的语言和它们的代码。

{ logger: m => console.log(m) } 对于获取正在处理的图像的进度信息非常有用。logger属性需要一个函数,这个函数在Tesseract处理图像时将被多次调用。Logger函数的参数应该是一个对象,其属性为workerId,jobId,statusprogress

  1. { workerId: worker-200030’, jobId: job-734747’, status: recognizing text’, progress: 0.9 }

progress 是一个介于0和1之间的数字,它以百分比来显示图像识别过程的进度。

Tesseract自动生成该对象作为记录器函数的参数,但也可以手动提供。随着识别过程的进行,logger 对象的属性在每次函数被调用时都会被更新。因此,它可以用来显示转换进度条,改变应用程序的某些部分,或者用来实现任何期望的结果。

上面代码中的result 是图像识别过程的结果。result 的每个属性都有属性 bbox 作为其边界盒的 x/y 坐标。

下面是result 对象的属性,它们的含义或用途。

  1. {
  2. text: "I am codingnninja from Nigeria..."
  3. hocr: "<div class=ocr_page id= ..."
  4. tsv: "1 1 0 0 0 0 0 0 1486 ..."
  5. box: null
  6. unlv: null
  7. osd: null
  8. confidence: 90
  9. blocks: [{...}]
  10. psm: "SINGLE_BLOCK"
  11. oem: "DEFAULT"
  12. version: "4.0.0-825-g887c"
  13. paragraphs: [{...}]
  14. lines: (5) [{...}, ...]
  15. words: (47) [{...}, {...}, ...]
  16. symbols: (240) [{...}, {...}, ...]
  17. }
  • text: 所有被识别的文本为一个字符串。
  • lines: 每一行识别的文本的数组。
  • words: 每个被识别的单词的数组。
  • symbols: 每个被识别的字符的数组。
  • paragraphs :每个被识别的段落的一个数组。我们将在本篇文章的后面讨论 “信心”。

Tesseract也可以更有必要地使用,如:。

  1. import { createWorker } from tesseract.js;
  2. const worker = createWorker({
  3. logger: m => console.log(m)
  4. });
  5. (async () => {
  6. await worker.load();
  7. await worker.loadLanguage(eng);
  8. await worker.initialize(eng);
  9. const { data: { text } } = await worker.recognize(https://tesseract.projectnaptha.com/img/eng_bw.png);
  10. console.log(text);
  11. await worker.terminate();
  12. })();

这种方法与第一种方法有关,但实现方式不同。

createWorker(options) 创建一个网络工作者或节点子进程,该进程创建一个Tesseract工作者。该工作者帮助设置Tesseract OCR引擎。load() 方法加载Tesseract核心脚本,loadLanguage() 加载以字符串形式提供给它的任何语言,initialize() 确保Tesseract已经完全准备好使用,然后使用recognition方法处理提供的图像。terminate()方法停止工作器并清理一切。

注意请查看Tesseract APIs文档以了解更多信息。

现在,我们必须建立一些东西,以真正看到Tesseract.js的有效性。

我们要建立什么?

我们将建立一个礼品卡密码提取器,因为从礼品卡中提取密码是导致这次写作冒险的首要问题。

我们将建立一个简单的应用程序,从扫描的礼品卡中提取密码。当我着手建立一个简单的礼品卡密码提取器时,我将带领你了解我在这一过程中面临的一些挑战,我提供的解决方案,以及我根据经验得出的结论。

下面是我们要用来测试的图片,因为它有一些现实的属性,在现实世界中是可能的。

我们将从卡上提取AQUX-QWMB6L-R6JAU。所以,让我们开始吧。

安装React和Tesseract

在安装ReactTesseract.js之前有一个问题需要注意,这个问题就是,为什么要用React和Tesseract?实际上,我们可以将Tesseract与Vanilla JavaScript、任何JavaScript库或框架如React、Vue和Angular一起使用。

在这种情况下使用React是一种个人偏好。最初,我想使用Vue,但我决定使用React,因为我对React比Vue更熟悉。

现在,让我们继续安装。

要用create-react-app安装React,你必须运行下面的代码。

  1. npx create-react-app image-to-text
  2. cd image-to-text
  3. yarn add Tesseract.js

  1. npm install tesseract.js

我决定用yarn来安装Tesseract.js,因为我无法用npm安装Tesseract,但yarn毫无压力地完成了工作。你可以使用npm,但从我的经验来看,我建议用yarn安装Tesseract。

现在,让我们通过运行下面的代码来启动我们的开发服务器。

  1. yarn start

  1. npm start

运行yarn start或npm start后,你的默认浏览器应该打开一个网页,看起来像下面这样。

你也可以在浏览器中导航到localhost:3000 ,前提是该页面没有自动启动。

在安装完React和Tesseract.js之后,接下来是什么?

设置一个上传表单

在这种情况下,我们要调整刚才在浏览器中查看的主页(App.js),以包含我们需要的表单。

  1. import { useState, useRef } from react;
  2. import Tesseract from tesseract.js;
  3. import ./App.css;
  4. function App() {
  5. const [imagePath, setImagePath] = useState("");
  6. const [text, setText] = useState("");
  7. const handleChange = (event) => {
  8. setImage(URL.createObjectURL(event.target.files[0]));
  9. }
  10. return (
  11. <div className="App">
  12. <main className="App-main">
  13. <h3>Actual image uploaded</h3>
  14. <img
  15. src={imagePath} className="App-logo" alt="logo"/>
  16. <h3>Extracted text</h3>
  17. <div className="text-box">
  18. <p> {text} </p>
  19. </div>
  20. <input type="file" onChange={handleChange} />
  21. </main>
  22. </div>
  23. );
  24. }
  25. export default App

在这一点上,上面的代码中需要我们注意的部分是函数handleChange

  1. const handleChange = (event) => {
  2. setImage(URL.createObjectURL(event.target.files[0]));
  3. }

在这个函数中,URL.createObjectURL 通过event.target.files[0] ,获取一个选定的文件,并创建一个可用于HTML标签(如img、音频和视频)的参考URL。我们使用setImagePath ,将URL添加到状态中。现在,这个URL现在可以用imagePath

  1. <img src={imagePath} className="App-logo" alt="image"/>

我们将图像的src属性设置为{imagePath} ,以便在处理之前在浏览器中预览。

将选定的图像转换为文本

由于我们已经抓取了所选图片的路径,我们可以将图片的路径传递给Tesseract.js来提取其中的文本。

  1. import { useState} from react;
  2. import Tesseract from tesseract.js;
  3. import ./App.css;
  4. function App() {
  5. const [imagePath, setImagePath] = useState("");
  6. const [text, setText] = useState("");
  7. const handleChange = (event) => {
  8. setImagePath(URL.createObjectURL(event.target.files[0]));
  9. }
  10. const handleClick = () => {
  11. Tesseract.recognize(
  12. imagePath,eng,
  13. {
  14. logger: m => console.log(m)
  15. }
  16. )
  17. .catch (err => {
  18. console.error(err);
  19. })
  20. .then(result => {
  21. // Get Confidence score
  22. let confidence = result.confidence
  23. let text = result.text
  24. setText(text);
  25. })
  26. }
  27. return (
  28. <div className="App">
  29. <main className="App-main">
  30. <h3>Actual imagePath uploaded</h3>
  31. <img
  32. src={imagePath} className="App-image" alt="logo"/>
  33. <h3>Extracted text</h3>
  34. <div className="text-box">
  35. <p> {text} </p>
  36. </div>
  37. <input type="file" onChange={handleChange} />
  38. <button onClick={handleClick} style={{height:50}}> convert to text</button>
  39. </main>
  40. </div>
  41. );
  42. }
  43. export default App

我们在 “App.js “中添加了 “handleClick “函数,它包含了Tesseract.js的API,获取了所选图片的路径。Tesseract.js需要 “imagePath”、”language”、”a setting object”。

下面的按钮被添加到表单中,以调用 “handClick”,只要按钮被点击,就会触发图像到文本的转换。

  1. <button onClick={handleClick} style={{height:50}}> convert to text</button>

当处理成功后,我们从结果中访问 “信心 “和 “文本”。然后,我们用 “setText(text) “将 “text “添加到状态中。

通过添加到<p> {text} </p> ,我们显示了提取的文本。

很明显,”文本 “是从图像中提取出来的,但什么是信心?

置信度显示了转换的精确程度。置信度在1到100之间。1代表最差的,而100代表在准确性方面最好的。它也可以用来确定一个提取的文本是否应该被接受为准确。

那么问题来了,什么因素会影响置信度分数或整个转换的准确性呢?它主要受三个主要因素的影响—所用文件的质量和性质、从文件中创建的扫描质量以及魔方引擎的处理能力。

现在,让我们把下面的代码添加到 “App.css “中,使应用程序有一点风格。

  1. .App {
  2. text-align: center;
  3. }
  4. .App-image {
  5. width: 60vmin;
  6. pointer-events: none;
  7. }
  8. .App-main {
  9. background-color: #282c34;
  10. min-height: 100vh;
  11. display: flex;
  12. flex-direction: column;
  13. align-items: center;
  14. justify-content: center;
  15. font-size: calc(7px + 2vmin);
  16. color: white;
  17. }
  18. .text-box {
  19. background: #fff;
  20. color: #333;
  21. border-radius: 5px;
  22. text-align: center;
  23. }

下面是我第一次测试的结果。

火狐浏览器中的结果

上述结果的置信度为64。值得注意的是,礼品卡图片的颜色很深,这肯定会影响我们得到的结果。

如果你仔细看一下上面的图片,你会发现卡上的针脚在提取的文字中几乎是准确的。它不准确是因为礼品卡并不真正清晰。

哦,等等!在Chrome浏览器中会是什么样子?

在Chrome中的结果

啊!在Chrome中的结果更糟糕。但是为什么在Chrome中的结果与Mozilla Firefox不同呢?不同的浏览器对图像及其颜色配置文件的处理方式不同。这意味着,一个图像会因浏览器的不同而呈现出不同的效果。通过向Tesseract提供预渲染的image.data ,很可能在不同的浏览器中产生不同的结果,因为根据使用的浏览器,向Tesseract提供不同的image.data 。正如我们将在本文后面看到的那样,对图像进行预处理将有助于获得一致的结果。

我们需要更加准确,这样才能确保我们获得或提供的信息是正确的。因此,我们必须再进一步。

让我们多尝试一下,看看我们最终是否能达到目的。

测试准确度

有很多因素会影响Tesseract.js的图像到文本的转换。这些因素大多围绕着我们要处理的图像的性质,其余的则取决于Tesseract引擎如何处理转换。

在内部,Tesseract在实际的OCR转换之前对图像进行预处理,但它并不总是能给出准确的结果。

作为一个解决方案,我们可以对图像进行预处理以实现准确的转换。我们可以对图像进行二值化、反转、扩张、纠偏或重新缩放,为Tesseract.js进行预处理。

图像预处理是一项大量的工作,或者说本身就是一个广泛的领域。幸运的是,P5.js已经提供了我们想要使用的所有图像预处理技术。我没有重新发明轮子或使用整个库,只是因为我们想使用它的一小部分,而是复制了我们需要的那些。所有的图像预处理技术都包含在preprocess.js中。

什么是二值化?

二进制化是将图像的像素转换为黑色或白色。我们想对以前的礼品卡进行二值化,以检查准确率是否会提高。

之前,我们从礼品卡中提取了一些文本,但目标密码并不像我们想要的那样准确。因此,有必要找到另一种方法来获得准确的结果。

现在,我们要对礼品卡进行二值化处理,也就是说,我们要把它的像素转换成黑白的,这样我们就可以看到是否可以达到更好的准确度。

下面的函数将用于二进制化,它被包含在一个单独的文件中,名为preprocess.js

  1. function preprocessImage(canvas) {
  2. const ctx = canvas.getContext(2d);
  3. const image = ctx.getImageData(0,0,canvas.width, canvas.height);
  4. thresholdFilter(image.data, 0.5);
  5. return image;
  6. }
  7. Export default preprocessImage

上面的代码是做什么的?

我们引入canvas来保存图像数据,应用一些过滤器,对图像进行预处理,然后再传递给Tesseract进行转换。

第一个preprocessImage 函数位于preprocess.js中,通过获取画布的像素来为其使用做准备。该函数thresholdFilter ,通过将其像素转换为黑色或白色来对图像进行二进制化。

让我们调用preprocessImage ,看看从之前的礼品卡中提取的文字是否能更准确。

当我们更新App.js时,它现在应该看起来像这样的代码。

  1. import { useState, useRef } from react;
  2. import preprocessImage from ./preprocess;
  3. import Tesseract from tesseract.js;
  4. import ./App.css;
  5. function App() {
  6. const [image, setImage] = useState("");
  7. const [text, setText] = useState("");
  8. const canvasRef = useRef(null);
  9. const imageRef = useRef(null);
  10. const handleChange = (event) => {
  11. setImage(URL.createObjectURL(event.target.files[0]))
  12. }
  13. const handleClick = () => {
  14. const canvas = canvasRef.current;
  15. const ctx = canvas.getContext(2d);
  16. ctx.drawImage(imageRef.current, 0, 0);
  17. ctx.putImageData(preprocessImage(canvas),0,0);
  18. const dataUrl = canvas.toDataURL("image/jpeg");
  19. Tesseract.recognize(
  20. dataUrl,eng,
  21. {
  22. logger: m => console.log(m)
  23. }
  24. )
  25. .catch (err => {
  26. console.error(err);
  27. })
  28. .then(result => {
  29. // Get Confidence score
  30. let confidence = result.confidence
  31. console.log(confidence)
  32. // Get full output
  33. let text = result.text
  34. setText(text);
  35. })
  36. }
  37. return (
  38. <div className="App">
  39. <main className="App-main">
  40. <h3>Actual image uploaded</h3>
  41. <img
  42. src={image} className="App-logo" alt="logo"
  43. ref={imageRef}
  44. />
  45. <h3>Canvas</h3>
  46. <canvas ref={canvasRef} width={700} height={250}></canvas>
  47. <h3>Extracted text</h3>
  48. <div className="pin-box">
  49. <p> {text} </p>
  50. </div>
  51. <input type="file" onChange={handleChange} />
  52. <button onClick={handleClick} style={{height:50}}>Convert to text</button>
  53. </main>
  54. </div>
  55. );
  56. }
  57. export default App

首先,我们要用下面的代码从 “preprocess.js “中导入 “preprocessImage”。

  1. import preprocessImage from ./preprocess;

然后,我们在表单中添加一个canvas标签。我们将canvas和img标签的ref属性分别设置为{ canvasRef }{ imageRef } 。refs是用来从App组件中访问canvas和图片的。我们用 “useRef “来获取画布和图片,如图所示。

  1. const canvasRef = useRef(null);
  2. const imageRef = useRef(null);

在这部分代码中,我们将图像合并到画布上,因为我们只能在JavaScript中预处理画布。然后我们把它转换为一个数据URL,以 “jpeg “作为其图像格式。

  1. const canvas = canvasRef.current;
  2. const ctx = canvas.getContext(2d);
  3. ctx.drawImage(imageRef.current, 0, 0);
  4. ctx.putImageData(preprocessImage(canvas),0,0);
  5. const dataUrl = canvas.toDataURL("image/jpeg");

“dataUrl “作为要处理的图像被传递给Tesseract。

现在,让我们检查一下所提取的文本是否会更准确。

测试#2

上面的图片显示了Firefox中的结果。很明显,图像的暗部已经变成了白色,但是对图像进行预处理并没有带来更准确的结果。情况甚至更糟。

第一次转换只有两个错误的字符,但这次却有四个错误的字符。我甚至试着改变阈值水平,但无济于事。我们没有得到更好的结果,并不是因为二值化不好,而是因为二值化图像没有以适合魔方引擎的方式修复图像的性质。

让我们看看它在Chrome中也是什么样子。

我们得到了同样的结果。

在通过二进制化得到较差的结果后,有必要检查其他的图像预处理技术,看看我们是否能解决这个问题。所以,我们接下来要尝试扩张、反转和模糊处理。

我们就从本文所使用的P5.js中获取每个技术的代码。我们将把图像处理技术添加到preprocess.js中,并逐一使用它们。在使用之前,有必要了解我们要使用的每一项图像预处理技术,所以我们要先讨论这些技术。

什么是扩张?

扩张是在图像中物体的边界上增加像素,使其更宽、更大或更开放。扩张 “技术被用来预处理我们的图像,以增加图像上物体的亮度。我们需要一个使用JavaScript来扩张图像的函数,所以扩张图像的代码片段被添加到preprocess.js中。

什么是模糊?

模糊是通过降低图像的清晰度来平滑图像的颜色。有时,图像有一些小点/斑点。为了去除这些斑点,我们可以对图像进行模糊处理。模糊图像的代码片段包含在preprocess.js中。

什么是反转?

反转是将图像的浅色区域变为深色,将深色区域变为浅色。例如,如果一张图片的背景是黑色的,前景是白色的,我们可以将其反转,使其背景为白色,前景为黑色。我们还在preprocess.js中添加了反转图像的代码片段。

在 “preprocess.js “中加入dilateinvertColorsblurARGB ,我们现在可以用它们来预处理图像。为了使用它们,我们需要更新preprocess.js中最初的 “preprocessImage “函数。

preprocessImage(...) 现在看起来像这样。

  1. function preprocessImage(canvas) {
  2. const level = 0.4;
  3. const radius = 1;
  4. const ctx = canvas.getContext(2d);
  5. const image = ctx.getImageData(0,0,canvas.width, canvas.height);
  6. blurARGB(image.data, canvas, radius);
  7. dilate(image.data, canvas);
  8. invertColors(image.data);
  9. thresholdFilter(image.data, level);
  10. return image;
  11. }

在上面的preprocessImage ,我们对图像应用了四种预处理技术:blurARGB() ,去除图像上的点,dilate() ,增加图像的亮度,invertColors() ,切换图像的前景和背景颜色,thresholdFilter() ,将图像转换成更适合魔方转换的黑白图像。

thresholdFilter()image.datalevel 为参数。level 用于设置图像应该是白色还是黑色。我们通过试验和错误来确定thresholdFilter 水平和blurRGB 半径,因为我们不确定图像应该有多白、多黑或多平滑,以便魔方产生一个好的结果。

测试#3

下面是应用四种技术后的新结果。

上面的图片代表了我们在Chrome和Firefox中得到的结果。

哎呀!这下好了。这个结果很糟糕。

与其使用所有四种技术,为什么我们不一次只使用其中的两种呢?

是的!我们可以简单地使用invertColorsthresholdFilter 技术,将图像转换为黑白,并切换图像的前景和背景。但是我们怎么知道要结合什么和什么技术呢?我们根据要预处理的图像的性质来知道要结合什么。

例如,数字图像必须转换为黑白图像,有斑点的图像必须进行模糊处理以去除点/斑点。真正重要的是了解每项技术的用途。

要使用invertColorsthresholdFilter ,我们需要在preprocessImage 中注释掉blurARGBdilate

  1. function preprocessImage(canvas) {
  2. const ctx = canvas.getContext(2d);
  3. const image = ctx.getImageData(0,0,canvas.width, canvas.height);
  4. // blurARGB(image.data, canvas, 1);
  5. // dilate(image.data, canvas);
  6. invertColors(image.data);
  7. thresholdFilter(image.data, 0.5);
  8. return image;
  9. }
测试#4

现在,这里是新的结果。

结果仍然比没有进行任何预处理的结果差。在对这一特定图像和其他一些图像调整了各项技术后,我得出结论,不同性质的图像需要不同的预处理技术。

简而言之,使用Tesseract.js而不进行图像预处理,对上面的礼品卡产生了最佳结果。所有其他使用图像预处理的实验产生的结果都不太准确。

问题

最初,我想从任何亚马逊礼品卡中提取PIN码,但我无法实现,因为没有必要去匹配一个不一致的PIN码来获得一个一致的结果。虽然有可能通过处理图像来获得准确的PIN码,但是当使用另一张不同性质的图像时,这样的预处理就会不一致了。

产生的最佳结果

下面的图片展示了实验产生的最佳结果。

测试#5

图片上的文字和提取的文字是完全一样的。转换的准确性是100%。我试图重现这个结果,但我只能在使用性质相似的图片时重现这个结果。

观察和教训

  • 一些没有经过预处理的图像在不同的浏览器中可能会出现不同的结果。这种说法在第一个测试中就很明显。在Firefox中的结果与Chrome中的结果是不同的。然而,预处理图像有助于在其他测试中获得一致的结果。
  • 白色背景上的黑色往往能带来可控的结果。下面的图片是一个没有经过任何预处理的准确结果的例子。我也能够通过预处理图像获得同样的准确度,但我花了很多调整,这是不必要的。

这个转换是100%准确的。

  • 字体大的文字往往更准确。

  • 弯曲边缘的字体往往会使魔方混淆。当我使用Arial(字体)时,我得到了最好的结果。
  • OCR目前还不足以实现图像到文本的自动转换,特别是当需要80%以上的准确度时。然而,它可以通过提取文本进行人工校正,使图像上的文本的人工处理变得不那么紧张
  • OCR目前还不足以将有用的信息传递给屏幕阅读器以实现无障碍。向屏幕阅读器提供不准确的信息,很容易误导或分散用户的注意力。
  • OCR是非常有前途的,因为神经网络使它有可能学习和改进。深度学习将使OCR在不久的将来成为游戏规则的改变者
  • 做出有信心的决定。信任度分数可以用来做决定,这对我们的应用有很大影响。信心分数可以用来决定是接受还是拒绝一个结果。从我的经验和实验中,我意识到任何低于90分的置信度都不是真正有用的。如果我只需要从一个文本中提取一些针脚,我希望可信度分数在75到100之间,任何低于75的都会被拒绝

如果我处理的是不需要提取任何部分的文本,我肯定会接受90到100之间的置信度分数,但拒绝任何低于这个分数的。例如,如果我想把支票、历史性的汇票或任何需要精确复制的文件数字化,90分及以上的准确率将被期待。但是,当精确复制并不重要时,例如从礼品卡上获取密码,75-90分之间的分数是可以接受的。简而言之,信心分数有助于做出影响我们应用的决定

结论

鉴于图像上的文本所造成的数据处理限制以及与之相关的缺点,光学字符识别(OCR)是一种有用的技术。尽管OCR有其局限性,但由于其对神经网络的使用,它是非常有前途的。

随着时间的推移,OCR将在深度学习的帮助下克服其大部分局限性,但在此之前,可以利用本文强调的方法来处理图像中的文本提取,至少可以减少与人工处理相关的困难和损失--特别是从商业角度来看。

现在轮到你尝试OCR从图像中提取文本了。祝你们好运!

进一步阅读


文章标签:

原文连接:https://juejin.cn/post/6977764913612029982

相关推荐

Webpack学习系列 - Webpack5 怎么集成Babel ?

我在淘宝做弹窗,2022 年初的回顾与展望

看完这篇,你也可以搞定有趣的动态曲线绘制

低代码平台的属性面板该如何设计?

34个图片压缩工具集合,包含在线压缩和CLI工具

冴羽答读者问:过程比结果重要吗?如果是,怎么理解?如果不是,又怎么解?

中杯超大杯中间的新选择——vue2.7+vite+ts实践

LiveData源码分析

亚马逊Prime:流媒大战杀手锏

Vue详解知识概括

基于 Docker 来部署 Vue 或 React 前端项目及 Node 后端服务

完美解决自定义字体垂直方向上下偏移的问题

使用vuepress从零开始搭建我的技术文档|已部署到线上

【Vue.js 3.0源码】AST 转换之节点内部转换

小程序+电商,该如何寻找营销增长点

前端如何开始深度学习,那不妨试试JAX

你可能不知道的 前端浏览器(window) 对本地文件操作(File System Access API)

爱奇艺向抖音开启授权,打开内容价值的新大门

使用ComposeDesktop开发一款桌面端多功能APK工具

一个简洁、强大、可扩展的前端项目架构是什么样的?