关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » PHP »PHP OCR实战:用Tesseract从图像中读取文字

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

    2016-01-15 00:00:00 出处:ITJS
    分享

    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中的以下代码:

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

    修改成:

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

    同样要在hosts文件中添加

    192.168.10.10       homestead.app

    安装Tesseract

    下一步是安装Tesseract

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

    sudo apt-get install tesseract-ocr

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

    测试并定制安装

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

    首先保存这个图片sign.png

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

    tesseract sign.png out

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

    现在尝试sign2.jpg

    tesseract sign2.jpg out

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

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

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

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

    解压:

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

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

    /usr/share/tesseract-ocr/tessdata

    例如

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

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

    tesseract sign2.jpg out -l deu

    “deu” 是德语的 ISO 639-3码.

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

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

    配置应用程序

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

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

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

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

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

    然后建立三个文件夹:

    - public
    - uploads
    - views

    我们需要上传表单(viewsindex.twig):

    <html>
      <head>
        <title>OCR</title>
      </head>
      <body>
    
        <form action="" method="post" enctype="multipart/form-data">
          <input type="file" name="upload">
          <input type="submit">
        </form>
    
      </body>
    </html>

    需要一个结果展示页面(viewsresults.twig)::

    <html>
      <head>
        <title>OCR</title>
      </head>
      <body>
    
        <h2>Results</h2>
    
        <textarea cols="50" rows="10">{{ text }}</textarea>
    
        <hr>
    
        <a href="/">← Go back</a>
    
      </body>
    </html>

    现在建立skeleton Silex app (publicindex.php):

    < php 
    
    require __DIR__.'/../vendor/autoload.php'; 
    
    use SymfonyComponentHttpFoundationRequest; 
    
    $app = new SilexApplication(); 
    
    $app->register(new SilexProviderTwigServiceProvider(), [
      'twig.path' => __DIR__.'/../views',
    ]);
    
    $app['debug'] = true; 
    
    $app->get('/', function() use ($app) { 
    
      return $app['twig']->render('index.twig');
    
    }); 
    
    $app->post('/', function(Request $request) use ($app) { 
    
        // TODO
    
    }); 
    
    $app->run();

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

    http://homestead.app/

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

    // Grab the uploaded file
    $file = $request->files->get('upload'); 
    
    // Extract some information about the uploaded file
    $info = new SplFileInfo($file->getClientOriginalName());
    
    // Create a quasi-random filename
    $filename = sprintf('%d.%s', time(), $info->getExtension());
    
    // Copy the file
    $file->move(__DIR__.'/../uploads', $filename);

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

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

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

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

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

    return $app['twig']->render(
        'results.twig',
        [
            'text'  =>  $text,
        ]
    );

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

    一个实际的例子

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

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

    结果应该如下:

    :ii‘i
    Customer Service Helplines
    
    British Airways Helpline
    
    09040 490 541

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

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

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

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

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

    所以我们采用两步处理。

    尝试提取可能是电话号码的数字串。 用一个库轮流评估每一个候选字符,一旦找到一个有效电话号码则停止。

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

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

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

    "giggsey/libphonenumber-for-php": "~7.0"

    别忘了升级:

    composer update

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

    /**
     * Parse a string, trying to find a valid telephone number. As soon as it finds a 
     * valid number, it'll return it in E1624 format. If it can't find any, it'll 
     * simply return NULL.
     * 
     * @param  string   $text           The string to parse
     * @param  string   $country_code   The two digit country code to use as a "hint"
     * @return string | NULL
     */
    function findPhoneNumber($text, $country_code = 'GB') {
    
      // Get an instance of Google's libphonenumber
      $phoneUtil = libphonenumberPhoneNumberUtil::getInstance();
    
      // Use a simple regular expression to try and find candidate phone numbers
      preg_match_all('/(+d+) s*((d+)) ([s-] d+)+/', $text, $matches);
    
      // Iterate through the matches
      foreach ($matches as $match) {
    
        foreach ($match as $value) {
    
          try {
    
            // Attempt to parse the number
            $number = $phoneUtil->parse(trim($value), $country_code);    
    
            // Just because we parsed it successfully, doesn't make it vald - so check it
            if ($phoneUtil->isValidNumber($number)) {
    
              // We've found a telephone number. Format using E.164, and exit
              return $phoneUtil->format($number, libphonenumberPhoneNumberFormat::E164);
    
            }
    
          } catch (libphonenumberNumberParseException $e) {
    
            // Ignore silently; getting here simply means we found something that isn't a phone number
    
          }
    
        }
      }
    
      return null;
    
    }

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

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

    现在我们可以如下使用:

    $text = $tesseract->recognize();
    
    $number = findPhoneNumber($text, 'GB');

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

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

    $app->post('/identify-telephone-number', function(Request $request) use ($app) { 
    
      // Grab the uploaded file
      $file = $request->files->get('upload'); 
    
      // Extract some information about the uploaded file
      $info = new SplFileInfo($file->getClientOriginalName());
    
      // Create a quasi-random filename
      $filename = sprintf('%d.%s', time(), $info->getExtension());
    
      // Copy the file
      $file->move(__DIR__.'/../uploads', $filename); 
    
      // Instantiate the Tessearct library
      $tesseract = new TesseractOCR(__DIR__ . '/../uploads/' . $filename);
    
      // Perform OCR on the uploaded image
      $text = $tesseract->recognize();
    
      $number = findPhoneNumber($text, 'GB');
    
      return $app->json(
        [
          'number'     =>  $number,
        ]
      );
    
    });

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

    总结

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

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。