首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有PHP性能的Tesseract

具有PHP性能的Tesseract
EN

Stack Overflow用户
提问于 2021-04-28 14:36:32
回答 1查看 385关注 0票数 2

我已经用Laminas和Mezzio (前Zend表现力)实现了一个API。这里有一个处理程序,它使用thiagoalessio\TesseractOCR库(https://github.com/thiagoalessio/tesseract-ocr-for-php)从PHP调用Tesseract。

在我的开发环境中,一切都很好。通过调用API获取图像文本需要2-6秒。

现在,我首先将API部署到Google,现在将其部署到RaspberryPIP4.4GBRAM模型中。两个动作都很慢!请求响应需要25-30秒。似乎不是问题所在。如果我从CLI呼叫它,它是超快的。但是简单的API调用也不会慢!看起来拉米纳/梅齐奥和特瑟乐手的结合是非常缓慢的。我实际上只做了从图像中提取文本并将其作为JSON响应发送回来。

我正在apache2服务器上运行php7.3。Pi在我的本地网络中,通过局域网连接。我正在用Postman测试API调用。

我能做些什么来提高绩效呢?是因为硬件吗?

这是我的处理程序代码

代码语言:javascript
复制
<?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上它是超快的。在这里,它占用了大部分的响应时间(279秒)!

代码语言:javascript
复制
{
    "result": "...",
    "measure": {
        "body_parse": 0.0018658638000488281,
        "image_write": 0.0020492076873779297,
        "image_parsing": 27.909277200698853,
        "image_delete": 0.0005030632019042969
    }
}

为什么它在CLI上这么快,但是当我从PHP调用它时却这么慢?是否有任何可能的性能改进?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-28 15:50:50

好的,正如我在编辑中提到的,瓶装水似乎是图像解析。更具体地说,瓶颈是“thiagoalessio/tesseract-ocr”库。下面的代码使用PHP的exec-函数而不是库,耗时5,82秒(而不是27,9秒)。这是一个巨大的差异。假设您已经在您的计算机上安装了tesseract,下面的代码可以正常工作:

代码语言:javascript
复制
<?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));
    }
}

您可以在堆栈溢出上为thiagoalessio/tesseract- performance库找到很多建议,但是您应该检查性能!在我的开发机器上,它工作得很好,但是在生产上它是超慢的,生产是一个成本问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67302320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档