用Tesseract从图像中读取文字,虚拟开发环境

 Web前端     |      2020-03-25 05:39

本文由码农网 – 邱康原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

简介

Laravel 致力于让你在 PHP 开发过程中更加轻松愉快,这其中也包括本地开发环境的搭建。 Vagrant 提供了一种简单、优雅的方式来管理和配置虚拟机。

Laravel Homestead 是一个官方预封装的 Vagrant box,它为你提供了一个完美的开发环境,你无需在本地安装 PHP ,web 服务器,或其他服务软件。 Vagrant box 是完全一次性的,你不用担心系统被搞乱!如果有什么地方出错了,你可以在几分钟内销毁并重建 box !

Homestead 可以运行在 Windows 、Mac 或 Linux 系统上,它里面包含了 Nginx Web 服务器、PHP 7.1 、MySQL 、Postgres 、Redis 、Memcached 、Node ,以及一些有利于你开发 laravel 应用的其他程序。

如果你使用的是 Windows 系统,你可能需要启用硬件虚拟化(VT-x)。这通常需要通过 BIOS 来启用它。如果你在一个 UEFI 系统上使用 Hyper-V,您可能还需要禁用 Hyper-V 才能启用 VT-x。

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

内置软件

  • Ubuntu 16.04
  • Git
  • PHP 7.1
  • Nginx
  • MySQL
  • MariaDB
  • Sqlite3
  • Postgres
  • Composer
  • Node (With Yarn, Bower, Grunt, and Gulp)
  • Redis
  • Memcached
  • Beanstalkd
  • Mailhog
  • ngrok

图片 1

安装与设置

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

第一步

在你使用 Homestead 环境之前,你必须先安装 VirtualBox 5.1 、VMWare 或者 Parallels 中的一个,然后再安装 Vagrant。上述软件均提供了针对不同操作系统的可视化安装包。

若要使用 VMware provider,你需要同时购买 VMware Fusion / Workstation 以及 VMware Vagrant 插件 的软件授权,因为它们不是免费的。使用 VMware 的优势是:可以获得开箱即用的共享文件夹特性。

若要使用 Parallels provider,你需要安装 Parallels Vagrant 插件 ,这是免费的。

安装

安装 Homestead Vagrant Box

当 VirtualBox / VMware 以及 Vagrant 安装完成后,你可以使用以下命令将 laravel/homestead 这个 box 添加进你的 Vagrant 当中。 homestead box 的下载会花费你一点时间,具体的下载时长由网络速度决定:

vagrant box add laravel/homestead

如果上面的命令运行失败,请先确保你已经安装了最新版本的 Vagrant。

  • 如果使用国内网络,可以复制终端上显示的 homestead box 下载地址手动下载并重命名。例如重命名为 virtualbox-3.0.0.box。

然后,新建一个 metadata.json 文件,并写入以下示例内容:

{
    "name": "laravel/homestead",
    "versions": 
    [
        {
            "version": "3.0.0",
            "providers": [
                {
                  "name": "virtualbox",
                  "url": "virtualbox-3.0.0.box"
                }
            ]
        }
    ]
}

最后,使用以下命令手动添加 box

vagrant box add metadata.json # 添加 box
vagrant box list # 列出所有 box

准备

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

安装 Homestead

你可以简单使用 Git 克隆代码仓库的方式来安装 Homestead。建议将克隆的代码仓库重命名为 Homestead ,并放置到你的「home」目录中,如此一来 Homestead box 就能作为主机,为你的所有 Laravel 项目提供服务:

cd ~

git clone https://github.com/laravel/homestead.git Homestead

由于 Homestead 的 master 分支并不是稳定分支,你应该检出已经标签过的稳定版本。你可以在 Github Release Page 找到最新的稳定版本。

cd Homestead

// 检出所需要的版本...
git checkout v5.4.0

一旦你克隆完 Homestead 的代码仓库,就可以在 Homestead 目录中运行 bash init.sh 命令来创建 Homesstead.yaml 配置文件。 Homesstead.yaml 文件会被放置在你的 Homestead 目录中:

// Mac / Linux...
bash init.sh

// Windows...
init.bat

配置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

配置 Homestead

安装Tesseract

下一步是安装Tesseract

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

sudo apt-get install tesseract-ocr

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

配置你的提供者

Homestead.yaml 中的 provider 参数设置取决于你用的是哪一个 Vagrant 提供者 virtualbox 、vmware_fusion 、vmware_workstation 或者 parallels。你可以根据自己的实际情况来设置提供者:

provider: virtualbox

测试并定制安装

我们将使用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(正确的)。

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

配置共享文件夹

你可以在 Homestead.yaml 文件的 folders 属性里列出所有想与 Homestead 环境共享的文件夹。这些文件夹中的文件若有变更,它们将会在你的本机电脑与 Homestead 环境自动更新同步。你可以在这里设置多个共享文件夹:

folders:
    - map: ~/Code
      to: /home/vagrant/Code

若要启动 NFS ,只需要在共享文件夹的设置值中加入一个简单的参数:

folders:
    - map: ~/Code
      to: /home/vagrant/Code
      type: "nfs"
  • 如果使用 NFS ,建议你安装 vagrant-bindfs 插件。 这个插件会替你处理 box 中的文件或目录权限问题。

你也可以在配置中传递任何 Vagrant 共享文件夹 支持的参数,在 options 配置项下列出它们:

folders:
    - map: ~/Code
      to: /home/vagrant/Code
      type: "rsync"
      options:
          rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
          rsync__exclude: ["node_modules"]

配置应用程序

我们将使用这个库来用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,
    ]
);

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

配置 Nginx 站点

对 Nginx 不熟悉吗?没关系。sites 属性可以帮助你可以轻易指定一个 域名 来对应到 homestead 环境中的一个目录上。在 Homestead.yaml 文件中已包含了一个网站设置范本。同样的,你也可以增加多个网站到你的 Homestead 环境中。 Homestead 可以同时为多个 Laravel 应用提供虚拟化环境:

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

如果你在 Homestead box 配置之后更改了 sites 属性,那么应该重新运行 vagrant reload --provision 来更新 Nginx 配置到虚拟机上。

一个实际的例子

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

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

图片 2

结果应该如下:

:ii‘i
Customer Service Helplines

British Airways Helpline

09040 490 541

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

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

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

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

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

所以我们采用两步处理。

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

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

备注:我已在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响应-—我们可以用来作为一个简单的移动应用的后端,这款应用可以用来从一幅图中添加联系人,打电话。

关于 Hosts 文件

你必须将在 Nginx sites 中所添加的「域名」也添加到你本机电脑的 hosts 上。 hosts 文件会将请求重定向至 Homestead 环境中设置的本地域名。在 Mac 或 Linux 上,该文件通常会存放在 /etc/hosts。在 Windows 上,则存放于 C:WindowsSystem32driversetchosts。设置内容如下所示:

192.168.10.10  homestead.app

请务必确认 IP 地址与 Homestead.yaml 文件中设置的相同。将域名设置在 hosts 文件之后,你就可以通过网页浏览器访问你的网站。

http://homestead.app

总结

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

启动 Vagrant Box

根据你的喜好完成 Homestead.yaml 编辑后,进入你的 Homestead 目录并运行 vagrant up 命令。 Vagrant 就会根据 Homestead.yaml 里的配置信息启动,并为虚拟机设置共享文件夹和 Nginx 网站。

如果要移除虚拟机,你可以使用 vagrant destroy --force 命令

为每个项目分开安装

除了在全局范围内安装 Homestead 环境,所有项目共享相同的 Homestead box 外,你还可以为每一个项目配置一个独立的 Homestead 实例。通过传递 Vagrantfile ,可以实现为每个项目分别安装上 Homestead ,其他项目成员只需要通过简单的 vagrant up 即能跟你拥有一样的 Homestead 环境。

要将 Homestead 直接安装到项目中,需要使用 Composer:

composer require laravel/homestead --dev

一旦 Homestead 安装完毕,可以使用 make 命令生成 Vagrantfile 与 Homestead.yaml 文件,并存放于项目的根目录。make 命令将会自动在 Homestead.yaml 文件中配置 sites 及 folders

Mac / Linux:

php vendor/bin/homestead make

Windows:

vendor\bin\homestead make

接下来,在命令行中运行 vagrant up 并通过网页浏览器访问 http://homestead.app。再次提醒:你仍然需要在 /etc/hosts 里配置 homestead.app 或其它想要使用的域名。

如果你希望使用 MariaDB 来替换 MySQL,你可以在 Homestead.yaml 文件中增加一个 mariadb 的选项,这个选项会移除 MySQL 并安装 MariaDB。因为 MariaDB 可用作 MySQL 的替代品,所以在你的数据库配置信息里,可继续使用 mysql 数据库驱动。

box: laravel/homestead
ip: "192.168.20.20"
memory: 2048
cpus: 4
provider: virtualbox
mariadb: true
  • 安装 MariaDB 需要连接境外网络,请确保网络畅通!

常见用法

全局使用

有时候你希望在文件系统的任何地方都可以使用 vagrant up 命令启动虚拟机,那么你需要添加以下代码到你的 Mac / Linux 系统的 Bash profile 文件里面。对于 Windows 系统,您可以通过在 PATH 环境变量中添加「批处理」文件的方式来实现此目的。下面这些脚本让你可以在文件系统的任何位置都能运行 Vagrant 命令,它相当于切换到 Homestead 目录运行 Vagrant 命令:

Mac / Linux
function homestead() {
    ( cd ~/Homestead && vagrant $* )
}

请将 ~/Homestead 这个路径修改为你的实际 Homestead 的安装路径,一旦这个函数安装成功,就可以在系统的任意位置运行 homestead up 或 homestead ssh 命令。

Windows

在系统的任意位置创建一个批处理文件 homestead.bat ,并添加如下内容:

@echo off

set cwd=%cd%
set homesteadVagrant=C:Homestead

cd /d %homesteadVagrant% && vagrant %*
cd /d %cwd%

set cwd=
set homesteadVagrant=

请确保将 C:Homestead 这个路径修改为你的实际 Homestead 的安装路径,创建完这个文件后,将这个文件路径添加到 PATH 环境变量中,就可以在系统的任意位置运行 homestead up 或 homestead ssh 命令。

上一篇:没有了 下一篇:没有了