PHP OCR实战:用Tesseract从图像中读取文字

本文涉及的产品
小语种识别,小语种识别 200次/月
个人证照识别,个人证照识别 200次/月
通用文字识别,通用文字识别 200次/月
简介:

Optical Character Recognition (OCR)即光学字符辨识是把打印文本转换成一个数字表示的过程。它有各种各样的实际应用–从数字化印刷书籍、创建收据的电子记录,到车牌识别甚至破解基于图像的验证码。

Robotic eye

Tesseract是一个能实现OCR的开源项目。你能在*Nix系统,Mac系统和Windows系统上运行这个项目,但是只要使用一个库,我们就能在PHP项目中使用它了。本教程的目的是教你如何使用。

安装

准备

为了让事情变得简单和一致的, 我们将使用虚拟机(本文使用Vagrant)来运行应用程序,这会涉及到安装PHP和Nginx,我们将安装 Tesseract来分别演示过程。如果你想自己基于现有Debian-based系统安装Tesseract,你可以跳过下一部分—或者查看the README来获得在其他*nix上,Mac系统或者Windows的安装指导.

配置Vagrant

为了配置Vagrant以跟上本教程,完成如下步骤。或者你也可以简单的从Github获得代码。

输入以下命令来下载Homestead Improved Vagrant配置到一个名为orc的文件夹:

git clone https://github.com/Swader/homestead_improved ocr

将Nginx配置文件Homestead.yml中的以下代码:


 
 
  1. sites: 
  2.     - map: homestead.app 
  3.       to: /home/vagrant/Code/Project/public 

修改成:


 
 
  1. sites: 
  2.     - map: homestead.app 
  3.       to: /home/vagrant/Code/public 

同样要在hosts文件中添加


 
 
  1. 192.168.10.10       homestead.app 

安装Tesseract

下一步是安装Tesseract

因为Homestead Improved 使用debian,我们可以在使用vagrant ssh登陆虚拟机后使用apt-get 来安装它,简单运行如下命令:


 
 
  1. sudo apt-get install tesseract-ocr 

正如上文提到的,在the README中有其他的操作系统对应教程。

测试并定制安装

我们将使用PHP包装,但是之前我们可以在命令行测试Tesseract。

首先保存这个图片sign.png

在虚拟机中,执行如下命令来从图片中读取文字


 
 
  1. tesseract sign.png out 

这将在当前文件夹创建一个文件:out.txt里面应该有单词:CAUTION

现在尝试sign2.jpg


 
 
  1. tesseract sign2.jpg out 

这次产生单词Einbahnstral’ie。很接近但不正确—虽然图像中的文字相当清晰,它没能识别字符ß。

为了获使Tesseract正常读取字符串,我们需要安装一些新的语言文件—就本例来说,德语。

这里有一个全面的可用语言文件列表,但我们直接下载所需的文件:


 
 
  1. wget https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.deu.tar.gz 

解压:


 
 
  1. tar zxvf tesseract-ocr-3.02.deu.tar.gz 

然后把文件复制到如下目录:


 
 
  1. /usr/share/tesseract-ocr/tessdata 

例如


 
 
  1. cp deu-frak.traineddata /usr/share/tesseract-ocr/tessdata 
  2. cp deu.traineddata /usr/share/tesseract-ocr/tessdata 

现在我们再次执行原来的命令但是要用 –l


 
 
  1. tesseract sign2.jpg out -l deu 
  2.  
  3.     “deu” 是德语的 ISO 639-3码. 

这次,文字应该是Einbahnstraße(正确的)。

可以通过重复上述过程来使用任意语言。

配置应用程序

我们将使用这个库来用PHP使用Tesseract。

我们将建立一个极简的web应用:用户上传图片,并查看OCR处理结果。我们将使用Silex microframework 来实现。不要担心你不熟悉它,这个应用本身很简单。

记住这篇教程的所有代码都能在Github上获得。

第一步是用Composer来安装依赖文件:


 
 
  1. composer require silex/silex twig/twig thiagoalessio/tesseract_ocr:dev-master 

然后建立三个文件夹:


 
 
  1. public 
  2. - uploads 
  3. - views 

我们需要上传表单(views\index.twig):


 
 
  1. <html> 
  2.   <head> 
  3.     <title>OCR</title> 
  4.   </head> 
  5.   <body> 
  6.  
  7.     <form action="" method="post" enctype="multipart/form-data"
  8.       <input type="file" name="upload"
  9.       <input type="submit"
  10.     </form> 
  11.  
  12.   </body> 
  13. </html> 

需要一个结果展示页面(views\results.twig)::


 
 
  1. <html> 
  2.   <head> 
  3.     <title>OCR</title> 
  4.   </head> 
  5.   <body> 
  6.  
  7.     <h2>Results</h2> 
  8.  
  9.     <textarea cols="50" rows="10">{{ text }}</textarea> 
  10.  
  11.     <hr> 
  12.  
  13.     <a href="/">← Go back</a> 
  14.  
  15.   </body> 
  16. </html> 

现在建立skeleton Silex app (public\index.php):


 
 
  1. <php 
  2.  
  3. require __DIR__.'/../vendor/autoload.php'
  4.  
  5. use Symfony\Component\HttpFoundation\Request; 
  6.  
  7. $app = new Silex\Application(); 
  8.  
  9. $app->register(new Silex\Provider\TwigServiceProvider(), [ 
  10.   'twig.path' => __DIR__.'/../views'
  11. ]); 
  12.  
  13. $app['debug'] = true; 
  14.  
  15. $app->get('/'function() use ($app) { 
  16.  
  17.   return $app['twig']->render('index.twig'); 
  18.  
  19. }); 
  20.  
  21. $app->post('/'function(Request $requestuse ($app) { 
  22.  
  23.     // TODO 
  24.  
  25. }); 
  26.  
  27. $app->run(); 

如果你在浏览器访问这个应用,你应该能看到一个文件上传表单。如果你在使用Homestead Improved Vagrant,你可以通过如下链接访问该应用。


 
 
  1. http://homestead.app/ 

下一步是实现文件上传。Silex使得这项工作非常简单;$request包含一个files组件,我们可以通过它来获得任意上传的文件,代码:


 
 
  1. // Grab the uploaded file 
  2. $file = $request->files->get('upload'); 
  3.  
  4. // Extract some information about the uploaded file 
  5. $info = new SplFileInfo($file->getClientOriginalName()); 
  6.  
  7. // Create a quasi-random filename 
  8. $filename = sprintf('%d.%s', time(), $info->getExtension()); 
  9.  
  10. // Copy the file 
  11. $file->move(__DIR__.'/../uploads'$filename); 

如你所见,我们产生随机文件名来减少文件名冲突—但在本应用中,我们怎么命名文件是不重要的。一旦我们在本地有一份文件拷贝,我们就可以产生一个Tessearct库的实例,然后进行分析:


 
 
  1. // Instantiate the Tessearct library 
  2. $tesseract = new TesseractOCR(__DIR__ . '/../uploads/' . $filename); 

在图像上实现OCR相当简单,我们只需调用方法recognize()。


 
 
  1. // Perform OCR on the uploaded image 
  2. $text = $tesseract->recognize(); 

最后我们把结果展示到结果页面:


 
 
  1. return $app['twig']->render( 
  2.     'results.twig'
  3.     [ 
  4.         'text'  =>  $text
  5.     ] 
  6. ); 

在一些图片上尝试,看看它效果怎样。如果你有困难,可以参考这个

一个实际的例子

让我们来看OCR一个更实用的例子。在本例中,我们尝试在图像中找到一个格式化的电话号码。

看看下面一幅图,上传到你的应用:

结果应该如下:


 
 
  1. :ii‘i 
  2. Customer Service Helplines 
  3.  
  4. British Airways Helpline 
  5.  
  6. 09040 490 541 

它没有挑出正文文本,这是我们能料到的,因为图片质量太差。虽然识别了号码但是也有一些“噪声”。

为了提取相关信息,有如下几件事我们可以做。

你可以让Tesseract 把它的结果限制在一定的字符集内,所以我们告诉它只返回数字型的内容代码如下:


 
 
  1. $tesseract->setWhitelist(range(0,9)); 

但这样有个问题。它常常把非数字字符解释成数字而非忽略它们。比如“Bob”可能被解释称数字“808”。

所以我们采用两步处理。

  1. 尝试提取可能是电话号码的数字串。

  2. 用一个库轮流评估每一个候选字符,一旦找到一个有效电话号码则停止。

第一步,我们可以用一个基本的正则表达式。可以用谷歌电话库来确定一个数字串是否是合法电话号码。

备注:我已在Sitepoint 写过关于谷歌电话库的内容

让我们给谷歌电话库添加一个PHP 端口,修改composer.json,添加:


 
 
  1. "giggsey/libphonenumber-for-php""~7.0" 

别忘了升级:


 
 
  1. composer update 

现在我们可以写一个函数,输入为一个字符串,尝试提取一个合法的电话号码


 
 
  1. /** 
  2. * Parse a string, trying to find a valid telephone number. As soon as it finds a 
  3. * valid number, it'll return it in E1624 format. If it can't find any, it'll 
  4. * simply return NULL. 
  5. * 
  6. * @param  string   $text           The string to parse 
  7. * @param  string   $country_code   The two digit country code to use as a "hint" 
  8. * @return string | NULL 
  9. */ 
  10. function findPhoneNumber($text$country_code = 'GB') { 
  11.  
  12.   // Get an instance of Google's libphonenumber 
  13.   $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance(); 
  14.  
  15.   // Use a simple regular expression to try and find candidate phone numbers 
  16.   preg_match_all('/(\+\d+)?\s*(\(\d+\))?([\s-]?\d+)+/'$text$matches); 
  17.  
  18.   // Iterate through the matches 
  19.   foreach ($matches as $match) { 
  20.  
  21.     foreach ($match as $value) { 
  22.  
  23.       try { 
  24.  
  25.         // Attempt to parse the number 
  26.         $number = $phoneUtil->parse(trim($value), $country_code);    
  27.  
  28.         // Just because we parsed it successfully, doesn't make it vald - so check it 
  29.         if ($phoneUtil->isValidNumber($number)) { 
  30.  
  31.           // We've found a telephone number. Format using E.164, and exit 
  32.           return $phoneUtil->format($number, \libphonenumber\PhoneNumberFormat::E164); 
  33.  
  34.         } 
  35.  
  36.       } catch (\libphonenumber\NumberParseException $e) { 
  37.  
  38.         // Ignore silently; getting here simply means we found something that isn't a phone number 
  39.  
  40.       } 
  41.  
  42.     } 
  43.   } 
  44.  
  45.   return null; 
  46.  

希望注释能解释这个函数在干什么。注意如果这个库没能从字符串中解析出一个合法的电话号码它会抛出一个异常。这不是什么问题;我们直接忽略它并继续下一个候选字符。

如果我们找到一个电话号码,我们以E.164的形式返回它。这提供了一个国际化的号码,我们可以用来打电话或者发送SMS。

现在我们可以如下使用:


 
 
  1. $text = $tesseract->recognize(); 
  2. $number = findPhoneNumber($text'GB'); 

我们需要给谷歌电话库提供一个提示来说明这个号码是哪个国家的。你也可以改成你自己的国家。

我们把所有的这些打包在一个新的路由中:


 
 
  1. $app->post('/identify-telephone-number'function(Request $requestuse ($app) { 
  2.  
  3.   // Grab the uploaded file 
  4.   $file = $request->files->get('upload'); 
  5.  
  6.   // Extract some information about the uploaded file 
  7.   $info = new SplFileInfo($file->getClientOriginalName()); 
  8.  
  9.   // Create a quasi-random filename 
  10.   $filename = sprintf('%d.%s', time(), $info->getExtension()); 
  11.  
  12.   // Copy the file 
  13.   $file->move(__DIR__.'/../uploads'$filename); 
  14.  
  15.   // Instantiate the Tessearct library 
  16.   $tesseract = new TesseractOCR(__DIR__ . '/../uploads/' . $filename); 
  17.  
  18.   // Perform OCR on the uploaded image 
  19.   $text = $tesseract->recognize(); 
  20.  
  21.   $number = findPhoneNumber($text'GB'); 
  22.  
  23.   return $app->json( 
  24.     [ 
  25.       'number'     =>  $number
  26.     ] 
  27.   ); 
  28.  
  29. }); 

我们现在有简单的API的基础—-也就是JSON响应-—我们可以用来作为一个简单的移动应用的后端,这款应用可以用来从一幅图中添加联系人,打电话。

总结

OCR有许多应用——并且很容易整合进你的应用(超过你的预期)。本文中,我们安装了开源OCR包;并使用一个包装器库,把它整合进一个非常简单的PHP应用。我们只是触及到了所有可能性的表面,希望这能给你一些想法,帮你想想怎么在你自己的应用中使用OCR。


作者:邱康

来源:51CTO

相关文章
|
2月前
|
JSON 文字识别 数据可视化
Qwen2-VL微调实战:LaTex公式OCR识别任务(完整代码)
《SwanLab机器学习实战教程》推出了一项基于Qwen2-VL大语言模型的LaTeX OCR任务,通过指令微调实现多模态LLM的应用。本教程详述了环境配置、数据集准备、模型加载、SwanLab集成及微调训练等步骤,旨在帮助开发者轻松上手视觉大模型的微调实践。
|
2月前
|
机器学习/深度学习 人工智能 文字识别
Kimi 上线视觉思考模型,K1 系列强化学习模型正式开放,无需借助外部 OCR 处理图像与文本进行思考并回答
k1视觉思考模型是kimi推出的k1系列强化学习AI模型,具备端到端图像理解和思维链技术,能够在数学、物理、化学等领域表现优异。本文详细介绍了k1视觉思考模型的功能、技术原理、使用方法及其在多个应用场景中的表现。
270 68
Kimi 上线视觉思考模型,K1 系列强化学习模型正式开放,无需借助外部 OCR 处理图像与文本进行思考并回答
|
5月前
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
270 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
|
5月前
|
存储 关系型数据库 MySQL
深入浅出PHP:从基础到实战
【9月更文挑战第20天】本文将带你走进PHP的世界,从最基础的语法开始,逐步深入到实战应用。我们将通过实例讲解PHP的核心概念,如变量、控制结构、函数等,然后介绍如何使用PHP进行数据库操作和文件处理。最后,我们将展示如何用PHP构建一个简单的博客系统,让你在实践中掌握PHP的应用。无论你是编程新手,还是有一定经验的开发者,都能在这篇文章中找到有价值的信息。让我们一起探索PHP的魅力吧!
|
1月前
|
编解码 文字识别 自然语言处理
如何使用OCR技术批量识别图片中的文字并重命名文件,OCR 技术批量识别图片中的文字可能出现的错误
### 简介 【批量识别图片内容重命名】工具可批量识别图片中的文字并重命名文件,方便高效处理大量图片。然而,OCR 技术面临字符识别错误(如形近字混淆、生僻字识别不佳)、格式错误(段落错乱、换行问题)和语义理解错误等挑战。为提高准确性,建议提升图片质量、选择合适的 OCR 软件及参数,并结合自动校对与人工审核,确保最终文本的正确性和完整性。
168 12
如何使用OCR技术批量识别图片中的文字并重命名文件,OCR 技术批量识别图片中的文字可能出现的错误
|
2月前
|
文字识别 测试技术 API
实战阿里通义灵码极速编程-截屏-OCR-Ollama篇代码
该代码实现了一个截屏测试工具,结合了鼠标事件监听、屏幕截图和OCR功能。用户可通过拖动鼠标选择屏幕区域进行截图,并将截图转换为Markdown格式的文本内容。具体步骤包括:初始化大模型客户端、编码图像为Base64格式、捕获指定屏幕区域并保存截图、调用大模型API进行OCR识别并输出Markdown格式的内容。
115 9
|
2月前
|
文字识别 程序员 C++
实战阿里通义灵码极速编程-截屏-OCR-OLlama篇
通过实际案例展示阿里通义灵码如何极大提高编程效率。以开发屏幕截图OCR Python程序为例,使用Win10、Anaconda3、VS Code及通义灵码插件。经过四次提问与优化,从截屏选择矩形区域到调用大模型进行OCR识别,整个过程仅耗时半小时,最终形成可运行的控制台程序。加入界面开发后,总用时2小时,显著提升开发速度和质量。
154 5
|
2月前
|
PHP 计算机视觉 UED
Buzz库:PHP图像处理中的异步图像下载和保存
Buzz库:PHP图像处理中的异步图像下载和保存
|
3月前
|
编译器 PHP 开发者
PHP 8新特性解析与实战应用####
随着PHP 8的发布,这一经典编程语言迎来了诸多令人瞩目的新特性和性能优化。本文将深入探讨PHP 8中的几个关键新功能,包括命名参数、JIT编译器、新的字符串处理函数以及错误处理改进等。通过实际代码示例,展示如何在现有项目中有效利用这些新特性来提升代码的可读性、维护性和执行效率。无论你是PHP新手还是经验丰富的开发者,本文都将为你提供实用的技术洞察和最佳实践指导。 ####
57 1
|
3月前
|
自然语言处理 安全 PHP
深入浅出PHP编程:从基础到实战
【10月更文挑战第36天】本文将带你走进PHP的奇妙世界,无论你是初学者还是有一定经验的开发者,都将从中获益。文章首先介绍PHP的基础概念和语法,然后通过实际代码示例,展示如何利用PHP进行高效的Web开发。最后,我们将探讨一些高级主题,如面向对象编程、数据库操作以及安全性问题。让我们一起开启PHP的学习之旅吧!

热门文章

最新文章