【问题标题】:Converting PDF to PNG for Tesseract to process将 PDF 转换为 PNG 以供 Tesseract 处理
【发布时间】:2018-04-07 20:04:17
【问题描述】:

我目前在使用 Imagemagick 和 Tesseract 时遇到问题。

我正在为 PHP 中的文档开发一个命令行分类器。这个想法是它接收 PDF 文档并使用League Pipeline package 将其传递给多个步骤。我认为必要的步骤如下:

  1. 将 PDF 转换为 PNG 文件
  2. 从 PNG 文件中提取文本
  3. 通过机器学习库运行文本以对其进行分类

主要命令如下所示:

<?php

namespace Matthewbdaly\LetterClassifier\Commands;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use League\Pipeline\Pipeline;
use Matthewbdaly\LetterClassifier\Stages\ConvertPdfToPng;
use Matthewbdaly\LetterClassifier\Stages\ReadFile;

class Processor extends Command
{
    protected function configure()
    {
        $this->setName('process')
            ->setDescription('Processes a file')
            ->setHelp('This command processes a file')
            ->addArgument('file', InputArgument::REQUIRED, 'File to process');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $file = $input->getArgument('file');
        $pipeline = (new Pipeline)
            ->pipe(new ConvertPdfToPng)
            ->pipe(new ReadFile);
        $pipeline->process($file);
    }
}

如您所见,它接受文件名作为第一个参数,然后为所需步骤定义一个管道,然后将文件传递给管道。

转换PDF的步骤如下:

<?php

namespace Matthewbdaly\LetterClassifier\Stages;

use Imagick;

class ConvertPdfToPng
{
    public function __invoke($file)
    {
        $tmp = tmpfile();
        $uri = stream_get_meta_data($tmp)['uri'];
        $img = new Imagick($file);
        $img->setResolution(300, 300);
        $img->setImageDepth(8);
        $img->setImageFormat('png');
        $img->writeImage($uri);
        return $tmp;
    }
}

它将 PDF 的 PNG 版本作为临时文件写入。生成的文件看起来不错,至少在我看来,但 Tesseract 无法正确读取它。这是 Tesseract 应该处理文件的第二步:

<?php

namespace Matthewbdaly\LetterClassifier\Stages;

use thiagoalessio\TesseractOCR\TesseractOCR;

class ReadFile
{

    public function __invoke($file)
    {
        $uri = stream_get_meta_data($file)['uri'];
        $ocr = new TesseractOCR($uri);
        $output = $ocr->lang('eng')->run();
        eval(\Psy\Sh());
    }
}

Psysh 的输出如下所示:

=> """
   Am sum\n
   \n
   mm“ m mun SuHrkw-l\n
   n m 51mm\n
   \n
   mm\n
   \n
   um um\n
   \n
   ms Murine\n
   1 Elm: 51mm\n
   Emnuumn\n
   \n
   a mu\n
   \n
   m Mm 2m-\n
   Dav st-n-m.\n
   \n
   P‘Eualanfl ma lumnflarvlmamrmy ”Hay ”mum-m-\n
   we we “mum-m n: "mum,“ m mun\n
   \n
   vm [harem\n
   \n
   Am smrm
   """

这不是我要分类的信件的内容 - 文本被破坏了。如果我从 shell 运行以下命令,它们会按预期工作,将字母的文本转换并写入输出文件:

convert -density 300 Quote.pdf output.png
tesseract output.png output

如果我在 Tesseract 阶段硬编码文件的路径以指向使用convert 命令生成的output.png,则可以。所以我相当有信心问题在于生成PNG文件的步骤。我没有使用 Imagemagick 的经验,所以我不确定为什么无法处理该文件,但似乎我缺少某种设置。

谁能提出问题可能是什么?

【问题讨论】:

    标签: php imagemagick tesseract


    【解决方案1】:

    我怀疑问题在于 Imagick 在您致电 setResolution() 之前会读取 PDF。

    尝试实例化一个空的 IMagick 对象,设置分辨率,然后读取文件:

    $img = new Imagick();
    $img->setResolution(300, 300);
    $img->readImage($file);
    

    【讨论】:

    • 这正是问题所在 - 它现在按预期工作。非常感谢。看图后调用setResolution()有什么意义,为什么会出问题?
    • @MatthewDaly 在加载输入图像后调用它可以为输出图像设置所需的像素密度,或者什么都不做。我不确定。
    猜你喜欢
    • 2010-10-13
    • 2015-12-30
    • 1970-01-01
    • 2020-12-15
    • 2021-12-14
    • 2017-10-25
    • 2010-10-28
    • 2011-06-29
    • 2011-04-19
    相关资源
    最近更新 更多