具有 PHP 性能的 Tesseract
Tesseract with PHP performance
我已经用 Laminas 和 Mezzio(以前的 Zend Expressive)实现了 API。我有一个处理程序,它使用 thiagoalessio\TesseractOCR 库 (https://github.com/thiagoalessio/tesseract-ocr-for-php) 从 PHP.
调用 Tesseract
在我的开发环境中一切正常。通过调用 API 获取图像文本需要 2-6 秒。
现在我首先将 API 部署到 Google 云 VM,现在我将其部署到 Raspberry Pi 4 4GB RAM 模型。两者都非常慢!请求响应需要 25-30 秒。 Tesseract 似乎不是问题所在。如果我从 CLI 调用它,它会非常快。但是简单的 API 调用也不慢!看起来 Lamina / Mezzio 与 Tesseract 的组合超级慢。除了从图像中提取文本并将其作为 JSON 响应发回之外,我什么也没做。
我在 apache2 服务器上 运行 php 7.3。 Pi 在我通过 LAN 连接的本地网络中。我正在使用 Postman 测试 API 调用。
我可以做些什么来提高性能?是硬件吗?
这是我的处理程序代码
<?php
declare(strict_types=1);
namespace App\Handler;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use thiagoalessio\TesseractOCR\TesseractOCR;
class OcrHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$measure = [];
$start = microtime(true);
$body = $request->getBody();
$result = '';
if(!empty($body->getContents())) {
$measure['body_parse'] = microtime(true) - $start;
$start = microtime(true);
$guid = $this->GUID();
$imagePath = sprintf('%s/data/%s', getcwd(), $guid);
file_put_contents($imagePath, $body->getContents());
$measure['image_write'] = microtime(true) - $start;
$start = microtime(true);
$tesseractOcr = new TesseractOCR($imagePath);
$tesseractOcr->withoutTempFiles();
$result = $tesseractOcr->lang('deu')->run();
$measure['image_parsing'] = microtime(true) - $start;
$start = microtime(true);
unlink($imagePath);
$measure['image_delete'] = microtime(true) - $start;
}
return new JsonResponse(['result' => $result, 'measure' => $measure]);
}
private function GUID()
{
if (function_exists('com_create_guid') === true)
return trim(com_create_guid(), '{}');
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
}
编辑
好的,我添加了时间测量并找到了瓶颈。确实是“image_parsing”,Tesseract的执行。这对我来说很奇怪,因为正如我所说,在 CLI 上它非常快。这里它占用了大部分响应时间(27.9 秒)!
{
"result": "...",
"measure": {
"body_parse": 0.0018658638000488281,
"image_write": 0.0020492076873779297,
"image_parsing": 27.909277200698853,
"image_delete": 0.0005030632019042969
}
}
为什么它在 CLI 上这么快,但从 PHP 调用它时却这么慢?是否有任何可能的性能改进?
好的,正如我在编辑中提到的那样,瓶颈似乎是图像解析。更具体地说,瓶颈是库“thiagoalessio/tesseract-ocr-for-php”。以下代码使用 PHP 的 exec 函数而不是库,需要 5.82 秒(与 27.9 秒相比)。这是一个巨大的差异。下面的代码工作正常,假设你已经在你的机器上安装了 tesseract:
<?php
declare(strict_types=1);
namespace App\Handler;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class OcrHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$measure = [];
$start = microtime(true);
$body = $request->getBody();
$result = '';
if(!empty($body->getContents())) {
$measure['body_parse'] = microtime(true) - $start;
$start = microtime(true);
$guid = $this->GUID();
$imagePath = sprintf('%s/data/%s', getcwd(), $guid);
$outputPath = $imagePath . '_out';
file_put_contents($imagePath, $body->getContents());
$measure['image_write'] = microtime(true) - $start;
$start = microtime(true);
exec(sprintf('tesseract %s %s', $imagePath, $outputPath));
$result = file_get_contents($outputPath . '.txt');
$measure['image_parsing'] = microtime(true) - $start;
$start = microtime(true);
unlink($imagePath);
unlink($outputPath . '.txt');
$measure['image_delete'] = microtime(true) - $start;
}
return new JsonResponse(['result' => $result, 'measure' => $measure]);
}
private function GUID()
{
if (function_exists('com_create_guid') === true)
return trim(com_create_guid(), '{}');
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
}
您在 Stack Overflow 上找到了很多关于 thiagoalessio/tesseract-ocr-for-php 库的建议,但您应该检查一下您的表现!在我的开发机器上它运行良好,但在生产上它非常慢而且生产是一个成本问题。
我已经用 Laminas 和 Mezzio(以前的 Zend Expressive)实现了 API。我有一个处理程序,它使用 thiagoalessio\TesseractOCR 库 (https://github.com/thiagoalessio/tesseract-ocr-for-php) 从 PHP.
调用 Tesseract在我的开发环境中一切正常。通过调用 API 获取图像文本需要 2-6 秒。
现在我首先将 API 部署到 Google 云 VM,现在我将其部署到 Raspberry Pi 4 4GB RAM 模型。两者都非常慢!请求响应需要 25-30 秒。 Tesseract 似乎不是问题所在。如果我从 CLI 调用它,它会非常快。但是简单的 API 调用也不慢!看起来 Lamina / Mezzio 与 Tesseract 的组合超级慢。除了从图像中提取文本并将其作为 JSON 响应发回之外,我什么也没做。
我在 apache2 服务器上 运行 php 7.3。 Pi 在我通过 LAN 连接的本地网络中。我正在使用 Postman 测试 API 调用。
我可以做些什么来提高性能?是硬件吗?
这是我的处理程序代码
<?php
declare(strict_types=1);
namespace App\Handler;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use thiagoalessio\TesseractOCR\TesseractOCR;
class OcrHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$measure = [];
$start = microtime(true);
$body = $request->getBody();
$result = '';
if(!empty($body->getContents())) {
$measure['body_parse'] = microtime(true) - $start;
$start = microtime(true);
$guid = $this->GUID();
$imagePath = sprintf('%s/data/%s', getcwd(), $guid);
file_put_contents($imagePath, $body->getContents());
$measure['image_write'] = microtime(true) - $start;
$start = microtime(true);
$tesseractOcr = new TesseractOCR($imagePath);
$tesseractOcr->withoutTempFiles();
$result = $tesseractOcr->lang('deu')->run();
$measure['image_parsing'] = microtime(true) - $start;
$start = microtime(true);
unlink($imagePath);
$measure['image_delete'] = microtime(true) - $start;
}
return new JsonResponse(['result' => $result, 'measure' => $measure]);
}
private function GUID()
{
if (function_exists('com_create_guid') === true)
return trim(com_create_guid(), '{}');
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
}
编辑
好的,我添加了时间测量并找到了瓶颈。确实是“image_parsing”,Tesseract的执行。这对我来说很奇怪,因为正如我所说,在 CLI 上它非常快。这里它占用了大部分响应时间(27.9 秒)!
{
"result": "...",
"measure": {
"body_parse": 0.0018658638000488281,
"image_write": 0.0020492076873779297,
"image_parsing": 27.909277200698853,
"image_delete": 0.0005030632019042969
}
}
为什么它在 CLI 上这么快,但从 PHP 调用它时却这么慢?是否有任何可能的性能改进?
好的,正如我在编辑中提到的那样,瓶颈似乎是图像解析。更具体地说,瓶颈是库“thiagoalessio/tesseract-ocr-for-php”。以下代码使用 PHP 的 exec 函数而不是库,需要 5.82 秒(与 27.9 秒相比)。这是一个巨大的差异。下面的代码工作正常,假设你已经在你的机器上安装了 tesseract:
<?php
declare(strict_types=1);
namespace App\Handler;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class OcrHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$measure = [];
$start = microtime(true);
$body = $request->getBody();
$result = '';
if(!empty($body->getContents())) {
$measure['body_parse'] = microtime(true) - $start;
$start = microtime(true);
$guid = $this->GUID();
$imagePath = sprintf('%s/data/%s', getcwd(), $guid);
$outputPath = $imagePath . '_out';
file_put_contents($imagePath, $body->getContents());
$measure['image_write'] = microtime(true) - $start;
$start = microtime(true);
exec(sprintf('tesseract %s %s', $imagePath, $outputPath));
$result = file_get_contents($outputPath . '.txt');
$measure['image_parsing'] = microtime(true) - $start;
$start = microtime(true);
unlink($imagePath);
unlink($outputPath . '.txt');
$measure['image_delete'] = microtime(true) - $start;
}
return new JsonResponse(['result' => $result, 'measure' => $measure]);
}
private function GUID()
{
if (function_exists('com_create_guid') === true)
return trim(com_create_guid(), '{}');
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
}
您在 Stack Overflow 上找到了很多关于 thiagoalessio/tesseract-ocr-for-php 库的建议,但您应该检查一下您的表现!在我的开发机器上它运行良好,但在生产上它非常慢而且生产是一个成本问题。